Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@polymtl.ca>
To: Yao Qi <qiyaoltc@gmail.com>
Cc: GDB Patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH 2/2] Fix gdb.mi/mi-stack.exp when gcc generates a stack protector
Date: Tue, 02 Jan 2018 18:14:00 -0000	[thread overview]
Message-ID: <9860ca45c4896a0e42190f4c34c68c4a@polymtl.ca> (raw)
In-Reply-To: <CAH=s-POVUgp0Vbh_g6bchswwL8UfPy2XSZmBB2ONKUb4A1Xe7w@mail.gmail.com>

On 2018-01-02 05:38, Yao Qi wrote:
> On Sat, Dec 16, 2017 at 2:56 PM, Simon Marchi <simon.marchi@polymtl.ca> 
> wrote:
>> I see some failures in the gdb.mi/mi-stack.exp test.  The test runs to
>> the callee4 function:
>> 
>>   int callee4 (void)
>>   {
>>     int A=1;
>>     int B=2;
>>     int C;
>>     int D[3] = {0, 1, 2};
>> 
>>     C = A + B;
>>     return 0;
>>   }
>> 
>> and expects to be stopped at the A=1 line.  However, when gcc 
>> generates
>> some stack protection code, it will stop at the { instead, as shown by
>> this disassembly (after I did "break callee4" and "run"):
> 
> Can't we fix GDB to skip these stack protection code?

I think it would be desirable to consider the stack protection code as 
part of the prologue, since it's compiler-generated and of little 
interest to the user.  But I don't know how to do it without breaking 
existing behavior.

Our heuristic, when using SaL to skip prologue, is to consider the first 
linetable entry to represent the prologue.  If we find a consecutive 
entry with the same line number, we assume it's the prologue -> body 
transition (because otherwise there would be no point in having a 
separate entry).  When adding a stack protector, gcc puts it in a 
separate linetable entry, as if it was user code, so GDB thinks it's the 
beginning of the body.

Let's take this small example:

1  int main()
2  {
3    int n = 0;
4    n++;
5    return n;
6  }

Which compiles to this with -fstack-protector-all:

    0x0000000000400546 <+0>:     push   %rbp
    0x0000000000400547 <+1>:     mov    %rsp,%rbp
    0x000000000040054a <+4>:     sub    $0x10,%rsp
    0x000000000040054e <+8>:     mov    %fs:0x28,%rax
    0x0000000000400557 <+17>:    mov    %rax,-0x8(%rbp)
    0x000000000040055b <+21>:    xor    %eax,%eax
    0x000000000040055d <+23>:    movl   $0x0,-0xc(%rbp)
    0x0000000000400564 <+30>:    addl   $0x1,-0xc(%rbp)
    0x0000000000400568 <+34>:    mov    -0xc(%rbp),%eax
    0x000000000040056b <+37>:    mov    -0x8(%rbp),%rdx
    0x000000000040056f <+41>:    xor    %fs:0x28,%rdx
    0x0000000000400578 <+50>:    je     0x40057f <main+57>
    0x000000000040057a <+52>:    callq  0x400420 <__stack_chk_fail@plt>
    0x000000000040057f <+57>:    leaveq
    0x0000000000400580 <+58>:    retq

test.c                                         2            0x400546
test.c                                         2            0x40054e
test.c                                         3            0x40055d
test.c                                         4            0x400564
test.c                                         5            0x400568
test.c                                         6            0x40056b

GDB currently assumes that the second entry is the beginning of the 
body.  But ideally we would treat the first two entries as the prologue, 
and put our breakpoint on line 3/0x40055d.

And then let's look at this modified example, where the first line of 
code is on the same line as the opening curly bracket, and compiled 
without stack protection (-fno-stack-protector):

1  int main()
2  { int n = 0;
3    n++;
4    return n;
5  }


    0x00000000004004d6 <+0>:     push   %rbp
    0x00000000004004d7 <+1>:     mov    %rsp,%rbp
    0x00000000004004da <+4>:     movl   $0x0,-0x4(%rbp)
    0x00000000004004e1 <+11>:    addl   $0x1,-0x4(%rbp)
    0x00000000004004e5 <+15>:    mov    -0x4(%rbp),%eax
    0x00000000004004e8 <+18>:    pop    %rbp
    0x00000000004004e9 <+19>:    retq

test.c                                         2            0x4004d6
test.c                                         2            0x4004da
test.c                                         3            0x4004e1
test.c                                         4            0x4004e5
test.c                                         5            0x4004e8

We have a similar line table as the previous example (same source line, 
different address), but in this case the second entry at line 2 is 
really the start of user code.  We would want to put our breakpoint at 
line 2/0x4004da.  So, how do we differentiate these two cases?

When skipping prologue without DWARF info, we could always recognize the 
pattern of instructions.  But when skipping the prologue using SAL, we 
don't look at the instructions, we only rely on DWARF, and I think it 
should stay that way.  If we need more information, then the DWARF info 
needs to be improved.  Are you aware of any other information that is 
currently present that could help us?

There exists a DWARF linetable opcode that indicates the end of prologue 
(DW_LNS_set_prologue_end).  Do you know why GCC doesn't use it?

Thanks,

Simon


  reply	other threads:[~2018-01-02 18:14 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-16 14:57 [PATCH 1/2] Fix indentation in gdb.mi/mi-stack.exp Simon Marchi
2017-12-16 14:57 ` [PATCH 2/2] Fix gdb.mi/mi-stack.exp when gcc generates a stack protector Simon Marchi
2018-01-02 10:38   ` Yao Qi
2018-01-02 18:14     ` Simon Marchi [this message]
2018-01-03 21:53       ` Yao Qi
2018-01-03 22:39         ` Simon Marchi
2018-01-04 20:10           ` Simon Marchi
2018-04-07 18:14         ` Simon Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9860ca45c4896a0e42190f4c34c68c4a@polymtl.ca \
    --to=simon.marchi@polymtl.ca \
    --cc=gdb-patches@sourceware.org \
    --cc=qiyaoltc@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox