[asterisk-dev] ugly fix for module embedding bug (Re: module embedding help ?)

Luigi Rizzo rizzo at icir.org
Tue Nov 6 09:52:01 CST 2007


I found the bug that causes module embedding not to work on FreeBSD
(and maybe on other architectures too).

Module embedding is implemented using some linker magic that
causes ast_module_register() to be called for each of the
embedded objects.
This in turn adds the entry to a list, module_list, in main/loader.c

The problem is that module_list itself has a constructor associated:

	static AST_LIST_HEAD_STATIC(module_list, ast_module);

which happens (at least on FreeBSD) to be called _after_ the
other constructors. The constructor resets module_list to
empty, so you can imagine the result.

I have an ugly fix, below - store the relevant values from
module_list in a static variable not subject to constructors,
and restore module_list from that variable near the beginning
of load_modules().

However i don't like it too much, and furthermore I am afraid that
the same problem - unspecified order in the execution of
constructors - may appear also in other parts of the code.

Anyways, if you think it is ok to commit this one i will do
as a temporary bandaid.

	cheers
	luigi

Index: main/loader.c
===================================================================
--- main/loader.c	(revision 88929)
+++ main/loader.c	(working copy)
@@ -110,6 +110,10 @@
 */
 struct ast_module *resource_being_loaded;
 
+static struct _mine {
+	void *modlist_first;
+	void *modlist_last;
+} mine;
 /* XXX: should we check for duplicate resource names here? */
 
 void ast_module_register(const struct ast_module_info *info)
@@ -142,6 +156,10 @@
 	   just opened was registered or failed to load
 	*/
 	AST_LIST_INSERT_TAIL(&module_list, mod, entry);
+	if (embedding) {
+		mine.modlist_first = module_list.first;
+		mine.modlist_last = module_list.last;
+	}
 
 	if (!embedding)
 		AST_LIST_UNLOCK(&module_list);
@@ -738,6 +755,11 9@@
        AST_LIST_HEAD_INIT_NOLOCK(&load_order);

        AST_LIST_LOCK(&module_list);
+	if (mine.modlist_first) {
+		module_list.first = mine.modlist_first;
+		module_list.last = mine.modlist_last;
+		mine.modlist_first = NULL;
+	}
        if (!(cfg = ast_config_load(AST_MODULE_CONFIG, config_flags))) {
                ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
                goto done;



More information about the asterisk-dev mailing list