Segmentation Fault GTK+ application [duplicate] - c
This question already has answers here:
Why do I get a segmentation fault in my GTK+ signal callback?
(2 answers)
Closed 5 years ago.
I'm making a GTK 3+ application using Glade.
Here is my structure in C :
# include <gtk/gtk.h>
# include <stdio.h>
# include <stdlib.h>
typedef struct s_gtk
{
GtkBuilder *interface;
GtkWidget *MainWindow;
GtkWidget *AddObject;
GtkWidget *DeleteObject;
GtkWidget *Launch;
GError *error;
gchar *filename;
} t_gtk;
My function for intializing gtk->AddObject, it is called in the main :
if ((gtk->interface = gtk_builder_new()) == NULL ||
(gtk->filename = g_build_filename("interface.glade", NULL)) == NULL)
{
g_error("%s", gtk->error->message);
g_error_free(gtk->error);
return (gtk->error->code);
}
gtk_builder_add_from_file(gtk->interface, gtk->filename, >k->error);
g_free(gtk->filename);
if (gtk->error)
{
g_printerr("%s\n", gtk->error->message);
g_error_free(gtk->error);
return (gtk->error->code);
}
gtk->MainWindow = GTK_WIDGET(gtk_builder_get_object
(gtk->interface, "MainWindow"));
gtk->AddObject = GTK_WIDGET(gtk_builder_get_object
(gtk->interface, "AddDialog"));
gtk_builder_connect_signals(gtk->interface, gtk);
return (0);
My handler for AddObject:
void on_AddObject_clicked(gpointer user_data)
{
t_gtk *gtk;
gint response;
gtk = (t_gtk *)user_data;
printf("I'm here\n");
response = gtk_dialog_run(GTK_DIALOG(gtk->AddObject));
printf("I'm here2\n");
if (response == 1)
{
printf("Add pressed!\n");
}
else
{
printf("Cancel pressed!\n");
}
gtk_widget_hide(gtk->AddObject);
}
And I get a Segfault here but I don't know why...:
response = gtk_dialog_run(GTK_DIALOG(gtk->AddObject));
Valgrind says it:
Invalid read of size 8
==7272== at 0x6B16620: g_type_check_instance_cast (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x401063: on_AddObject_clicked (in /home/vives_j/Documents/Epitech/Tests/main)
==7272== by 0x6AF3473: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D086: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D9DE: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x4F3CA1C: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1400.5)
==7272== by 0x4F3CA74: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1400.5)
==7272== by 0x6AF3473: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D086: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D9DE: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x4F3A9FF: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1400.5)
==7272== by 0xB795DBF: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.2)
==7272== Address 0x400000003 is not stack'd, malloc'd or (recently) free'd
==7272==
==7272==
==7272== Process terminating with default action of signal 11 (SIGSEGV)
==7272== Access not within mapped region at address 0x400000003
==7272== at 0x6B16620: g_type_check_instance_cast (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x401063: on_AddObject_clicked (in /home/vives_j/Documents/Epitech/Tests/main)
==7272== by 0x6AF3473: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D086: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D9DE: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x4F3CA1C: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1400.5)
==7272== by 0x4F3CA74: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1400.5)
==7272== by 0x6AF3473: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D086: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x6B0D9DE: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==7272== by 0x4F3A9FF: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1400.5)
==7272== by 0xB795DBF: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.2)
==7272== If you believe this happened as a result of a stack
==7272== overflow in your program's main thread (unlikely but
==7272== possible), you can try to increase the size of the
==7272== main thread stack using the --main-stacksize= flag.
==7272== The main thread stack size used in this run was 8388608.
And I compile as (From make command):
gcc -Wextra -Wall -ansi -pedantic -I. -O3 -D REENTRANT -rdynamic -DGTK_DISABLE_DEPRECATED=1 -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DG_DISABLE_DEPRECATED -DGTK_MULTIHEAD_SAFE=1 -DGTK_MULTIDEVICE_SAFE=1 `pkg-config gmodule-export-2.0 --libs` `pkg-config gtk+-3.0 --cflags` -c -o main.o main.c
gcc main.o -o main `pkg-config gtk+-3.0 --libs` `pkg-config gmodule-export-2.0 --libs`
GDB results :
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./main...done.
(gdb)
(gdb) run
Starting program: /home/vives_j/Documents/Epitech/Tests/main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
(process:3752): Gtk-WARNING **: Locale not supported by C library.
Using the fallback 'C' locale.
[New Thread 0x7fffee33c700 (LWP 3756)]
[New Thread 0x7fffedb3b700 (LWP 3757)]
[New Thread 0x7fffecfe7700 (LWP 3759)]
I'm here
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff5f0f620 in g_type_check_instance_cast ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
(gdb) backtrac
#0 0x00007ffff5f0f620 in g_type_check_instance_cast ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#1 0x0000000000401034 in on_AddObject_clicked (user_data=0x8d0350)
at main.c:57
#2 0x00007ffff5eec474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#3 0x00007ffff5f06087 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#4 0x00007ffff5f069df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#5 0x00007ffff762ca1d in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#6 0x00007ffff762ca75 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#7 0x00007ffff5eec474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#8 0x00007ffff5f06087 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#9 0x00007ffff5f069df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 0x00007ffff762aa00 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#11 0x00007ffff127edc0 in ffi_call_unix64 ()
from /usr/lib/x86_64-linux-gnu/libffi.so.6
#12 0x00007ffff127e828 in ffi_call ()
from /usr/lib/x86_64-linux-gnu/libffi.so.6
---Type <return> to continue, or q <return> to quit---
#13 0x00007ffff5eecebc in g_cclosure_marshal_generic_va ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#14 0x00007ffff5eec474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#15 0x00007ffff5f06087 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#16 0x00007ffff5f069df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#17 0x00007ffff76cf191 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#18 0x00007ffff5eef233 in g_cclosure_marshal_VOID__BOXEDv ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#19 0x00007ffff5eec474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#20 0x00007ffff5f06087 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#21 0x00007ffff5f069df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#22 0x00007ffff76cc94e in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#23 0x00007ffff76cdd9b in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#24 0x00007ffff76d05e0 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#25 0x00007ffff76a3e7b in gtk_event_controller_handle_event ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#26 0x00007ffff783f41d in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
---Type <return> to continue, or q <return> to quit---
#27 0x00007ffff771241e in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#28 0x00007ffff5eec474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#29 0x00007ffff5f05b30 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#30 0x00007ffff5f069df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#31 0x00007ffff7842de4 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#32 0x00007ffff770fd2e in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#33 0x00007ffff771193e in gtk_main_do_event ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#34 0x00007ffff72b8b12 in ?? () from /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#35 0x00007ffff5c16c5d in g_main_context_dispatch ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#36 0x00007ffff5c16f48 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#37 0x00007ffff5c17272 in g_main_loop_run ()
from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#38 0x00007ffff7710bf5 in gtk_main ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#39 0x0000000000401275 in main (ac=1, av=0x7fffffffdcf8) at main.c:115
(gdb) quit
The line 57 is the line I posted previously where it crashed.
Glade file :
http://pastebin.com/JrHza6iW
I think I have a clue. Because, when I took this example code from a tutorial :
http://pastebin.com/WpJ6kWQB
and compiled it with (and their builder file):
gcc -o dialog1 dialog1.c $(pkg-config --cflags --libs gtk+-2.0 \
* gmodule-export-2.0)
It works, but if I change gtk+-2.0 by 3.0, it crashes at the same thing.
Thank you in advance !!
I found the problem.
In my handler function, we need to pass in parameter the type of the widget we clicked. Here, it's a GtkButton, so I added it in my parameters that I receive :
void on_AddObject_clicked(GtkButton *button, gpointer user_data)
{
t_gtk *gtk;
gint response;
gtk = (t_gtk *)user_data;
(void) button;
printf("I'm here\n");
response = gtk_dialog_run(GTK_DIALOG(gtk->AddObject));
printf("I'm here2\n");
if (response == 1)
{
printf("Add pressed!\n");
}
else
{
printf("Cancel pressed!\n");
}
gtk_widget_hide(gtk->AddObject);
}
I think GTK needs it in background. So it's resolved.
Thank you anyway for your help ! :)
Valgrind won't help you much here. Delete the .o and executable, recompile adding -g and -O0 to the compile commands.
Then run gdb, and, when the segmentation fault occurs, do a backtrace. You should be able to follow that to where the problem is. (post the backtrace here)
Did you see any message during the run? Even warnings?
Related
How to verify if a symbol-file is compatible with an executable?
I experience problems analyzing a core dump for an ELF executable accompanied by symbol-file. Without symbols file I see just function name symbols in back trace: Core was generated by `./DSWP.out'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x00005614b4dc58fd in ntl_avl3_find () [Current thread is 1 (LWP 1344)] (gdb) bt #0 0x00005614b4dc58fd in ntl_avl3_find () #1 0x00005614b3ed4c03 in qbra_aro_find_route () #2 0x00005614b3ed5c70 in qbra_is_aro_lu_route_found () #3 0x00005614b3ed71ba in qbra_aro_add_route () #4 0x00005614b3f33c9b in qbum_cont_aro_announced () #5 0x00005614b3e4fe4f in qbdc_sub_stage_aro_announce () #6 0x00005614b3e4e23b in qbdc_do_work_part_3 () #7 0x00005614b3e4f4a0 in qbdc_do_work () #8 0x00005614b3ef20d3 in qbrm_conn_fsm () #9 0x00005614b3f0c282 in qbrm_process_established () #10 0x00005614b3df1a60 in qbrm_receive_proc () #11 0x00005614b4dfa78d in nbb_dispatch_process () #12 0x00005614b4dfc0f5 in nbb_schedule_one () #13 0x00005614b4e0effe in nbb_mp_scheduler () #14 0x00005614b4e0f0cb in nbb_sched_thread_main_fn () #15 0x00007f6284399ed4 in ?? () from /lib64/libpthread.so.0 #16 0x00007f6283bf5e4f in clone () from /lib64/libc.so.6 And when I load symbol-file, the stack gets shorter and some symbols disappear: (gdb) symbol-file DSWP.symbols Reading symbols from DSWP.symbols... warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. (gdb) bt #0 0x00005614b4dc58fd in ntl_avl3_find (tree=0x4c026e90, key=key#entry=0x7f61717f9ae8, tree_info=0x4c026ea8) at code/comn/ntlavll.c:510 #1 0x00005614b3ed4c03 in qbra_aro_find_route (aro_cb=<optimized out>, dest_prefix=<optimized out>) at code/bgp/qbraaro1.c:1538 #2 0x00007f616001b7c0 in ?? () #3 0x00007f61717f9b20 in ?? () #4 0x00005614b3ed5c70 in qbra_is_aro_lu_route_found (nlri=0x7f616001b7c0, route_aro_cb=0x7f614c026c78) at code/bgp/qbraaro1.c:2233 Is there a way to verify executable and symbol-file are compatible with each other? or to understand what went wrong while creating the symbols file?
MinGW's GDB does not show my stackframes on SegFault
On MinGW's GDB (7.6.1) I sometimes run into the problem that a SegFault does not leave much useful information on the stacks (see transcript below). For the error in the transcript I know why it occured: I called fseeki64 with a bad value as file-pointer. The fseeki64 does appear in the stack-trace but I cant see which part of my program indirectly called it. I dont want to see the Microsoft symbols, I want to see the part of the stack that belongs to my program (which was compiled with -g). Since I dont run into SegFaults often, my current workaround is some manual labor: 'next' through main (spamming enter) to find out which top-level function was responsible, restart, 'step' (spamming enter) through that function until the segfault. GNU gdb (GDB) 7.6.1 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "mingw32". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from A:\prj\lib\fileBuffer\test.exe...done. (gdb) r Starting program: A:\prj\lib\fileBuffer/test.exe [New Thread 3408.0x4094] [New Thread 3408.0x3e40] [New Thread 3408.0x4c14] [New Thread 3408.0x5754] Program received signal SIGSEGV, Segmentation fault. 0x77e2b2e3 in ?? () (gdb) info thr Id Target Id Frame 4 Thread 3408.0x5754 0x77e5396c in ?? () 3 Thread 3408.0x4c14 0x77e5396c in ?? () 2 Thread 3408.0x3e40 0x77e5396c in ?? () * 1 Thread 3408.0x4094 0x77e2b2e3 in ?? () (gdb) where #0 0x77e2b2e3 in ?? () #1 0x74d38384 in msvcrt!__p__iob () from C:\WINDOWS\SysWOW64\msvcrt.dll #2 0x000000f4 in ?? () #3 0x000000d4 in ?? () #4 0x0063fd88 in ?? () #5 0x74d43175 in msvcrt!_fseeki64 () from C:\WINDOWS\SysWOW64\msvcrt.dll #6 0x000000d4 in ?? () #7 0x0ab2d946 in ?? () #8 0x00000000 in ?? () (gdb) thr 2 [Switching to thread 2 (Thread 3408.0x3e40)] #0 0x77e5396c in ?? () (gdb) where #0 0x77e5396c in ?? () #1 0x75588744 in KERNEL32!BaseThreadInitThunk () from C:\WINDOWS\SysWOW64\kernel32.dll #2 0x77e4582d in ?? () #3 0x77e457fd in ?? () #4 0x00000000 in ?? () (gdb) thr 3 [Switching to thread 3 (Thread 3408.0x4c14)] #0 0x77e5396c in ?? () (gdb) where #0 0x77e5396c in ?? () #1 0x75588744 in KERNEL32!BaseThreadInitThunk () from C:\WINDOWS\SysWOW64\kernel32.dll #2 0x77e4582d in ?? () #3 0x77e457fd in ?? () #4 0x00000000 in ?? () (gdb) thr 4 [Switching to thread 4 (Thread 3408.0x5754)] #0 0x77e5396c in ?? () (gdb) where #0 0x77e5396c in ?? () #1 0x75588744 in KERNEL32!BaseThreadInitThunk () from C:\WINDOWS\SysWOW64\kernel32.dll #2 0x77e4582d in ?? () #3 0x77e457fd in ?? () #4 0x00000000 in ?? () (gdb)
LD_PRELOAD with possible static shared library functions
My objective is to hook the open function that dlopen on linux uses. For some reason, this code is not hooking dlopen->open, but it does hook my version of open main.c->open. Is dlopen not using my symbols somehow? Compilation process is as follows: gcc main.c -ldl -ggdb gcc fake-open.c -o libexample.so -fPIC -shared export LD_PRELOAD="$PWD/libexample.so" When I run the program, everything works. Ensuring the LD_PRELOAD variable is set.. etc. Here is the problem, when I try to hook the open function directly or indirectly called by dlopen, somehow this "version" of open is not being resolved/redirected/hooked by my version. [main.c] #include <dlfcn.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { puts("calling open"); int fd = open("/tmp/test.so", O_RDONLY|O_CLOEXEC); puts("calling dlopen"); int *handle = dlopen("/tmp/test.so", RTLD_LAZY); } [fake-open.c] #define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h> #include <sys/types.h> #include <sys/stat.h> //#include <fcntl.h> int open(const char *pathname, int flags) { puts("from hooked.."); return 1; } Console Output: calling open from hooked.. calling dlopen I know for a fact dlopen is somehow calling open due to strace. write(1, "calling open\n", 13calling open ) = 13 write(1, "from hooked..\n", 14from hooked.. ) = 14 write(1, "calling dlopen\n", 15calling dlopen ) = 15 brk(0) = 0x804b000 brk(0x806c000) = 0x806c000 open("/tmp/test.so", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2\0\3\0\1\0\0\0`\205\4\0104\0\0\0"..., 512) = 512 But, for some reason, when dlopen calls open, it is not using my version of open. This has to be some kind of linking of run time symbol resolution problem, or perhaps dlopen is using a static version of open and doesnt need to resolve any symbols at run or load time?
First, contrary to #usr's answer, dlopen does open the library. We can confirm this by running a simple test under GDB: // main.c #include <dlfcn.h> int main() { void *h = dlopen("./foo.so", RTLD_LAZY); return 0; } // foo.c; compile with "gcc -fPIC -shared -o foo.so foo.c" int foo() { return 0; } Let's compile and run this: gdb -q ./a.out (gdb) start Temporary breakpoint 1 at 0x400605: file main.c, line 4. Starting program: /tmp/a.out Temporary breakpoint 1, main () at main.c:4 4 void *h = dlopen("./foo.so", RTLD_LAZY); (gdb) catch syscall open Catchpoint 2 (syscall 'open' [2]) (gdb) c Continuing. Catchpoint 2 (call to syscall open), 0x00007ffff7df3497 in open64 () at ../sysdeps/unix/syscall-template.S:81 81 ../sysdeps/unix/syscall-template.S: No such file or directory. (gdb) bt #0 0x00007ffff7df3497 in open64 () at ../sysdeps/unix/syscall-template.S:81 #1 0x00007ffff7ddf5bd in open_verify (name=0x602010 "./foo.so", fbp=0x7fffffffd568, loader=<optimized out>, whatcode=<optimized out>, found_other_class=0x7fffffffd550, free_name=<optimized out>) at dl-load.c:1930 #2 0x00007ffff7de2d6f in _dl_map_object (loader=loader#entry=0x7ffff7ffe1c8, name=name#entry=0x4006a4 "./foo.so", type=type#entry=2, trace_mode=trace_mode#entry=0, mode=mode#entry=-1879048191, nsid=0) at dl-load.c:2543 #3 0x00007ffff7deea14 in dl_open_worker (a=a#entry=0x7fffffffdae8) at dl-open.c:235 #4 0x00007ffff7de9fc4 in _dl_catch_error (objname=objname#entry=0x7fffffffdad8, errstring=errstring#entry=0x7fffffffdae0, mallocedp=mallocedp#entry=0x7fffffffdad0, operate=operate#entry=0x7ffff7dee960 <dl_open_worker>, args=args#entry=0x7fffffffdae8) at dl-error.c:187 #5 0x00007ffff7dee37b in _dl_open (file=0x4006a4 "./foo.so", mode=-2147483647, caller_dlopen=<optimized out>, nsid=-2, argc=1, argv=0x7fffffffde28, env=0x7fffffffde38) at dl-open.c:661 #6 0x00007ffff7bd702b in dlopen_doit (a=a#entry=0x7fffffffdd00) at dlopen.c:66 #7 0x00007ffff7de9fc4 in _dl_catch_error (objname=0x7ffff7dd9110 <last_result+16>, errstring=0x7ffff7dd9118 <last_result+24>, mallocedp=0x7ffff7dd9108 <last_result+8>, operate=0x7ffff7bd6fd0 <dlopen_doit>, args=0x7fffffffdd00) at dl-error.c:187 #8 0x00007ffff7bd762d in _dlerror_run (operate=operate#entry=0x7ffff7bd6fd0 <dlopen_doit>, args=args#entry=0x7fffffffdd00) at dlerror.c:163 #9 0x00007ffff7bd70c1 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87 #10 0x0000000000400614 in main () at main.c:4 This tells you that on 64-bit system, dlopen calls open64 instead of open, so your interposer wouldn't work (you'd need to interpose open64 instead). But you are on a 32-bit system (as evidenced by the 0x806c000 etc. addresses printed by strace), and there the stack trace looks like this: #0 0xf7ff3774 in open () at ../sysdeps/unix/syscall-template.S:81 #1 0xf7fe1211 in open_verify (name=0x804b008 "./foo.so", fbp=fbp#entry=0xffffc93c, loader=0xf7ffd938, whatcode=whatcode#entry=0, found_other_class=found_other_class#entry=0xffffc933, free_name=free_name#entry=true) at dl-load.c:1930 #2 0xf7fe4114 in _dl_map_object (loader=loader#entry=0xf7ffd938, name=name#entry=0x8048590 "./foo.so", type=type#entry=2, trace_mode=trace_mode#entry=0, mode=mode#entry=-1879048191, nsid=0) at dl-load.c:2543 #3 0xf7feec14 in dl_open_worker (a=0xffffccdc) at dl-open.c:235 #4 0xf7feac06 in _dl_catch_error (objname=objname#entry=0xffffccd4, errstring=errstring#entry=0xffffccd8, mallocedp=mallocedp#entry=0xffffccd3, operate=operate#entry=0xf7feeb50 <dl_open_worker>, args=args#entry=0xffffccdc) at dl-error.c:187 #5 0xf7fee644 in _dl_open (file=0x8048590 "./foo.so", mode=-2147483647, caller_dlopen=0x80484ea <main+29>, nsid=<optimized out>, argc=1, argv=0xffffcf74, env=0xffffcf7c) at dl-open.c:661 #6 0xf7fafcbc in dlopen_doit (a=0xffffce90) at dlopen.c:66 #7 0xf7feac06 in _dl_catch_error (objname=0xf7fb3070 <last_result+12>, errstring=0xf7fb3074 <last_result+16>, mallocedp=0xf7fb306c <last_result+8>, operate=0xf7fafc30 <dlopen_doit>, args=0xffffce90) at dl-error.c:187 #8 0xf7fb037c in _dlerror_run (operate=operate#entry=0xf7fafc30 <dlopen_doit>, args=args#entry=0xffffce90) at dlerror.c:163 #9 0xf7fafd71 in __dlopen (file=0x8048590 "./foo.so", mode=1) at dlopen.c:87 #10 0x080484ea in main () at main.c:4 So why isn't open_verifys call to open redirected to your open interposer? First, let's look at the actual call instruction in frame 1: (gdb) fr 1 #1 0xf7fe1211 in open_verify (name=0x804b008 "./foo.so", fbp=fbp#entry=0xffffc93c, loader=0xf7ffd938, whatcode=whatcode#entry=0, found_other_class=found_other_class#entry=0xffffc933, free_name=free_name#entry=true) at dl-load.c:1930 1930 dl-load.c: No such file or directory. (gdb) x/i $pc-5 0xf7fe120c <open_verify+60>: call 0xf7ff3760 <open> Compare this to the call instruction in frame 10: (gdb) fr 10 #10 0x080484ea in main () at main.c:4 4 void *h = dlopen("./foo.so", RTLD_LAZY); (gdb) x/i $pc-5 0x80484e5 <main+24>: call 0x80483c0 <dlopen#plt> Notice anything different? That's right: the call from main goes through the procedure linkage table (PLT), which the dynamic loader (ld-linux.so.2) resolves to appropriate definition. But the call to open in frame 1 does not go through PLT (and thus is not interposable). Why is that? Because that call must work before there is any other definition of open available -- it is used while the libc.so.6 (which normally supplies the definition of open) is itself being loaded (by the dynamic loader). For this reason, the dynamic loader must be entirely self-contained (in fact in contains a statically linked in copy of a subset of libc). My objective is to hook the open function that dlopen on linux uses. For the reason above, this objective can't be achieved via LD_PRELOAD. You'll need to use some other hooking mechanism, such as patching the loader executable code at runtime.
Segmentation fault inside SDL_CreateRenderer
I'm trying to make skeleton SDL2 application on Xubuntu 14.04 (every packages are up to date). Here is the my init function source code: int map_x = 50; int map_y = 20; //The window we'll be rendering to SDL_Window *gWindow = NULL; //The window renderer SDL_Renderer* gRenderer = NULL; void init() { if (SDL_Init(SDL_INIT_VIDEO) < 0) eprintf("SDL could not initialize: %s\n", SDL_GetError()); gWindow = SDL_CreateWindow( "SDL Tutorial",\ SDL_WINDOWPOS_UNDEFINED,\ SDL_WINDOWPOS_UNDEFINED,\ map_x, map_y,\ SDL_WINDOW_SHOWN); if (gWindow == NULL) eprintf( "window could not be created: %s\n", SDL_GetError()); gRenderer = SDL_CreateRenderer( gWindow, -1,\ SDL_RENDERER_ACCELERATED); if (gRenderer == NULL) eprintf("renderer could not be created: %s\n", SDL_GetError()); //Initialize renderer color SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); } But it seg faults inside SDL_CreateRenderer function. Here is gdb output: (gdb) run Starting program: /home/ghi/Desktop/tron/client [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x0000000000005885 in ?? () (gdb) up #1 0x00007ffff67dce02 in XCloseIM () from /usr/lib/x86_64-linux-gnu/libX11.so.6 (gdb) #2 0x00007ffff7b8d4fb in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #3 0x00007ffff7b81cce in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #4 0x00007ffff7aed785 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #5 0x00007ffff7aed8c8 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #6 0x0000000000400cc5 in close () at client.c:56 56 SDL_Quit(); (gdb) #7 0x00007ffff464d723 in ?? () from /lib/x86_64-linux-gnu/libdbus-1.so.3 (gdb) #8 0x00007ffff4645a46 in ?? () from /lib/x86_64-linux-gnu/libdbus-1.so.3 (gdb) #9 0x00007ffff4644ea7 in ?? () from /lib/x86_64-linux-gnu/libdbus-1.so.3 (gdb) #10 0x00007ffff4630e72 in ?? () from /lib/x86_64-linux-gnu/libdbus-1.so.3 (gdb) #11 0x00007ffff7b8d534 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #12 0x00007ffff7b81cce in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #13 0x00007ffff7aed785 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #14 0x00007ffff7aed8c8 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #15 0x0000000000400cc5 in close () at client.c:56 56 SDL_Quit(); (gdb) #16 0x00007ffff217ab35 in ?? () from /usr/lib/nvidia-331/libGL.so.1 (gdb) #17 0x00007ffff0bbda41 in ?? () from /usr/lib/nvidia-331/libnvidia-glcore.so.331.113 (gdb) #18 0x00007ffff0ef1814 in ?? () from /usr/lib/nvidia-331/libnvidia-glcore.so.331.113 (gdb) #19 0x00007ffff0efd869 in ?? () from /usr/lib/nvidia-331/libnvidia-glcore.so.331.113 (gdb) #20 0x00007ffff0db2238 in ?? () from /usr/lib/nvidia-331/libnvidia-glcore.so.331.113 (gdb) #21 0x00007ffff0dbd8a7 in ?? () from /usr/lib/nvidia-331/libnvidia-glcore.so.331.113 (gdb) #22 0x00007ffff0ba34b3 in ?? () from /usr/lib/nvidia-331/libnvidia-glcore.so.331.113 (gdb) #23 0x00007ffff0b8665c in ?? () from /usr/lib/nvidia-331/libnvidia-glcore.so.331.113 (gdb) #24 0x00007ffff2122b30 in ?? () from /usr/lib/nvidia-331/libGL.so.1 (gdb) #25 0x00007ffff2122cdc in ?? () from /usr/lib/nvidia-331/libGL.so.1 (gdb) #26 0x00007ffff2153f59 in ?? () from /usr/lib/nvidia-331/libGL.so.1 (gdb) #27 0x00007ffff7b8c0ad in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #28 0x00007ffff7b80be6 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #29 0x00007ffff7b80e95 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #30 0x00007ffff7b2ea44 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #31 0x00007ffff7b284c0 in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (gdb) #32 0x0000000000400c38 in init () at client.c:38 38 gRenderer = SDL_CreateRenderer( gWindow, -1,\ (gdb) #33 0x0000000000400cef in main (argc=1, argv=0x7fffffffdf48) at client.c:61 61 init(); And Makefile: client : client.o gcc client.o -Wall -lm -o client `sdl2-config --cflags --libs` client.o : client.c gcc -ggdb3 -lm -Wall -c client.c `sdl2-config --cflags --libs` I'm using libsdl2-dev from official repositories. Do anyone know what is wrong here? Entire source can be found here: https://github.com/hafron/tron/blob/master/client.c
(posted previously as a comment, turned out to be an answer; some typos fixed) I know nothing about SDL using, but the stack dump shows your close() function was called from inside the nvidia library. I suspect you superseded some other close identifier with your function. Try making your close strictly local by prepending a static keyword to the declaration: static void close() {...} or renaming the function to some my_close() or whatever...
dlopen malloc deadlock
We have some unit tests that often deadlock. Closer inspection with GDB reveals the following: Thread 1: (gdb) bt #0 0x00110424 in __kernel_vsyscall () #1 0x00c681a3 in __lll_lock_wait_private () from /lib/libc.so.6 #2 0x00bf09fb in _L_lock_515 () from /lib/libc.so.6 #3 0x00bf068c in tr_mallochook () from /lib/libc.so.6 #4 0x00bece22 in calloc () from /lib/libc.so.6 #5 0x00b5ed93 in _dl_new_object () from /lib/ld-linux.so.2 #6 0x00b5b287 in _dl_map_object_from_fd () from /lib/ld-linux.so.2 #7 0x00b5c521 in _dl_map_object () from /lib/ld-linux.so.2 #8 0x00b66f43 in dl_open_worker () from /lib/ld-linux.so.2 #9 0x00b629a6 in _dl_catch_error () from /lib/ld-linux.so.2 #10 0x00b66a06 in _dl_open () from /lib/ld-linux.so.2 #11 0x00d38c3b in dlopen_doit () from /lib/libdl.so.2 #12 0x00b629a6 in _dl_catch_error () from /lib/ld-linux.so.2 #13 0x00d3903c in _dlerror_run () from /lib/libdl.so.2 #14 0x00d38b71 in dlopen##GLIBC_2.1 () from /lib/libdl.so.2 ... Thread 2: #0 0x00110424 in __kernel_vsyscall () #1 0x00d4c059 in __lll_lock_wait () from /lib/libpthread.so.0 #2 0x00d4740e in _L_lock_752 () from /lib/libpthread.so.0 #3 0x00d4731a in pthread_mutex_lock () from /lib/libpthread.so.0 #4 0x00c95dd2 in _dl_addr () from /lib/libc.so.6 #5 0x00bf0425 in tr_where () from /lib/libc.so.6 #6 0x00bf06bd in tr_mallochook () from /lib/libc.so.6 #7 0x00bed01b in malloc () from /lib/libc.so.6 .... I did a lot of searches on the Internet but I can't really find out whether I am doing something wrong, or whether I have found a bug in the libraries.
glibc's dlopen() code doesn't seem to be thread safe. It looks like your code calls malloc() and dlopen() concurrently from two threads. It also looks like malloc() call hits an unresolved dynamic symbol and tries to resolve it using _dl_addr(), which implies that the binary you are executing was linked with lazy binding (default ld behaviour) and this is why the runtime linker resolves symbols on demand on the first call. Try linking it with -Wl,-z,now gcc linker option to cause the runtime linker resolve all symbols prior to starting your application. This bug looks similar to the one I filed a bug report against.