I'm observing some weird behaviour from a relatively simple piece of code and would like to ask if anybody has seen such before.
The code below is a basic example for allocating memory inside a function and returning a pointer to it (you can find similar in most C textbooks).
// BROKEN CODE EXAMPLE:
// Function which returns a char pointer
char *f() {
// Allocate some memory; 1024 is merely an example
char *c = malloc(1024);
return c;
}
// Calling function
void main_f() {
char *c = f();
// Do some stuff here
free(c);
}
In my actual program the main_f()
function is repeatedly called from its main loop. Everything works as expected when the main_f()
function is compiled into the program's executable or comes from a library that the executable is linked to.
However, if the code resides in a shared library that the executable loads using dlopen()
, a strange thing happens: after a random number of iterations (which may be 5, 15, 50 or even more) the code crashes with SIGSEGV. Debugging the code reveals that the crash happens exactly when return
is called.
Adding to the weirdness is that, found by trial and error, a simple cure for the crash is not to return a pointer from the f()
function, but supply the function with a double pointer:
// WORKING CODE EXAMPLE:
// Modify the function to use a double pointer
void f(char **c) {
// Allocate some memory; 1024 is merely an example
*c = malloc(1024);
}
// Calling function
void main_f() {
char *c;
f(&c);
// Do some stuff here
free(c);
}
The actual code is part of a GTK+ program and runs inside the main loop of GLib. The said program does not create additional threads but executes the above stanza once a minute via timer (and runs do not overlap). The shared library is loaded only once via dlopen()
at init time.
Could it be that malloc(), dlopen() and GLib do not always play nice? The actual program is UNIX-only, so we saw no need to resort to GLib-provided portable functions like g_malloc()
or larger objects like GModule
; would it make any sense to prefer them though?
Has anybody else seen this issue?