this silly little test program demonstrates a bug in GNU gdb 4.17.0.11 with Linux support as shipped with Red Hat Linux 6.0. when a dynamically loaded shared object is unloaded, gdb doesn't adjust its idea of the state of the process accordingly. run this program within gdb. place a breakpoint in main and run it. type "i sharedlibrary" and examine the list of libraries. now put a break on the call to dlclose(). notice how libtgdb.so is in the list. step over the call to dlclose (). notice how libtgdb.so is _still_ in the list. the real trouble creeps in when you then load up another shared object. any future objects loaded do not show up in gdb's list at all, and in fact none of their symbols are available within the debugger, making debugging impossible. as a developer of component based software, i consider this to be a critical bug in gdb. see enclosed test case. #!/bin/sh # This is a shell archive (produced by GNU sharutils 4.2). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 1999-09-14 11:52 EDT by <greg>. # Source directory was `/home/greg/testgdb'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This shar contains: # length mode name # ------ ---------- ---------------------------------------- -- # 321 -rw-r--r-- Makefile # 1378 -rw-r--r-- testgdb.c # 62 -rw-r--r-- testmod.c # save_IFS="${IFS}" IFS="${IFS}:" gettext_dir=FAILED locale_dir=FAILED first_param="$1" for dir in $PATH do if test "$gettext_dir" = FAILED && test -f $dir/gettext \ && ($dir/gettext --version >/dev/null 2>&1) then set `$dir/gettext --version 2>&1` if test "$3" = GNU then gettext_dir=$dir fi fi if test "$locale_dir" = FAILED && test -f $dir/shar \ && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) then locale_dir=`$dir/shar --print-text-domain-dir` fi done IFS="$save_IFS" if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED then echo=echo else TEXTDOMAINDIR=$locale_dir export TEXTDOMAINDIR TEXTDOMAIN=sharutils export TEXTDOMAIN echo="$gettext_dir/gettext -s" fi touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo $echo 'WARNING: not restoring timestamps. Consider getting and' $echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if mkdir _sh09913; then $echo 'x -' 'creating lock directory' else $echo 'failed to create lock directory' exit 1 fi # ============= Makefile ============== if test -f 'Makefile' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'Makefile' '(file already exists)' else $echo 'x -' extracting 'Makefile' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && # Makefile for gdb shared library bug X CFLAGS = -Wall -fpic -ggdb X X.PHONY : all clean X all : libtgdb.so libtgdb2.so testgdb X clean : X rm testmod.o testgdb.o libtgdb.so libtgdb2.so testgdb X libtgdb.so : testmod.o X gcc $^ -shared -o $@ X libtgdb2.so : testmod.o X gcc $^ -shared -o $@ X testgdb : testgdb.o X gcc $^ -o $@ -ldl SHAR_EOF $shar_touch -am 0914114499 'Makefile' && chmod 0644 'Makefile' || $echo 'restore of' 'Makefile' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'Makefile:' 'MD5 check failed' 16070d1996cc8327f66fc86b14edcc12 Makefile SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`" test 321 -eq "$shar_count" || $echo 'Makefile:' 'original size' '321,' 'current size' "$shar_count!" fi fi # ============= testgdb.c ============== if test -f 'testgdb.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'testgdb.c' '(file already exists)' else $echo 'x -' extracting 'testgdb.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'testgdb.c' && /* X * testgdb.c X * X * this silly little test program demonstrates a bug in GNU gdb 4.17.0.11 X * with Linux support as shipped with Red Hat Linux 6.0. when a dynamically X * loaded shared object is unloaded, gdb doesn't adjust its idea of the state X * of the process accordingly. run this program within gdb. place a X * breakpoint in main and run it. type "i sharedlibrary" and examine the list X * of libraries. now put a break on the call to dlclose (). notice how X * libtgdb.so is in the list. step over the call to dlclose(). notice how X * libtgdb.so is _still_ in the list. the real trouble creeps in when you X * then load up another shared object. any future objects loaded do not X * show up in gdb's list at all, and in fact none of their symbols are X * available within the debugger, making debugging impossible. as a developer X * of component based software, i consider this to be a critical bug in gdb. X */ X #include <stdio.h> #include <dlfcn.h> X int main( X int argc, X char *argv[] X ) { X void *module; X X if ((module = dlopen("./libtgdb.so", RTLD_LAZY | RTLD_GLOBAL)) != NULL) { X X dlclose(module); X X if ((module = dlopen("./libtgdb2.so", X RTLD_LAZY | RTLD_GLOBAL)) != NULL) { X X dlclose(module); X X } else { X X fprintf(stderr, "%s\n", dlerror()); X X } X X } else { X X fprintf(stderr, "%s\n", dlerror()); X X } X X return 0; } SHAR_EOF $shar_touch -am 0914114799 'testgdb.c' && chmod 0644 'testgdb.c' || $echo 'restore of' 'testgdb.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'testgdb.c:' 'MD5 check failed' e15933f5cf6b82847e0121f87b31a9c0 testgdb.c SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'testgdb.c'`" test 1378 -eq "$shar_count" || $echo 'testgdb.c:' 'original size' '1378,' 'current size' "$shar_count!" fi fi # ============= testmod.c ============== if test -f 'testmod.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'testmod.c' '(file already exists)' else $echo 'x -' extracting 'testmod.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'testmod.c' && int spam = 5; X void doNothing( X void X ) { X return; } SHAR_EOF $shar_touch -am 0914113599 'testmod.c' && chmod 0644 'testmod.c' || $echo 'restore of' 'testmod.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'testmod.c:' 'MD5 check failed' 37c6cb0a8cf8533916bea542e3ee6eb6 testmod.c SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'testmod.c'`" test 62 -eq "$shar_count" || $echo 'testmod.c:' 'original size' '62,' 'current size' "$shar_count!" fi fi rm -fr _sh09913 exit 0
I may find time to look into this; it is a long-standing GDB limitation for what it is worth.
This would take a major bit of work to fix in gdb; it's extremely unlikely it's worth the trouble.
I think its time to revisit this issue. It is not possible to use gdb to debug an Oracle PRO*C applications. It seems the Oracle9 client is making calls to dlclose and that is causing gdb to fail with the error message: "Error while reading shared library symbols" before main is called. If you have Oracle9 on Linux just build the sample1.pc program and attempt to debug it with gdb.