This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Re: DWARF question
Carlos Eduardo Seo <cseo@linux.vnet.ibm.com> writes:
> Carlos Eduardo Seo wrote:
>> It's generating one compilation unit for the "main" program and another
>> one for a function called by that program. Both are implemented in the
>> same source file.
>>
>>
> And the source is in Fortran. This another problem that happens in the
> situation I described in this thread:
> http://sourceware.org/ml/gdb/2007-09/msg00134.html
> aside from that finding "main" problem.
>
>
> The problem is that, when I try to set a breakpoint by line number in
> this case, two things may happen:
>
> 1. if I set the breakpoint somewhere inside "main", it works.
> 2. if I set the breakpoint somewhere inside the function, it doesn't
> work (i.e. 'No line xx in file "foo.f".').
>
> In other words, it seems that GDB doesn't have the line number
> information for that function.
>
> In order to fix this, I can think about two approaches:
>
> - Make GDB read the two existing symtabs for that source file when the
> binary is loaded; or
> - When a breakpoint by line number is called, GDB tries to look for that
> line in the other symtabs corresponding to the current objfile.
>
> What do you think?
I've reproduced this in C:
$ cat 1s2c.c
#include <stdio.h>
extern void foo (void);
#ifdef FIRST
int
main (int argc, char **argv)
{
puts ("main");
foo ();
puts ("main again");
return 0;
}
#else
void
foo (void)
{
puts ("foo");
}
#endif
$ cat 1s2c.mk
CFLAGS = -g
CC = gcc
all: 1s2c
1s2c: 1s2c1.o 1s2c2.o
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
1s2c1.o: 1s2c.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
1s2c1.o: CFLAGS += -DFIRST
1s2c2.o: 1s2c.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
clean:
rm -f 1s2c 1s2c[12].o
$ make -f 1s2c.mk clean all
rm -f 1s2c 1s2c[12].o
gcc -g -DFIRST -c 1s2c.c -o 1s2c1.o
gcc -g -c 1s2c.c -o 1s2c2.o
gcc -g 1s2c1.o 1s2c2.o -o 1s2c
$ ~/gdb/exp/nat/gdb/gdb 1s2c
GNU gdb 6.7.50-20070926-cvs
Copyright (C) 2007 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 "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) break 20
No line 20 in file "1s2c.c".
(gdb) break 10
Breakpoint 1 at 0x80483a1: file 1s2c.c, line 10.
(gdb)
However, the problem isn't that GDB isn't reading the symtabs; given
some source file name S, GDB always reads full symbols for all
psymtabs whose names match S. We can verify this:
(gdb) maint info psymtabs
{ objfile /home/jimb/play/1s2c ((struct objfile *) 0x98d2de0)
{ psymtab 1s2c.c ((struct partial_symtab *) 0x98da7c4)
readin yes
fullname (null)
text addresses 0x0 -- 0x0
globals (none)
statics (none)
dependencies {
psymtab 1s2c.c ((struct partial_symtab *) 0x98da774)
}
}
{ psymtab 1s2c.c ((struct partial_symtab *) 0x98da774)
readin yes
fullname (null)
text addresses 0x80483c0 -- 0x80483d4
globals (* (struct partial_symbol **) 0x98d8e94 @ 1)
statics (* (struct partial_symbol **) 0x98d9060 @ 12)
dependencies (none)
}
{ psymtab 1s2c.c ((struct partial_symtab *) 0x98da720)
readin yes
fullname (null)
text addresses 0x0 -- 0x0
globals (none)
statics (none)
dependencies {
psymtab 1s2c.c ((struct partial_symtab *) 0x98da628)
}
}
{ psymtab 1s2c.c ((struct partial_symtab *) 0x98da628)
readin yes
fullname (null)
text addresses 0x8048384 -- 0x80483c0
globals (* (struct partial_symbol **) 0x98d8e90 @ 1)
statics (* (struct partial_symbol **) 0x98d9030 @ 12)
dependencies (none)
}
}
(gdb) maint info symtabs
{ objfile /home/jimb/play/1s2c ((struct objfile *) 0x98d2de0)
{ symtab 1s2c.c ((struct symtab *) 0x98e43fc)
dirname /home/jimb/play
fullname (null)
blockvector ((struct blockvector *) 0x98e43ec) (primary)
debugformat DWARF 2
}
{ symtab 1s2c.c ((struct symtab *) 0x98db290)
dirname /home/jimb/play
fullname (null)
blockvector ((struct blockvector *) 0x98db280) (primary)
debugformat DWARF 2
}
}
(gdb)
There are no less than four partial symbol tables by the name of
1s2c.c --- for each CU, that's probably one for the .debug_info
compilation unit, and then one from the .debug_line info. This is the
natural state of affairs.
When the user types 'break 20', GDB reads full symbols for both of the
CUs.
The real question here is, why isn't find_line_symtab doing its job?
Its comment says:
/* Find line number LINE in any symtab whose name is the same as
SYMTAB.
If found, return the symtab that contains the linetable in which it was
found, set *INDEX to the index in the linetable of the best entry
found, and set *EXACT_MATCH nonzero if the value returned is an
exact match.
If not found, return NULL. */
That sounds to me like it's meant to address exactly the case we have
here. Could you take a look and tell us what you find?