This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]