This is the mail archive of the
gdb-prs@sourceware.org
mailing list for the GDB project.
[Bug gdb/20969] New: breakpoint sometimes skipped on alpha
- From: "rin at NetBSD dot org" <sourceware-bugzilla at sourceware dot org>
- To: gdb-prs at sourceware dot org
- Date: Thu, 15 Dec 2016 09:46:35 +0000
- Subject: [Bug gdb/20969] New: breakpoint sometimes skipped on alpha
- Auto-submitted: auto-generated
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.