From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27809 invoked by alias); 12 Jun 2005 07:07:49 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 27795 invoked by uid 22791); 12 Jun 2005 07:07:42 -0000 Received: from sibelius.xs4all.nl (HELO sibelius.xs4all.nl) (82.92.89.47) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Sun, 12 Jun 2005 07:07:42 +0000 Received: from elgar.sibelius.xs4all.nl (root@elgar.sibelius.xs4all.nl [192.168.0.2]) by sibelius.xs4all.nl (8.13.0/8.13.0) with ESMTP id j5C77YpK021462; Sun, 12 Jun 2005 09:07:34 +0200 (CEST) Received: from elgar.sibelius.xs4all.nl (kettenis@localhost.sibelius.xs4all.nl [127.0.0.1]) by elgar.sibelius.xs4all.nl (8.13.4/8.13.3) with ESMTP id j5C77YP2014883; Sun, 12 Jun 2005 09:07:34 +0200 (CEST) Received: (from kettenis@localhost) by elgar.sibelius.xs4all.nl (8.13.4/8.13.4/Submit) id j5C77TL6005645; Sun, 12 Jun 2005 09:07:29 +0200 (CEST) Date: Sun, 12 Jun 2005 07:07:00 -0000 Message-Id: <200506120707.j5C77TL6005645@elgar.sibelius.xs4all.nl> From: Mark Kettenis To: jmolenda@apple.com CC: gdb-patches@sources.redhat.com In-reply-to: <85C775AE-3B05-431E-96D2-49EA9D1413E6@apple.com> (message from Jason Molenda on Tue, 7 Jun 2005 22:51:36 -0700) Subject: Re: The gdb x86 function prologue parser References: <85C775AE-3B05-431E-96D2-49EA9D1413E6@apple.com> X-SW-Source: 2005-06/txt/msg00116.txt.bz2 From: Jason Molenda Date: Tue, 7 Jun 2005 22:51:36 -0700 Hi Jason, Sorry I didn't reply before; I still was on vacation when you sent out this mail. As was announced yesterday, we'll be transitioning from PPC to x86 over the next couple of years. Over the last few months I had a delightful little introduction to the x86 architecture (read: read the IA32 PDFs until I couldn't see straight any more) and worked to get our x86 gdb support up to snuff for this software release. Seems like a step backwards to me, but hey who am I to judge Apple. Watched the QuickTime video where your big boss announces the thingy. Seems he's firmly in bed with Intel and not AMD. Still makes me wonder if Apple is going to provide a 64-bit version of MacOS X for the new platform. Another question that I have is what calling convention MacOS X will use. Is it something like the System V ABI where the caller is supposed to clean up the stack after a function call? I certainly hope so since the Microsoft way of doing things poses a major headache for prologue scanning. One of the biggest problems we found was the x86 function prologue parser is remarkably weak. We have a very mature and featureful prologue parser on our ppc side and an amazing number of bugs were directed my way as we had people pounding on the x86 side. We aren't using DWARF yet, so CFI can't save our bacon -- the prologue parser has to work or our gdb fails. I don't know to what extent your version of gdb is synched with the FSF tree, but if it is anything close to gdb 6.x, then yes, you're pretty much hosed if the prologue scanner fails. It's no surprise to me though that the prologue scanner appears a bit weak to you though. It started out as a prologue scanner for the origional System V compiler with some additions to older GCC versions when I took over. At that point, GCC still had a fixed prologue. When GCC 3.x started scheduling prologue instructions, it also started generating usable DWARF CFI, so whe took the conscious decision to rely on that and only improve the prologue scanner on an as-needed basis. Since GCC 3.x targets for all major free OS'es all use DWARF by default, this means that the prologue scanner really only handles some bits of hand-optimized assembler. There are a couple classes of changes I made, and I spent today trying to massage them into some kind of presentable form. This is not perfect -- well, to be honest, this is just a first sketch -- but this is a HUGE improvement over the existing facilities. I wrote the code while under immense deadline pressure so I'm not particularly interested in how I implemented any of it. But changes akin to these are necessary if you want to debug programs with optimized code on the stack and without CFI. I'll guarantee it. It'd be great if we could improve the prologue scanner. This reminds me that I really should start testing -gstabs. Roughly speaking, here are the class of changes included in this patch. 1. i386_match_insn() bug fixes. It wouldn't work for an instruction pattern of 1 byte, and it would never check anything beyond the 2nd byte (notice where the final "return insn" is located). I've added patterns that can match prologue instructions, so exceptions had to be added for the big two (push %ebp, mov %esp, %ebp) and the equivalent ones used in the first frame (_start()). Duh. I must have been on drugs when I wrote that code. 2. i386_frame_setup_skip_insns table expansion. Because you can't skip over an unknown instruction on x86 without knowing its length, this was of paramount importance. Initially I waited for users to tell me of prologues that gdb was failing on, but this was taking too long and there were too many instructions scheduled into prologues for me to hear of them in time. So I wrote a little maintenance command (not included in the patch to keep things simple) which would tell you if gdb could parse through the prologue of a given function. Then with a couple of shell scripts, I could have gdb try to analyze the prologues of every function in every library on my MacOS X system and show me the ones it failed on. I'd add them to this list. I also made a little testsuite generator where the input looks like # SOURCE: RedHat FedoraCore2 /lib/ld-2.3.3.so _dl_reloc_bad_type # PROLOGUE push %ebp shl $0x5, %ecx # [ 0xc1 0xe1 0x05 ] mov %esp, %ebp sub $0x8, %esp # EPILOGUE add $0x8, %esp pop %ebp ret and a script that transforms the patterns into a test program and a Dejagnu expect script. So you can ensure that you don't regress the prologue parser. This was the lesson we learned in writing our PPC parser -- we have this wonderfully ornate parser with lots of exceptions and known tricks, but no testsuite for it. So whenever we change it we're cringing because the gdb testsuite has nothing useful in it. (you need optimized, no debug info test cases to be sure it's still working right). The testsuite stuff isn't included in this patch, but I'll put that together soon and send it along if anyone's interested. Certainly, if we change the prologue scanner to deal with new patterns we should test these patterns in the testsuite. 3. relatively minor changes to i386_analyze_frame_setup(). It had to have the push %ebp as the very first instruction or it would give up. That's really bad -- the compiler can (and does) schedule all sorts of stuff before that instruction. I believe you. I'm wondering though if the current way the prologue scanner is built up makes sense for this new world of completely scheduled prologues. 4. new function, i386_find_esp_adjustments(). This is used in a frameless leaf function where the compiler may create space on the stack for local variables and stuff, but doesn't call anything so it doesn't save the caller's frame pointer. And it allows -fomit-leaf- frame-pointer codegen to be debugged. -fomit-frame-pointer is a whole lot more complicated, but this wasn't so bad. (we didn't end up enabling -fomit-leaf-frame-pointer in this release because of the schedule time constraints, but that's why I wrote it) Being able to debug -fomit-frame-pointer code without CFI probably means that instead of scanning the prologue, we'll have to scan the complete function up to the current instruction pointer. I really wonder if that's the way we should go. 5. Huge i386_frame_cache() changes. There's no way around it, this function is just not right. It doesn't handle frameless functions correctly at all. It's written without a clear understanding of the different classes of functions it needs to handle and works primarily by luck. And for goodness sakes, if we can't figure out anything about a function that's not at the top of the stack, don't you think it'd be reasonable to assume that the function has set up a stack frame and saved the caller's EBP? Sure seems like a reasonable assumption to me. Why can't this function do something even that basic? This function really cheesed my mellow. Well, it handles most of the frameless functions encountered on a GNU/Linux system with GCC 3.2 fine. And no, assuming that a function has set up a stack frame isn't right; it makes gdb silently skip function calls in backtraces. That can be very confusing. As I've stated before, I'd rather have a backtrace that's obviously wrong than one that silently omits things. But it's a trade-off. Maybe improving the prologue scanner can shift the balance far enough that the assumption that a stack frame has been set up makes more sense again. Assuming that a function saves the previous value of %ebp is demanded by the System V ABI, but GCC might violate the ABI for static functions where it knows the caller has already saved %ebp. Mark, I want to say that I'm not directing any of these criticisms towards you -- I've been looking over the changes you've made and they're definite improvements over the existing code. The existing code bites, though. I can't even begin to imagine how annoyed developers using the FSF gdb on x86 must be. The changes I'm sending here are not a panacea/beautiful/perfect, but *functionally* they're a huge improvement. Now that our release is out there I'll be more than happy to revisit the decisions/implementation that I came up with on little sleep. :-) Great. I haven't looked at your patch in detail yet. But it sounds like some of the improvements can be made right away, so let's get working on this ;-). Oh, and I ran my "find all prologues gdb can't parse" on a FedoraCore 2 system I have handy here at the office today and added the patterns of the biggest offenders. There are still a few patterns I need to add to get 100% parsing success but I want to go home :-) so that'll be for another day. We're in the middle of an all-week Apple developer's conference, so my replies may not be very speedy (I'm off-line 10-12 hours a day; I slipped away to get this patch together today) until the weekend. But I'll try to stay on top of any questions or comments and address them promptly. No problem; I was having a vacation anyway ;-). Mark