Bug 13987 - jit debug interface fails attaching to pie executables
Summary: jit debug interface fails attaching to pie executables
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: unknown
: P2 normal
Target Milestone: 7.6
Assignee: Tom Tromey
URL:
Keywords:
: 14585 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-04-17 13:32 UTC by Richard Henderson
Modified: 2013-01-31 19:54 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Henderson 2012-04-17 13:32:01 UTC
It appears that when we *attach* to a pie executable, the jit load happens
before the symbols are relocated to the actual pie base address.

Test case is mainline qemu.  Run x86_64-softmmu/qemu-system-x86_64 without
arguments (a window will open booting the bios).  Three scenarios:

(1) Attach gdb to running process:

Attaching to process 28585
jit_inferior_init
Reading symbols from /home/rth/work/qemu/bld/x86_64-softmmu/qemu-system-x86_64...done.
jit_inferior_init
jit_inferior_init, descriptor_addr = 0x637580
Unable to read JIT descriptor from remote memory!
(gdb) bt
#0  0x00007ff8df1c3403 in ?? ()
#1  0x0000000000000000 in ?? ()


(2) Running qemu directly under gdb:

GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16)
...
jit_inferior_init
Reading symbols from /home/rth/work/qemu/bld/x86_64-softmmu/qemu-system-x86_64...done.
jit_inferior_init
jit_inferior_init, descriptor_addr = 0x637580
jit_breakpoint_re_set_internal, breakpoint_addr = 0x237290
(gdb) run
Starting program: /home/rth/work/qemu/bld/x86_64-softmmu/qemu-system-x86_64 
jit_inferior_init
jit_inferior_init
jit_inferior_init, descriptor_addr = 0x555555b8b580
jit_breakpoint_re_set_internal, breakpoint_addr = 0x55555578b290
jit_inferior_init, descriptor_addr = 0x555555b8b580
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
jit_register_code, symfile_addr = 0x555556439f70, symfile_size = 848
[New Thread 0x7fffef088700 (LWP 28666)]
[New Thread 0x7fffe6585700 (LWP 28667)]

Program received signal SIG38, Real-time event 38.
[Switching to Thread 0x7fffef088700 (LWP 28666)]
tlb_set_page (env=0x5555564415b0, vaddr=946176, paddr=946176, prot=7, mmu_idx=0, size=<optimized out>) at /home/rth/work/qemu/qemu/exec.c:2223
2223	    if (is_ram_rom(section)) {
Missing separate debuginfos, use: debuginfo-install celt051-0.5.1.3-3.fc15.x86_64 libgcc-4.6.3-2.fc16.x86_64 spice-server-0.10.1-1.fc16.x86_64
(gdb) bt
#0  tlb_set_page (env=0x5555564415b0, vaddr=946176, paddr=946176, prot=7, mmu_idx=0, size=<optimized out>)
    at /home/rth/work/qemu/qemu/exec.c:2223
#1  0x0000555555730264 in cpu_x86_handle_mmu_fault (env=0x5555564415b0, addr=<optimized out>, is_write1=1, mmu_idx=0)
    at /home/rth/work/qemu/qemu/target-i386/helper.c:762
#2  0x0000555555762ebc in tlb_fill (env1=<optimized out>, addr=<optimized out>, is_write=<optimized out>, mmu_idx=<optimized out>, retaddr=
    1073754945) at /home/rth/work/qemu/qemu/target-i386/op_helper.c:5015
#3  0x0000555555768b5c in __stb_mmu (addr=949231, val=137 '\211', mmu_idx=0) at /home/rth/work/qemu/qemu/softmmu_template.h:305
#4  0x0000000040003342 in code_gen_buffer ()
#5  0x000055555570dce1 in cpu_x86_exec (env=0x5555564415b0) at /home/rth/work/qemu/qemu/cpu-exec.c:565
#6  0x00005555557123ab in tcg_cpu_exec (env=0x5555564415b0) at /home/rth/work/qemu/qemu/cpus.c:1097
#7  tcg_exec_all () at /home/rth/work/qemu/qemu/cpus.c:1129
#8  qemu_tcg_cpu_thread_fn (arg=<optimized out>) at /home/rth/work/qemu/qemu/cpus.c:833
#9  0x00007ffff60bad90 in start_thread (arg=0x7fffef088700) at pthread_create.c:309
#10 0x00007ffff5119f5d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115


(3) Rebuild qemu with --disable-pie and attach to running process:


