This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFC] Try to enhanced backtrace on i386 machines.
- From: Pierre Muller <muller at cerbere dot u-strasbg dot fr>
- To: gdb-patches at sources dot redhat dot com
- Date: Mon, 03 Dec 2001 11:28:07 +0100
- Subject: [RFC] Try to enhanced backtrace on i386 machines.
GCC for i386 does several optimization
to allow correct pairing of instructions.
This leads in particular to mix loading of constants into registers
with usual prologue instructions.
The major effect is that the backtrace shows some
'pseudo' trace levels, which are due to a failure to get
the correct prologue.
One of the nastiest effect of this is that
if you use 'return' on that function, it sets a temporary
breakpoint on a wrong location and you program
continues without stopping when frame is left.
I started to implement some code that tries to deal with that issue.
Its far from perfect, but it gives already some result
(when debugging GDB with itself compiled with -O2,
it reduces the number of those false frame levels).
This code might probably be used at several other position.
All comments and suggestions welcome.
2001-12-02 Pierre Muller <muller@ics.u-strasbg.fr>
* i386-tdep.c (i386_skip_optimization_code): New function used to
skip over code inserted by optimizer.
(i386_get_frame_setup): Use i386_skip_optimization_code to
enhance prologue detection.
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.47
diff -u -p -r1.47 i386-tdep.c
--- i386-tdep.c 2001/12/02 18:29:08 1.47
+++ i386-tdep.c 2001/12/03 10:23:00
@@ -314,6 +314,64 @@ i386_follow_jump (void)
codestream_seek (pos);
}
+/* Skip over movl $imm,%exx
+ or xorl %exx,%exx
+ as these instructions are inserted by GCC
+ to optimize code.
+ op must have been read using codestream_get. */
+
+unsigned char
+i386_skip_optimization_code (unsigned char op)
+{
+ CORE_ADDR pos;
+
+ while (1)
+ {
+ switch (op)
+ {
+ case 0xb8:
+ case 0xb9:
+ case 0xba:
+ case 0xbb:
+ case 0xbc:
+ case 0xbd:
+ case 0xbe:
+ case 0xbf:
+ /* 'movl $immediate_long,%exx'. */
+ pos = codestream_tell ();
+ pos += 4;
+ codestream_seek (pos);
+ op = codestream_get();
+ break;
+ case 0x31:
+ case 0x33:
+ /* xorl %exx,%exx. */
+ pos = codestream_tell ();
+ op = codestream_get ();
+ /* don't accept 'xorl %esp,%esp' nor 'xorl %ebp,%ebp'. */
+ if (op == 0xc0 /* xorl %eax,%eax */
+ || op == 0xc9 /* xorl %ebx,%ebx */
+ || op == 0xd2 /* xorl %ecx,%ecx */
+ || op == 0xdb /* xorl %edx,%edx */
+ || op == 0xf6 /* xorl %esi,%esi */
+ || op == 0xff /* xorl %edi,%edi */)
+ {
+ pos += 1;
+ codestream_seek (pos);
+ op = codestream_get();
+ }
+ else
+ {
+ codestream_seek (pos);
+ return op;
+ }
+ break;
+ default:
+ return op;
+ }
+ }
+}
+
/* Find & return the amount a local space allocated, and advance the
codestream to the first register push (if any).
@@ -396,8 +454,11 @@ i386_get_frame_setup (CORE_ADDR pc)
if (op == 0x55) /* pushl %ebp */
{
+ int pos = codestream_tell ();
+ op = codestream_get ();
+ op = i386_skip_optimization_code (op);
/* Check for "movl %esp, %ebp" -- can be written in two ways. */
- switch (codestream_get ())
+ switch (op)
{
case 0x8b:
if (codestream_get () != 0xec)
@@ -435,7 +496,6 @@ i386_get_frame_setup (CORE_ADDR pc)
{
char buf[4];
/* Maybe it is `subl' with a 32 bit immedediate. */
- codestream_get ();
if (codestream_get () != 0xec)
/* Some instruction starting with 0x81 other than `subl'. */
{
@@ -448,7 +508,8 @@ i386_get_frame_setup (CORE_ADDR pc)
}
else
{
- return 0;
+ codestream_seek (pos);
+ return 0;
}
}
else if (op == 0xc8)
Pierre Muller
Institut Charles Sadron
6,rue Boussingault
F 67083 STRASBOURG CEDEX (France)
mailto:muller@ics.u-strasbg.fr
Phone : (33)-3-88-41-40-07 Fax : (33)-3-88-41-40-99