Summary: | ASTERISK-18399: When using autoload=yes in modules.conf, res_odbc_conf.so complaints about undefined symbol | ||
Reporter: | Mikael Carlsson (mickecarlsson) | Labels: | |
Date Opened: | 2011-08-31 15:14:59 | Date Closed: | 2011-09-01 14:15:44 |
Priority: | Trivial | Regression? | |
Status: | Closed/Complete | Components: | . I did not set the category correctly. |
Versions: | 1.8.6.0 | Frequency of Occurrence | Constant |
Related Issues: | |||
Environment: | Centos 6.0, x64 | Attachments: | ( 0) 20110831__asterisk-18399.diff |
Description: | When starting Asterisk an error is listed in log file: [Aug 31 21:54:45] WARNING[860] loader.c: Error loading module 'res_config_odbc.so': /usr/lib/asterisk/modules/res_config_odbc.so: undefined symbol: ast_odbc_clear_cache After a conversation with Corydon76-home on #asterisk-dev I emptied out modules.conf: [modules] autoload=yes The error still exists. If I preload odbc: preload => res_odbc.so preload => res_config_odbc.so The error is gone. This is from IRC: <Corydon76-home> mickecarlsson: I think I know what the problem is, but it's not solveable, because it's a bug in the DL library <Corydon76-home> Specifically, the DL library is not paying attention to the RTLD_LAZY flag | ||
Comments: | By: Walter Doekes (wdoekes) 2011-08-31 16:25:12.038-0500 Is there really a problem here? When I test this with 1.8-svn, I get see these things: (1) autoloaded modules are loaded in the readdir(2) order (2) if res_config_odbc is loaded before res_odbc, it's retried again (3) if you wrap ast_clear_odbc_cache in a res_config_odbc function (my_clear_odbc_cache) the error goes away (I added ast_log(NOTICE.. "Loading..)) before the 2 dlopen calls) ---- Module order in the directory: {code} $ find /usr/lib/asterisk/modules/ -type f | head /usr/lib/asterisk/modules/app_waitforring.so /usr/lib/asterisk/modules/app_stack.so /usr/lib/asterisk/modules/func_rand.so ... {code} Module order at load time: {code} 189 modules will be loaded. Loading module (a) 'app_waitforring.so': /usr/lib/asterisk/modules/app_waitforring.so Loading module (a) 'app_stack.so': /usr/lib/asterisk/modules/app_stack.so Loading module (a) 'func_rand.so': /usr/lib/asterisk/modules/func_rand.so ... {code} ---- Now, if I reshuffle the files in the path to get res_config_odbc first, we get this: (I got it in the dir in the preceding order by renaming it to rres_config_odbc.so, your mileage may vary) {code} Loading module (a) 'rres_config_odbc.so': /usr/lib/asterisk/modules/rres_config_odbc.so Error loading module 'rres_config_odbc.so': /usr/lib/asterisk/modules/rres_config_odbc.so: undefined symbol: ast_odbc_clear_cache ... Loading module (a) 'res_odbc.so': /usr/lib/asterisk/modules/res_odbc.so Loading module (b) 'res_odbc.so': /usr/lib/asterisk/modules/res_odbc.so ... Loading module (a) 'rres_config_odbc.so': /usr/lib/asterisk/modules/rres_config_odbc.so Loading module (b) 'rres_config_odbc.so': /usr/lib/asterisk/modules/rres_config_odbc.so {code} It gets loaded a second time because load_resource returns AST_MODULE_LOAD_SKIP after the failure. ---- Wrapping ast_clear_odbc_cache makes the error go away. res_config_odbc still gets loaded twice though: {code} --- res/res_config_odbc.c (revision 334212) +++ res/res_config_odbc.c (working copy) @@ -1131,6 +1131,10 @@ #undef warn_length #undef warn_type +static int my_odbc_clear_cache(const char *database, const char *tablename) { + return ast_odbc_clear_cache(database, tablename); +} + static struct ast_config_engine odbc_engine = { .name = "odbc", .load_func = config_odbc, @@ -1141,7 +1145,7 @@ .update_func = update_odbc, .update2_func = update2_odbc, .require_func = require_odbc, - .unload_func = ast_odbc_clear_cache, + .unload_func = my_odbc_clear_cache, }; static int unload_module (void) {code} (example with autoload=no and load=>res_config_odbc.so,load=>res_odbc.so) {code} Loading module (a) 'res_config_odbc.so': /usr/lib/asterisk/modules/res_config_odbc.so Loading module (a) 'res_odbc.so': /usr/lib/asterisk/modules/res_odbc.so Loading module (b) 'res_odbc.so': /usr/lib/asterisk/modules/res_odbc.so Loading module (a) 'res_config_odbc.so': /usr/lib/asterisk/modules/res_config_odbc.so Loading module (b) 'res_config_odbc.so': /usr/lib/asterisk/modules/res_config_odbc.so {code} By: Tilghman Lesher (tilghman) 2011-08-31 20:46:06.492-0500 Walter- Aha, you're right. The issue is that because we're dealing with a function pointer, it's resolved as a variable, which means lazy binding won't work. I agree with your workaround (wrapping the function). |