Hi, I'm new to embedding and also to GTK, so it's very likely that I'm misssing something quite obvious here, I apologize in advance if that's the case, I also apologize for the long post, but I wanted to include everything I think could be relevant.
Scenario: I'm trying to embed Gecko into a C application that uses extensive multithreading, the general idea is that once the gtkmozembed widget is running, it can be controlled from a separated thread (i.e load a different url, reload, etc.) Problem: So far I've been able to embed gtkmozembed into the application, trouble is that when the first call is made to any function that receives the gtkmozembed widget as a parameter i.e: gtk_moz_embed_load_url(GTK_MOZ_EMBED(mozembed), "http://www.yahoo.com"); from a different thread that the one that created the widget, I get a SIGSEV crash. Debug: I tried to debug the issue, and so far I found that it's not GTK related, because I can control the main window widget from other threads without any trouble. It seems that the pointer to the gtkmozembed widget is NULL right after calling gtk_main(). To further test the behavior I replaced the threads with a timed event inside a loop that calls gtk_main_iteration_do(FALSE), instead of using gtk_main(). This does work, so it may indicate that the issue is related to gtkmozembed and threads. I've have tried using pthreads in the usual way, and also gthreads of glib, with the same result. Questions: I'm I missing something obvious here ?, Is there any special considerations that need to be taken into account when using gtkmozembed widget in a multithread application ? Versions: Tested in 2 different platforms: FC3: 2.6.12-1.1381_FC3smp gcc version 3.4.4 20050721 (Red Hat 3.4.4-2) glibc-2.3.6-0.fc3.1 gtk2-2.4.14-4.fc3.3 glib2-2.4.8-1.fc3 mozilla-1.7.12-1.3.1 mozilla-devel-1.7.12-1.3.1 mozilla-nspr-1.7.12-1.3.1 mozilla-nspr-devel-1.7.12-1.3.1 mozilla-nss-devel-1.7.12-1.3.1 mozilla-nss-1.7.12-1.3.1 FC5:2.6.19-1.2288.fc5smp gcc version 4.1.1 20060525 (Red Hat 4.1.1-1) glibc-2.4.90-15 glib2-2.10.3-1 gtk2-2.8.20-1 mozilla-1.7.13-1.1.fc5 mozilla-devel-1.7.13-1.1.fc5 Any suggestions will be highly appreciated, thanks in advance. Dante ============================= test case ============================= /* test_mozembed.cpp * Should display a browser window, and after 5 secs will move the window to a different * position, and after 10 secs should load a different url. * * By defining DONT_USE_THREADS threads and gtk_main() are not used, and the programm runs ok * when DONT_USE_THREADS is undefined threads and gtk_main() are used and the programm crahses * * compiled with: * g++ -ggdb3 -o test_mozembed{,.cpp} \ * -I/usr/include/mozilla-1.7.13 \ * -I/usr/include/mozilla-1.7.13/xpcom \ * -I/usr/include/mozilla-1.7.13/gtkembedmoz \ * -L/usr/lib/mozilla-1.7.13 \ * -I/usr/include/nspr4 \ * -lgtkembedmoz \ * `pkg-config --cflags --libs gtk+-2.0 gthread-2.0` */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <time.h> #include <pthread.h> #include <gtk/gtk.h> #include <glib.h> #include <gtkmozembed.h> //#define DONT_USE_THREADS void *thread1(void *pv_Param); void *thread2(void *pv_Param); gint event_delete(GtkWidget *gtkwidget, GdkEvent *gdkevent, gpointer param); void event_destroy(GtkWidget *gtkwidget, gpointer param); GtkWidget *mainwin, *vbox, *mozembed; int end; int signalid[2]; GThread *gthread1, *gthread2; GError *err1 = NULL, *err2 = NULL; int main(int argc, char *argv[]) { int executed1, executed2; time_t start1, elapsed1, start2, elapsed2; gtk_init(&argc, (char ***)(&argv)); #ifndef DONT_USE_THREADS if(!g_thread_supported()) { g_thread_init(NULL); gdk_threads_init(); printf("main: g_thread supported\n"); } else { printf("main: g_thread NOT supported\n"); } #endif gtk_moz_embed_set_profile_path(".", "mozembed"); if((mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL)) == NULL) { printf("main: Creating main window\n"); exit(1); } printf("main: Main window created ok\n"); gtk_widget_set_usize(mainwin, 800, 600); gtk_window_resize(GTK_WINDOW(mainwin), 800, 600); gtk_window_move(GTK_WINDOW(mainwin), 100, 100); if((vbox = gtk_vbox_new(FALSE, 0)) == NULL) { printf("main: Creating vertical box\n"); exit(1); } printf("main: Vertical box created ok\n"); gtk_window_set_decorated(GTK_WINDOW(mainwin), TRUE); gtk_window_set_resizable(GTK_WINDOW(mainwin), TRUE); gtk_window_set_title(GTK_WINDOW(mainwin), "Test"); if((mozembed = gtk_moz_embed_new()) == NULL) { printf("main: Creating mozilla widget\n"); exit(1); } printf("main: Mozilla widget box created ok\n"); gtk_box_pack_start(GTK_BOX(vbox), mozembed, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(mainwin), vbox); signalid[0] = g_signal_connect(G_OBJECT(mainwin), "delete_event", G_CALLBACK(event_delete), NULL); signalid[1] = g_signal_connect(G_OBJECT(mainwin), "destroy", G_CALLBACK(event_destroy), NULL); printf("main: Browser created ok\n"); gtk_moz_embed_load_url(GTK_MOZ_EMBED(mozembed), "http://www.google.com"); printf("main: Loading url http://www.google.com\n"); gtk_widget_show(mozembed); gtk_widget_show(vbox); gtk_widget_show(mainwin); #ifndef DONT_USE_THREADS if((gthread1 = g_thread_create((GThreadFunc)thread1, NULL, TRUE, &err1)) == NULL) { printf("main: Thread create failed: %s!!\n", err1->message ); g_error_free(err1) ; } printf("main: gthread1 created ok\n"); if((gthread2 = g_thread_create((GThreadFunc)thread2, NULL, TRUE, &err2)) == NULL) { printf("main: Thread create failed: %s!!\n", err2->message ); g_error_free(err2) ; } printf("main: gthread2 created ok\n"); #endif printf("main: Entering gtk main loop\n"); /* dirty workaround, just to test if the trouble doest't * happend when not using threads and gtk_main() */ #ifdef DONT_USE_THREADS end = FALSE; executed1 = FALSE; start1 = start2 = time(NULL); executed2 = FALSE; while(!end) { gtk_main_iteration_do(FALSE); elapsed1 = time(NULL) - start1; if(!executed1 && elapsed1 >= 10) { printf("main: Loading http://www.yahoo.com\n"); gtk_moz_embed_load_url(GTK_MOZ_EMBED(mozembed), "http://www.yahoo.com"); executed1 = TRUE; } elapsed2 = time(NULL) - start2; if(!executed2 && elapsed2 >= 5) { printf("main: Moving window\n"); gtk_window_move(GTK_WINDOW(mainwin), 200, 200); executed2 = TRUE; } } #else gtk_main(); #endif return(0); } void *thread1(void *param) { printf("thread1: Waiting...\n"); sleep(10); printf("thread1: Loading http://www.yahoo.com\n"); gtk_moz_embed_load_url(GTK_MOZ_EMBED(mozembed), "http://www.yahoo.com"); printf("thread1: Ending\n"); return(NULL); } void *thread2(void *param) { printf("thread2: Waiting...\n"); sleep(20); printf("thread2: Moving window\n"); gtk_window_move(GTK_WINDOW(mainwin), 200, 200); printf("thread2: Ending\n"); return(NULL); } gint event_delete(GtkWidget *gtkwidget, GdkEvent *gdkevent, gpointer param) { printf("Delete event\n"); return(FALSE); } void event_destroy(GtkWidget *gtkwidget, gpointer param) { end = TRUE; gtk_main_quit(); gtk_exit(FALSE); printf("Destroy event\n"); } ============================= gdb session ============================= (gdb) run Starting program: /home/gtrevize/workspace/tbx/test/tst_browser1_d Reading symbols from shared object read from target memory...done. Loaded system supplied DSO at 0xb25000 [Thread debugging using libthread_db enabled] [New Thread -1208390976 (LWP 1835)] main: g_thread supported main: Main window created ok main: Vertical box created ok [New Thread 33373088 (LWP 1838)] main: Mozilla widget box created ok main: Browser created ok main: Loading url http://www.google.com Detaching after fork from child process 1839. [New Thread 145013664 (LWP 1841)] [New Thread -1222644832 (LWP 1843)] [New Thread -1212154976 (LWP 1842)] main: gthread1 created ok [New Thread -1233134688 (LWP 1844)] main: gthread2 created ok main: Entering gtk main loop thread1: Waiting... thread2: Waiting... [New Thread -1243624544 (LWP 1845)] [New Thread -1254114400 (LWP 1846)] thread1: Loading http://www.yahoo.com Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1212154976 (LWP 1842)] 0x00ec9984 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libnecko.so (gdb) backtrace #0 0x00ec9984 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libnecko.so #1 0x00ec9a7a in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libnecko.so #2 0x00ec98ec in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libnecko.so #3 0x020adaf7 in nsCOMPtr_base::~nsCOMPtr_base$base () from /usr/lib/mozilla-1.7.13/libxpcom.so #4 0x00f59d72 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libnecko.so #5 0x00f5dc00 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libnecko.so #6 0x04caa476 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libdocshell.so #7 0x04caaba1 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libdocshell.so #8 0x04c84302 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libdocshell.so #9 0x04c8e619 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libdocshell.so #10 0x04c966c9 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libdocshell.so #11 0x04c8f96c in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libdocshell.so #12 0x04c8c562 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libdocshell.so #13 0x00834b33 in NSGetModule () from /usr/lib/mozilla-1.7.13/components/libwebbrwsr.so #14 0x0032f388 in EmbedPrivate::LoadCurrentURI () from /usr/lib/mozilla-1.7.13/libgtkembedmoz.so #15 0x0032b034 in gtk_moz_embed_load_url () from /usr/lib/mozilla-1.7.13/libgtkembedmoz.so #16 0x0804904e in thread1 (param=0x0) at tst_browser1.cpp:153 #17 0x0048c9ff in g_thread_create_full () from /usr/lib/libglib-2.0.so.0 #18 0x00c2dfb5 in start_thread () from /lib/libpthread.so.0 #19 0x00a5abae in clone () from /lib/libc.so.6 ================== valgrind output (partial) ================== Process terminating with default action of signal 11 (SIGSEGV) Access not within mapped region at address 0x0 at 0x4A1C984: (within /usr/lib/mozilla-1.7.13/components/libnecko.so) by 0x4A1CA79: (within /usr/lib/mozilla-1.7.13/components/libnecko.so) by 0x4A1C8EB: (within /usr/lib/mozilla-1.7.13/components/libnecko.so) by 0x20ADAF6: nsCOMPtr_base::~nsCOMPtr_base() (in /usr/lib/mozilla-1.7.13/libxpcom.so) by 0x4AACD71: (within /usr/lib/mozilla-1.7.13/components/libnecko.so) by 0x4AB0BFF: (within /usr/lib/mozilla-1.7.13/components/libnecko.so) by 0x53BE475: (within /usr/lib/mozilla-1.7.13/components/libdocshell.so) by 0x53BEBA0: (within /usr/lib/mozilla-1.7.13/components/libdocshell.so) by 0x5398301: (within /usr/lib/mozilla-1.7.13/components/libdocshell.so) by 0x53A2618: (within /usr/lib/mozilla-1.7.13/components/libdocshell.so) by 0x53AA6C8: (within /usr/lib/mozilla-1.7.13/components/libdocshell.so) by 0x53A396B: (within /usr/lib/mozilla-1.7.13/components/libdocshell.so) _______________________________________________ dev-embedding mailing list [email protected] https://lists.mozilla.org/listinfo/dev-embedding
