This is the mail archive of the gdb-prs@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]

[Bug gdb/20969] New: breakpoint sometimes skipped on alpha


https://sourceware.org/bugzilla/show_bug.cgi?id=20969

            Bug ID: 20969
           Summary: breakpoint sometimes skipped on alpha
           Product: gdb
           Version: 7.12
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: rin at NetBSD dot org
  Target Milestone: ---

Created attachment 9699
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9699&action=edit
patch: add alpha_skip_entrypoint

For GDB on alpha, breakpoints sometimes do not work correctly:

  % uname -mrs
  NetBSD 7.99.43 alpha
  % gdb pwd
  GNU gdb (GDB) 7.12
  ...
  Reading symbols from pwd...Reading symbols from /tmp/pwd/pwd.debug...done.
  done.
  (gdb) b main
  Breakpoint 1 at 0x120000fa0: file pwd.c, line 71.
  (gdb) r
  Starting program: /tmp/pwd/pwd
  /tmp/pwd
  [Inferior 1 (process 8649) exited normally]
  (gdb)

This is because ___start skips first 8 bytes in main, and therefore a
breakpoint at the entrypoint of main (0x120000fa0):

  (gdb) disas ___start
  Dump of assembler code for function ___start:
  ...
     0x0000000120000c34 <+404>:   bsr     ra,0x120000fa8 <main+8>
  ...
  (gdb) disas main
  Dump of assembler code for function main:
     0x0000000120000fa0 <+0>:     ldah    gp,2(t12)
     0x0000000120000fa4 <+4>:     lda     gp,-31296(gp)
     0x0000000120000fa8 <+8>:     lda     sp,-48(sp)
     0x0000000120000fac <+12>:    stq     ra,0(sp)
     0x0000000120000fb0 <+16>:    stq     s0,8(sp)
  ...

Usually GDB skips the function prologue when it inserts a breakpoint,
but it does not skip when a target has been compiled by GCC with both
optimization and debugging information:

 
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=6e22494e5076e4d3c0b2c2785883162f83db499e

Instead, GDB call gdbarch_skip_entrypoint() in this case, which is not
defined for alpha:

 
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=141c5cc4c44a6ce1a5c628c0f4849a8b1c91d383

gdb/symtab.c from gdb-head:

  3488 struct symtab_and_line
  3489 find_function_start_sal (struct symbol *sym, int funfirstline)
  3490 {
  ... 
  3498   if (funfirstline && sal.symtab != NULL
  3499       && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
  3500           || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
  3501     {
  3502       struct gdbarch *gdbarch = symbol_arch (sym);
  3503 
  3504       sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
  3505       if (gdbarch_skip_entrypoint_p (gdbarch))
  3506         sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
  3507       return sal;
  3508     }
  ...
  3522   if (funfirstline)
  3523     skip_prologue_sal (&sal);
  3524 
  3525   return sal;
  3526 }

 
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/symtab.c;h=430bc8d26c472ab4942a4f67f4ae18e830d9cf25;hb=02aa377fbdd17b763b1e32ad72ccfd1c617ce463#l3488

The problem is who skips the first 8 bytes of main, out of control of
GCC. The answer is ld(1). It so clever that the redundant GP load in
function entrypoint is skipped:

bfd/elf64-alpha.c from binutils-head:

  3178 static bfd_vma
  3179 elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma
symval)
  3180 {
  3181   /* If the function has the same gp, and we can identify that the
  3182      function does not use its function pointer, we can eliminate the
  3183      address load.  */
  ...
  3239   /* We've now determined that we can skip an initial gp load.  Verify
  3240      that the call and the target use the same gp.   */
  3241   if (info->link_info->output_bfd->xvec != info->tsec->owner->xvec
  3242       || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
  3243     return 0;
  3244 
  3245   return symval + 8;
  3246 }

 
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=bfd/elf64-alpha.c;h=44f2cfe0048fb4d4651bcb7e96cdbb7c273e7da6;hb=02aa377fbdd17b763b1e32ad72ccfd1c617ce463#l3178

We do not know for which function ld(1) determined the initial GP load
can be skipped. Therefore GDB should also skips initial GP loads for
every functions by using gdbarch_skip_entrypoint(), IMO.

With the attached patch, breakpoints work well:

  % gdb.patched pwd
  GNU gdb (GDB) 7.12
  ...
  Reading symbols from pwd...Reading symbols from
/var/shm/pwd/pwd.debug...done.
  done.
  (gdb) b main
  Breakpoint 1 at 0x120000fa8: file pwd.c, line 71.
  (gdb) r
  Starting program: /var/shm/pwd/pwd
    Breakpoint 1, 0x0000000120000fa8 in main (argc=1, argv=0x1ffffd470) at
pwd.c:71
  71      {
  (gdb)

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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