Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* Backtraces broken on i386 by unorthodox encoding of push %ebp
@ 2013-03-30 19:13 Richard Smith
  2013-03-30 19:50 ` Jan Kratochvil
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Smith @ 2013-03-30 19:13 UTC (permalink / raw)
  To: gdb


I have an i386 program on Linux where some of the functions 
start with a slightly unorthodox encoding of the usual 
function prologue:

   08048104 <foo>:
    8048104:	ff f5                	push   %ebp
    8048106:	89 e5                	mov    %esp,%ebp

However, when I have this form of prologue, gdb doesn't 
recongnise it, and doesn't give a meaningful backtrace.

In this case, the push instruction is encoded using the 
two-byte PUSH r/m32 (FF /6) form, instead of the more common 
one-byte PUSH r32 (50+rd) form.  The two instructions 
execute identically, and both have been around since the 
8086.  So far as I'm aware, the ABI doesn't require the use 
of the shorter encoding of the instruction in the function 
prologue.  And for this particular application, I would 
prefer to continue using the two-byte form.

I think it should be pretty straightforward to make gdb 
accept both versions of the instruction.  I'm not familiar 
with gdb's source code, but at a guess, modifying the start 
of i386_analyze_frame_setup in gdb/i386-tdep.c so that it 
does something like this:

   /* Check for `pushl %ebp', either encoded using `push r32' (55)
      or less commonly using `push r/m32' (FF F5). */
   if (op == 0x55 || op == 0xff
       && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xf5)
     {
       /* Take into account that we've executed the `pushl %ebp' that
          starts this instruction sequence.  */
       cache->saved_regs[I386_EBP_REGNUM] = 0;
       cache->sp_offset += 4;
       pc += op == 0x55 ? 1 : 2;

I expect the amd64 version of the code could do with a 
similar change.

Richard


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Backtraces broken on i386 by unorthodox encoding of push %ebp
  2013-03-30 19:13 Backtraces broken on i386 by unorthodox encoding of push %ebp Richard Smith
@ 2013-03-30 19:50 ` Jan Kratochvil
  2013-03-30 20:07   ` Joel Brobecker
  2013-03-30 21:03   ` Richard Smith
  0 siblings, 2 replies; 6+ messages in thread
From: Jan Kratochvil @ 2013-03-30 19:50 UTC (permalink / raw)
  To: Richard Smith; +Cc: gdb

On Sat, 30 Mar 2013 20:13:06 +0100, Richard Smith wrote:
>   08048104 <foo>:
>    8048104:	ff f5                	push   %ebp
>    8048106:	89 e5                	mov    %esp,%ebp
> 
> However, when I have this form of prologue, gdb doesn't recongnise
> it, and doesn't give a meaningful backtrace.

You should always provide unwind information and then it is irrelevant which
instructions and/or which their coding you use.

See how GCC does it: -S -fasynchronous-unwind-tables -m32
	.cfi_startproc
	pushl   %ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl    %esp, %ebp
	.cfi_def_cfa_register 5

Then for:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:

readelf -wf will show:
  DW_CFA_advance_loc: 1 to 00000001
  DW_CFA_def_cfa_offset: 8
  DW_CFA_offset: r5 (ebp) at cfa-8
  DW_CFA_advance_loc: 2 to 00000003
  DW_CFA_def_cfa_register: r5 (ebp)

and readelf -wF will show:
   LOC   CFA      ebp   ra      
00000000 esp+4    u     c-4   
00000001 esp+8    c-8   c-4   
00000003 ebp+8    c-8   c-4   

See DWARF .debug_frame documentation.


Jan


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Backtraces broken on i386 by unorthodox encoding of push %ebp
  2013-03-30 19:50 ` Jan Kratochvil
@ 2013-03-30 20:07   ` Joel Brobecker
  2013-03-30 21:03   ` Richard Smith
  1 sibling, 0 replies; 6+ messages in thread
From: Joel Brobecker @ 2013-03-30 20:07 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Richard Smith, gdb

> > However, when I have this form of prologue, gdb doesn't recongnise
> > it, and doesn't give a meaningful backtrace.
> 
> You should always provide unwind information and then it is irrelevant which
> instructions and/or which their coding you use.

Agreed, and that could be the instant fix.

But if he cannot get the unwind information with the binary, it might
indeed be easy enough to improve the prologue analyzer for x86. On
x86_64, on the other hand, we made the conscious design decision to rely
more on unwind info, so it's a little more questionable whether we'd
want to do that for this target.

The thing I wanted to add to Richard is that there is a very high
chance that the only way to get this fixed in GDB is by submitting
a patch himself (to gdb-patches).

-- 
Joel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Backtraces broken on i386 by unorthodox encoding of push %ebp
  2013-03-30 19:50 ` Jan Kratochvil
  2013-03-30 20:07   ` Joel Brobecker
