[commit] SIGILL in ld.so when running program from GDB on ia64-linux

Joel Brobecker brobecker@adacore.com
Wed Apr 30 06:25:00 GMT 2008


Hello,

The debugger on ia64-linux (probably all ia64 targets actually) is
unable to run a program:

    (gdb) start
    Temporary breakpoint 1 at 0x4000000000003612: file foo.adb, line 5.
    Starting program: /taff.a/brobecke/regr/ex/foo 
    
    Program received signal SIGILL, Illegal instruction.
    0x200000000001b722 in _dl_debug_state () from /lib/ld-linux-ia64.so.2

And indeed, when you look at the code at this address:

    (gdb) x /3i 0x200000000001b720
    0x200000000001b720 <_dl_debug_state>:   [MII]       nop.m 0x0
    0x200000000001b721 <_dl_debug_state+1>:             nop.i 0x0
    0x200000000001b722 <_dl_debug_state+2>:             data8 0x108001100

It should looks like this:

   (gdb) x /3i 0x200000000001b720
   0x200000000001b720 <_dl_debug_state>:   [MIB]       nop.m 0x0
   0x200000000001b721 <_dl_debug_state+1>:             nop.i 0x0
   0x200000000001b722 <_dl_debug_state+2>:             br.ret.sptk.many b0;;

What happened is that we inserted our shlib breakpoint on the first
slot of our instruction bundle.  Later on, when we tried to step over it,
we proceeded to remove the breakpoint.  To do that, we first tried to
read the entire instruction bundle, so that we could reinsert the
real instruction in that slot. However, in the meantime, the target_read
had already tried to restore the breakpoint using the shadow contents.
The general mechanism for restoring the shadow contents doesn't work
on ia64, because the instruction is not actually located at the breakpoint
address (0x200000000001b720), but 5 bits later! Also, the instruction
length is also not equal to the length of our shadow contents buffer,
which is measured in bytes, not bits.

The fix was to disable the shadow_contents restoration during memory reads.

2008-04-29  Joel Brobecker  <brobecker@adacore.com>

        * ia64-tdep.c (ia64_memory_remove_breakpoint): Set
        show_memory_breakpoints to 1 while reading the instruction bundle.

Tested on ia64-tdep.c. Together with the ia64_convert_from_func_ptr_addr
patch I proposed earlier, this brings the testsuite results back to where
they were with gdb-6.8 (slightly better actually, not sure where, though).

Checked in.

-- 
Joel

PS: This makes me realize that, in the future, we might want to make
    the shadow contents restoration a gdbarch method.  We might have
    some related issues when parsing function prologues where
    a breakpoint has been inserted.  I'm waiting to see the problem
    in reality before moving in that direction...
    
-------------- next part --------------
Index: ia64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-tdep.c,v
retrieving revision 1.174
diff -u -p -r1.174 ia64-tdep.c
--- ia64-tdep.c	22 Apr 2008 11:03:41 -0000	1.174
+++ ia64-tdep.c	29 Apr 2008 21:08:35 -0000
@@ -598,9 +598,15 @@ ia64_memory_remove_breakpoint (struct gd
   long long instr;
   int val;
   int template;
+  struct cleanup *cleanup;
 
   addr &= ~0x0f;
 
+  /* Disable the automatic memory restoration from breakpoints while
+     we read our instruction bundle.  Otherwise, the general restoration
+     mechanism kicks in and ends up corrupting our bundle, because it
+     is not aware of the concept of instruction bundles.  */
+  cleanup = make_show_memory_breakpoints_cleanup (1);
   val = target_read_memory (addr, bundle, BUNDLE_LEN);
 
   /* Check for L type instruction in 2nd slot, if present then
@@ -616,6 +622,7 @@ ia64_memory_remove_breakpoint (struct gd
   if (val == 0)
     target_write_memory (addr, bundle, BUNDLE_LEN);
 
+  do_cleanups (cleanup);
   return val;
 }
 


More information about the Gdb-patches mailing list