From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 80681 invoked by alias); 21 Jan 2016 19:45:56 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 80666 invoked by uid 89); 21 Jan 2016 19:45:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=rescue, closure, edi, dov X-HELO: mail-lb0-f181.google.com Received: from mail-lb0-f181.google.com (HELO mail-lb0-f181.google.com) (209.85.217.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 21 Jan 2016 19:45:54 +0000 Received: by mail-lb0-f181.google.com with SMTP id oh2so29333692lbb.3 for ; Thu, 21 Jan 2016 11:45:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=Ft0yGgHTXxA8BJOpD9Pn7qaH/9ppJvqRR9mSMiUXZXk=; b=dnWQP8wIxBcBn0WLrA6gx05F96gIxmzlkg+iKS8NuC7W4jM4ZDfAo7NtooL2yoXj2N H+3a8BNPx3fhddzjc1oejV0Z8zlPLrqx6MZqJSv6I6o7XNzDqbQFUGG7unHQZoC0BZ3L 8jX1uLuxqPFRQ5EQ0tyruSfWAihbp1HmRdSwfFq0HKCr6FJ2VS4fq/43hdSw/npfZ1d+ kjJQnuRvCHG4l9QphhRj5SNEtdVyqzwpYHmOUVM0bltfnc2A8gGR1O1KTFuf8rsik+tu iJsNMzZwnlmzepFrbxtptACKIwLBv5LNSOt9qWHyii0RJ8DDsepm0HoJaYA4vQdlEcSo 1m6Q== X-Gm-Message-State: ALoCoQlXiO+gG1XWjJagPGvSHGemReRmgw0ESVPZxfhPpGy7DHgMM1WShe3bYOo6QhWaqeToszfrDPocumtfKUbVdCqy2vnYQA== MIME-Version: 1.0 X-Received: by 10.112.157.101 with SMTP id wl5mr16050936lbb.88.1453405550628; Thu, 21 Jan 2016 11:45:50 -0800 (PST) Received: by 10.112.43.175 with HTTP; Thu, 21 Jan 2016 11:45:50 -0800 (PST) Date: Thu, 21 Jan 2016 19:45:00 -0000 Message-ID: Subject: x64 machine code and stack frames From: Dov Grobgeld To: gdb@sourceware.org Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2016-01/txt/msg00046.txt.bz2 Hello, I've inherited some clever x64 machine code for linux that creates an machine code wrapper around a c-function call. I guess that in higher language terms the code might be called a decorator or a closure. The code is functioning well, but with the unfortunate artifact that when the wrapper is called, it gobbles the stack trace in gdb. >From what I have learned from the net gdb uses https://en.wikipedia.org/wiki/DWARF as a guide for separating the stack frames in the stack. This works well for static code, but obviously code generated and called at run time isn't registered in the DWARF framework. My question is if there is any way to rescue the stack trace in this situation? Here is a similar code that shows the problem. 1 typedef int (*ftype)(int x); 2 int wuz(int x) { return x + 7; } 3 int wbar(int x) { return wuz(x)+5; } 4 int main(int argc, char **argv) 5 { 6 const unsigned char wbarcode[] = { 7 0x55 , // push %rbp 8 0x48,0x89,0xe5 , // mov %rsp,%rbp 9 0x48,0x83,0xec,0x08 , // sub $0x8,%rsp 10 0x89,0x7d,0xfc , // mov %edi,-0x4(%rbp) 11 0x8b,0x45,0xfc , // mov -0x4(%rbp),%eax 12 0x89,0xc7 , // mov %eax,%edi 13 0x48,0xc7,0xc0,0xf6,0x04,0x40,00, // mov $0x4004f6,%rax 14 0xff,0xd0, // callq *%rax 15 0x83,0xc0,0x05 , // add $0x5,%eax 16 0xc9 , // leaveq 17 0xc3 // retq 18 }; 19 20 int wb = wbar(5); 21 ftype wf = (ftype)wbarcode; 22 int fwb = wf(5); 23 } Compile it by: gcc -o mcode mcode.c execstack -s mcode and run it in gdb by: $ gdb mcode (gdb) break wuz If we disassemble wbar we get something very similar to the byte sequence in wbarcode[]. The only difference is that I changed the calling convention for calling wuz(). (gdb) disas/r wbar Dump of assembler code for function wbar: 0x0000000000400505 <+0>: 55 push %rbp 0x0000000000400506 <+1>: 48 89 e5 mov %rsp,%rbp 0x0000000000400509 <+4>: 48 83 ec 08 sub $0x8,%rsp 0x000000000040050d <+8>: 89 7d fc mov %edi,-0x4(%rbp) 0x0000000000400510 <+11>: 8b 45 fc mov -0x4(%rbp),%eax 0x0000000000400513 <+14>: 89 c7 mov %eax,%edi 0x0000000000400515 <+16>: e8 dc ff ff ff callq 0x4004f6 0x000000000040051a <+21>: 83 c0 05 add $0x5,%eax 0x000000000040051d <+24>: c9 leaveq 0x000000000040051e <+25>: c3 retq End of assembler dump. If we now run the program it will stop twice in wuz(). The first time through our c-call and we can ask for a stack trace through bt. Breakpoint 3, wuz (x=5) at mcode.c:2 => 0x00000000004004fd : 8b 45 fc mov -0x4(%rbp),%eax 0x0000000000400500 : 83 c0 07 add $0x7,%eax 0x0000000000400503 : 5d pop %rbp 0x0000000000400504 : c3 retq (gdb) bt #0 wuz (x=5) at mcode.c:2 #1 0x000000000040051a in wbar (x=5) at mcode.c:3 #2 0x00000000004005b0 in main (argc=1, argv=0x7fffffffe528) at mcode.c:20 This is a normal stack trace showing that we got from main->wbar->wuz(). But if we now continue we reach wuz() a second time, and we again request a stack trace: (gdb) c Continuing. Breakpoint 3, wuz (x=5) at mcode.c:2 => 0x00000000004004fd : 8b 45 fc mov -0x4(%rbp),%eax 0x0000000000400500 : 83 c0 07 add $0x7,%eax 0x0000000000400503 : 5d pop %rbp 0x0000000000400504 : c3 retq (gdb) bt #0 wuz (x=5) at mcode.c:2 #1 0x00007fffffffe419 in ?? () #2 0x0000000500000001 in ?? () #3 0x00007fffffffe440 in ?? () #4 0x00000000004005c6 in main (argc=0, argv=0xffffffff) at mcode.c:22 Backtrace stopped: frame did not save the PC Even though we have done the same two hierarchical calls, we get a stack trace that contains the wrong frames. In my original inherited wrapper code the situation was even worse, as the the stack trace ended after 5 frames with the top level having address 0. So the question is again, is there any extra code that can be added to wbarcode[] that will cause gdb to output a valid stacktrace? Or is there any other run time technique that may be used to make gdb recognize the stack frames? Thanks! Dov