@ 2013-03-30 21:03   ` Richard Smith
  2013-03-30 23:53     ` Mike Frysinger
  2013-03-31  5:48     ` Jan Kratochvil
  1 sibling, 2 replies; 6+ messages in thread
From: Richard Smith @ 2013-03-30 21:03 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb

Jan Kratochvil wrote:

> You should always provide unwind information and then it is irrelevant which
> instructions and/or which their coding you use.

Yes, you're right, I could quite easily.  But a design 
criterion for this project is that it is easy for 
third-parties to produce backtraces from production code 
(i.e. once debugging information has been stripped).

I think on balance, I should just fix the prologue to use 
the one-byte push instruction.  (My reluctance to do that 
was because the in question code is just-in-time compiled 
code produced by a lightweight compiler/assembler that says 
resident in memory.  I'm not keen to change the assembler 
component from the upstream version as the change to fix it 
looks more intrusive than you might imagine.)


Joel Brobecker wrote:

> But if he cannot get the unwind information with the 
> binary, it might indeed be easy enough to improve the 
> prologue analyzer for x86. On x86_64, on the other hand, 
> we made the conscious design decision to rely more on 
> unwind info, so it's a little more questionable whether 
> we'd want to do that for this target.
>
> The thing I wanted to add to Richard is that there is a 
> very high chance that the only way to get this fixed in 
> GDB is by submitting a patch himself (to gdb-patches).

I'll certainly take a look at it to see if it's as 
straightforward as it seems.

However, I expect the same problem will arise on x86_64, and 
I can understand not wanting to complicate unnecessarily its 
prologue analyzer.

Richard


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Backtraces broken on i386 by unorthodox encoding of push %ebp
  2013-03-30 21:03   ` Richard Smith
@ 2013-03-30 23:53     ` Mike Frysinger
  2013-03-31  5:48     ` Jan Kratochvil
  1 sibling, 0 replies; 6+ messages in thread
From: Mike Frysinger @ 2013-03-30 23:53 UTC (permalink / raw)
  To: gdb; +Cc: Richard Smith, Jan Kratochvil

[-- Attachment #1: Type: Text/Plain, Size: 1538 bytes --]

On Saturday 30 March 2013 17:02:55 Richard Smith wrote:
> Jan Kratochvil wrote:
> > You should always provide unwind information and then it is irrelevant
> > which instructions and/or which their coding you use.
> 
> Yes, you're right, I could quite easily.  But a design
> criterion for this project is that it is easy for
> third-parties to produce backtraces from production code
> (i.e. once debugging information has been stripped).

do what all the distros are doing now: split the debug files out into dedicated 
files.  then wherever you run gdb, d/l the debug files first and point gdb at 
them.
	objcopy --only-keep-debug file file.debug
	strip file


> Joel Brobecker wrote:
> > But if he cannot get the unwind information with the
> > binary, it might indeed be easy enough to improve the
> > prologue analyzer for x86. On x86_64, on the other hand,
> > we made the conscious design decision to rely more on
> > unwind info, so it's a little more questionable whether
> > we'd want to do that for this target.
> > 
> > The thing I wanted to add to Richard is that there is a
> > very high chance that the only way to get this fixed in
> > GDB is by submitting a patch himself (to gdb-patches).
> 
> I'll certainly take a look at it to see if it's as
> straightforward as it seems.
> 
> However, I expect the same problem will arise on x86_64, and
> I can understand not wanting to complicate unnecessarily its
> prologue analyzer.

i think all the sniffers live in gdb/i386-tdep.c
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Backtraces broken on i386 by unorthodox encoding of push %ebp
  2013-03-30 21:03   ` Richard Smith
  2013-03-30 23:53     ` Mike Frysinger
@ 2013-03-31  5:48     ` Jan Kratochvil
  1 sibling, 0 replies; 6+ messages in thread
From: Jan Kratochvil @ 2013-03-31  5:48 UTC (permalink / raw)
  To: Richard Smith; +Cc: gdb

On Sat, 30 Mar 2013 22:02:55 +0100, Richard Smith wrote:
> Yes, you're right, I could quite easily.  But a design criterion for
> this project is that it is easy for third-parties to produce
> backtraces from production code (i.e. once debugging information has
> been stripped).

It should be in .eh_frame - which is also used for exceptions unwinding if
an exception is thrown through this frame. .eh_frame is runtime information,
it is in a mapped segment and never stripped.


Jan


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-03-31  5:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-30 19:13 Backtraces broken on i386 by unorthodox encoding of push %ebp Richard Smith
2013-03-30 19:50 ` Jan Kratochvil
2013-03-30 20:07   ` Joel Brobecker
2013-03-30 21:03   ` Richard Smith
2013-03-30 23:53     ` Mike Frysinger
2013-03-31  5:48     ` Jan Kratochvil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox