This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
debugging
- From: Jack Howarth <howarth at bromo dot msbb dot uc dot edu>
- To: jakub at redhat dot com
- Cc: libc-alpha at sources dot redhat dot com
- Date: Wed, 25 Sep 2002 23:01:50 -0400 (EDT)
- Subject: debugging
Jakub,
Using the following suggestion from Roland I attempted to debug this
crash in evolution....
Set a breakpoint before that loop in dl-addr.c, and look at symtab, strtab,
and strtabsize. You should be able to tell from readelf -d on the module
you're loading what the reasonable values for those will be, or at least
tell if they don't make sense with each other. e.g., if strtab does not
follow symtab the loop will run off into random memory and crash instead of
terminating. If they are reasonable, then step through the loop until you
see where it goes wrong. Look at all the variables involved in that
statement and at the values they point to.
What I found was the the crash is occurring in dl-addr.c in this area...
symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]);
strtab = (const void *) D_PTR (match, l_info[DT_STRTAB]);
strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
/* We assume that the string table follows the symbol table, because
there is no way in ELF to know the size of the dynamic symbol table!! */
for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
if (addr >= match->l_addr + symtab->st_value
&& ((symtab->st_size == 0 && addr == match->l_addr + symtab->st_value)
|| addr < match->l_addr + symtab->st_value + symtab->st_size)
&& symtab->st_name < strtabsize
&& (matchsym == NULL || matchsym->st_value < symtab->st_value)
&& (ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
|| ELFW(ST_BIND) (symtab->st_info) == STB_WEAK))
matchsym = symtab;
where the top line is number 72 and the bottom line 86. I find that
I can do the following in gdb...
howarth@bogus:~$ gdb evolution
GNU gdb 2002-08-18-cvs
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "powerpc-linux"...(no debugging symbols found)...
(gdb) break main
Breakpoint 1 at 0x10045dbc
(gdb) run
Starting program: /usr/bin/evolution
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...[New Thread 16384 (LWP 10427)]
(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...[Switching to Thread 16384 (LWP 10427)]
Breakpoint 1, 0x10045dbc in main ()
(gdb) break dl-addr.c:78
Breakpoint 2 at 0x1a3fac0: file dl-addr.c, line 78.
(gdb) c
Continuing.
Breakpoint 2, *__GI__dl_addr (address=0xeef4154, info=0x7ffff6e8)
at dl-addr.c:78
78 for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
(gdb) print *symtab
$1 = {st_name = 2135247942, st_value = 16908544, st_size = 0,
st_info = 0 '\0', st_other = 0 '\0', st_shndx = 0}
(gdb) print *strtab
$2 = 0 '\0'
(gdb) print strtabsize
$3 = 805404792
(gdb) c
Continuing.
Breakpoint 2, *__GI__dl_addr (address=0x1006ca38, info=0x7ffff6e8)
at dl-addr.c:78
78 for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
(gdb) print *symtab
$4 = {st_name = 2135247942, st_value = 16908544, st_size = 0,
st_info = 0 '\0', st_other = 0 '\0', st_shndx = 0}
(gdb) print *strtab
$5 = 0 '\0'
(gdb) print strtabsize
$6 = 254241824
(gdb)
I find in the above if I were to continue through to the next
dl-addr.c:78 for a third time that I get the crash..
Program received signal SIGSEGV, Segmentation fault.
0x01a3faf4 in *__GI__dl_addr (address=0x1006ca38, info=0x7ffff6e8)
at dl-addr.c:79
79 if (addr >= match->l_addr + symtab->st_value
so I am assuming the values for *symtab and *strtab are the
last current ones before the crash in the for/if section.
I also find that the number of passes through the for
varies making it impossible to step up to where the crash
will be since it occurs at a different number of for loops
each time. Also I am bit unclear which modules is being
loaded. According to LD_DEBUG=files, /usr/lib/gdk-imlib1/libimlib-png.so
is the last thing opened before the crash. The readelf -d on that file
is....
howarth@bogus:~$ readelf -d /usr/lib/gdk-imlib1/libimlib-png.so
Dynamic segment at offset 0x25ac contains 24 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libpng.so.2]
0x00000001 (NEEDED) Shared library: [libz.so.1]
0x00000001 (NEEDED) Shared library: [libgdk_imlib.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000e (SONAME) Library soname: [libimlib-png.so]
0x0000000c (INIT) 0xee8
0x0000000d (FINI) 0x24cc
0x00000004 (HASH) 0x94
0x00000005 (STRTAB) 0x7c0
0x00000006 (SYMTAB) 0x2e0
0x0000000a (STRSZ) 818 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x126d4
0x00000002 (PLTRELSZ) 468 (bytes)
0x00000014 (PLTREL) RELA
0x00000017 (JMPREL) 0xd14
0x00000007 (RELA) 0xbd0
0x00000008 (RELASZ) 792 (bytes)
0x00000009 (RELAENT) 12 (bytes)
0x6ffffffe (VERNEED) 0xb90
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0xaf2
0x6ffffff9 (RELACOUNT) 20
0x00000000 (NULL) 0x0
Hopefully you can deduce the bug from this if not please suggest
something else I can try in terms of debugging.
Jack