From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 76427 invoked by alias); 2 Jan 2018 18:14:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 76370 invoked by uid 89); 2 Jan 2018 18:14:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=our, interest X-HELO: smtp.polymtl.ca Received: from smtp.polymtl.ca (HELO smtp.polymtl.ca) (132.207.4.11) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 02 Jan 2018 18:14:35 +0000 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id w02IETFV029985 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 2 Jan 2018 13:14:34 -0500 Received: by simark.ca (Postfix, from userid 112) id DE9E91E5A6; Tue, 2 Jan 2018 13:14:28 -0500 (EST) Received: from simark.ca (localhost [127.0.0.1]) by simark.ca (Postfix) with ESMTP id 4B9AF1E519; Tue, 2 Jan 2018 13:14:14 -0500 (EST) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Date: Tue, 02 Jan 2018 18:14:00 -0000 From: Simon Marchi To: Yao Qi Cc: GDB Patches Subject: Re: [PATCH 2/2] Fix gdb.mi/mi-stack.exp when gcc generates a stack protector In-Reply-To: References: <20171216145651.13936-1-simon.marchi@polymtl.ca> <20171216145651.13936-2-simon.marchi@polymtl.ca> Message-ID: <9860ca45c4896a0e42190f4c34c68c4a@polymtl.ca> X-Sender: simon.marchi@polymtl.ca User-Agent: Roundcube Webmail/1.3.2 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Tue, 2 Jan 2018 18:14:29 +0000 X-IsSubscribed: yes X-SW-Source: 2018-01/txt/msg00021.txt.bz2 On 2018-01-02 05:38, Yao Qi wrote: > On Sat, Dec 16, 2017 at 2:56 PM, Simon Marchi > 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 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