Attaching to process 28679
Reading symbols from /home/rth/work/qemu/bld/x86_64-softmmu/qemu-system-x86_64...done.
...
Loaded symbols for /usr/lib64/libXfixes.so.3
jit_inferior_init
jit_inferior_init
jit_inferior_init, descriptor_addr = 0x9e5580
jit_breakpoint_re_set_internal, breakpoint_addr = 0x5e50b0
jit_inferior_init, descriptor_addr = 0x9e5580
0x0000003ef82ea403 in select () at ../sysdeps/unix/syscall-template.S:82
82	T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) bt 
#0  0x0000003ef82ea403 in select () at ../sysdeps/unix/syscall-template.S:82
#1  0x0000000000548ee1 in os_host_main_loop_wait (timeout=1000) at /home/rth/work/qemu/qemu/main-loop.c:304
#2  0x000000000054903b in main_loop_wait (nonblocking=0) at /home/rth/work/qemu/qemu/main-loop.c:486
#3  0x000000000053bfdb in main_loop () at /home/rth/work/qemu/qemu/vl.c:1555
#4  0x0000000000542b10 in main (argc=1, argv=0x7fff2a711448, envp=0x7fff2a711458) at /home/rth/work/qemu/qemu/vl.c:3643


Note that in case (2) we re-init the jit inferior again after the program
starts at its actual address, whereas in case (1) we use the unrelocated
symbol address, which then (apparently) causes the rest of symbol resolution
to fail as well.
Comment 1 Richard Henderson 2012-04-18 19:16:41 UTC
Some poking about suggests that it's too aggressive caching inside jit.c.
The test


jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
                                struct jit_inferior_data *inf_data)
{
  struct minimal_symbol *reg_symbol, *desc_symbol;
  struct objfile *objf;
  struct jit_objfile_data *objf_data;

  if (inf_data->objfile != NULL)
    return 0;


triggers and fails to re-examine the symbol after svr4_relocate_main_executable.
Comment 2 Tom Tromey 2012-09-17 18:37:46 UTC
*** Bug 14585 has been marked as a duplicate of this bug. ***
Comment 3 Tom Tromey 2012-09-17 18:40:57 UTC
Testing a patch.
Comment 4 Paul Pluzhnikov 2012-10-13 03:21:57 UTC
Just hit this while debugging native process from the start:

cat t.c
void __jit_debug_register_code() { }
int __jit_debug_descriptor[] = { 1, 0, 0, 0, };
int main() { return 0; }

gcc -g -fPIE -pie t.c

gdb
GNU gdb (GDB) 7.5.50.20121013-cvs
...
(gdb) set debug jit 1
(gdb) file ./a.out
Reading symbols from /tmp/a.out...done.
jit_inferior_init
jit_read_descriptor, descriptor_addr = 0x201020
jit_breakpoint_re_set_internal, breakpoint_addr = 0x72c
(gdb) run
Starting program: /tmp/a.out 
Warning:
Cannot insert breakpoint -1.
Error accessing memory address 0x72c: Input/output error.
Comment 5 Paul Pluzhnikov 2012-10-13 03:52:44 UTC
Confirmed that this patch:
  http://sourceware.org/ml/gdb-patches/2012-09/msg00320.html
fixes the problem for me, and does not re-introduce the JIT
slowness that caching was solving.

Tom, any chance you can commit the patch?
Comment 6 Sergio Durigan Junior 2012-10-13 04:35:00 UTC
(In reply to comment #5)
> Confirmed that this patch:
>   http://sourceware.org/ml/gdb-patches/2012-09/msg00320.html
> fixes the problem for me, and does not re-introduce the JIT
> slowness that caching was solving.
> 
> Tom, any chance you can commit the patch?

Thanks for testing and confirming it.  I have also confirmed that the patch fixes the issue.

Tom is absent for some days due to personal reasons, but I believe when he gets back the patch will be pushed upstream.  There is also the possibility of asking some maintainer to approve the patch and commit it.
Comment 7 cvs-commit@gcc.gnu.org 2013-01-31 19:52:08 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	tromey@sourceware.org	2013-01-31 19:52:03

Modified files:
	gdb            : ChangeLog jit.c 
	gdb/testsuite  : ChangeLog 
	gdb/testsuite/gdb.base: jit.exp 

Log message:
	PR gdb/13987:
	* jit.c (struct jit_inferior_data) <cached_code_address,
	jit_breakpoint>: New fields.
	(jit_breakpoint_re_set_internal): Fix logging.  Only create
	breakpoint if cached address has changed.
	(jit_update_inferior_cache, jit_breakpoint_deleted): New
	functions.
	(_initialize_jit): Register breakpoint deleted observer.
	gdb/testsuite
	* gdb.base/jit.exp (compile_jit_test): New proc.
	Add PIE tests.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.15092&r2=1.15093
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/jit.c.diff?cvsroot=src&r1=1.46&r2=1.47
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.3539&r2=1.3540
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/jit.exp.diff?cvsroot=src&r1=1.10&r2=1.11
Comment 8 Tom Tromey 2013-01-31 19:54:26 UTC
Fix finally in.