From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2369 invoked by alias); 19 Nov 2003 19:38:00 -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 2323 invoked from network); 19 Nov 2003 19:37:58 -0000 Received: from unknown (HELO mail-out3.apple.com) (17.254.13.22) by sources.redhat.com with SMTP; 19 Nov 2003 19:37:58 -0000 Received: from mailgate1.apple.com (a17-128-100-225.apple.com [17.128.100.225]) by mail-out3.apple.com (8.12.10/8.12.9) with ESMTP id hAJJbvLh018539 for ; Wed, 19 Nov 2003 11:37:57 -0800 (PST) Received: from scv2.apple.com (scv2.apple.com) by mailgate1.apple.com (Content Technologies SMTPRS 4.2.1) with ESMTP id for ; Wed, 19 Nov 2003 11:37:23 -0800 Received: from [17.201.22.245] (inghji6.apple.com [17.201.22.245]) by scv2.apple.com (8.12.9/8.12.9) with ESMTP id hAJJbbEV027245 for ; Wed, 19 Nov 2003 11:37:37 -0800 (PST) Mime-Version: 1.0 (Apple Message framework v606) In-Reply-To: <1069259237.12557.ezmlm@sources.redhat.com> References: <1069259237.12557.ezmlm@sources.redhat.com> Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: Content-Transfer-Encoding: 7bit From: Jim Ingham Subject: Re: [WIP] pending breakpoint support Date: Wed, 19 Nov 2003 19:38:00 -0000 To: gdb-patches@sources.redhat.com X-SW-Source: 2003-11/txt/msg00404.txt.bz2 On Nov 19, 2003, at 8:27 AM, gdb-patches-digest-help@sources.redhat.com wrote: > On Tue, Nov 18, 2003 at 08:03:09PM -0500, J. Johnston wrote: >> I have been hacking around with supporting "future-break" >> functionality >> (note, I said "hacking"). I have seen past discussion regarding the >> issue >> and the requirement to add functionality to the current breakpoint >> command >> as opposed to creating a separate command. > > Wonderful! As you may guess, I have some comments :) I concur! Thanks for doing this! > >> For my change, I wrappered the call to parse_breakpoint_sals() to >> catch any >> error. If the call fails, then I simply give the user the option as >> marking it as pending. I then make a fake breakpoint with a special >> enable_state of bp_shlib_pending. I also save the original breakpoint >> command as the addr_string plus some needed state to recreate the >> command >> at a later time. I attempted to have any original condition parsed >> but it >> isn't used in my current design as I end up reparsing the original >> command >> from scratch anyway. > > I don't really like this implementation (bp_shlib_pending). To explain > why, I need to take a step back to the last conversation about multiple > breakpoints. Particularly, the question of what "break foo" should do > in various cases. Here's some of the simple ones: > > 1. int foo(void); > int foo(int); > > 2. int foo(void); > int foo(void); > > 3. foo.c:static int foo(void); > bar.c:static int foo(void); > > 4. libfoo.so:int foo(void); > libbar.so:int foo(void); > appbar.exe:int foo(void); > > The answer for (1) is pretty straightforward. Right now we prompt and > create multiple independent breakpoints, and I don't see a problem with > that. I believe that's currently what we do for (2) also - a little > less clearcut but it still seems reasonable to me. > > For (3) we currently pick one at random (whichever appears first); when > the global symbol lookup fails we iterate through static blocks. > That's bad. We should prompt, and do as in (1). > > All clear so far, but the one I really wanted to point out was (4). I > believe that it shouldn't be handled like the others. Instead it > should be handled like I am planning to handle inlined functions - as > one breakpoint with multiple addresses (and some special handling for > PLT entries...). For a particular example of where this is useful, on > at least Darwin the libsupc++ functions used for C++ exception handling > can appear in multiple shared objects, and each will use its own. A > breakpoint on one of them had best be placed on all of them if you > really want GDB to catch all exceptions! In general, in this case, > there are too many factors to predict which copy of a function will be > called; so the least confusing thing for GDB to do would be to > breakpoint on all of them. There are two different needs here. The case of the exception handling is one extreme, where we not only want to set all the breakpoints we can currently find, but keep watching for any future chance to set the breakpoint. The other extreme is when you have an IDE that KNOWS that this breakpoint is being set in a project that produces a given shared library or executable. In that case, you want to specify only a particular shared library. On MacOS X, I also have some cases where there is enough shared library activity that I don't actually want to be re-evaluating ALL the breakpoints every time I get a load event. Our case is not so common - it mostly arises from the ZeroLink style of building applications where all the .o's get made into little shlib's instead of being linked together (this is done to speed up turn-around time) and so you can get ~500 or so shlibs loading, in batches of ~10 at a time, in the startup of a medium sized app. Still, it is worth keeping in mind... This need also arises for #4 when the IDE holds breakpoints persistently across runs. In that case, the sensible thing to do is tell the user you found multiple instances, and ask which ones they want. But then when you rerun the debugger, you really don't want to ask again. You need instead to record enough info, and be able to pass it to gdb, to reset the breakpoint in the right shlib. This is actually pretty easy to do in gdb - I hacked it into our version for the mi. But when we discussed this last time we didn't come to any consensus about how to pass this through the cli break command, so I didn't do it there... > > This suggests that a different implementation is in order, because when > a shared library is loaded we may want to expand a bp_enabled > breakpoint to have two addresses also. Support for breakpoints with a > variable number of location elements is coming "soon"; it's my next > planned project. This is great! One thing that we need to be sure is that we don't lock ourselves into an all or nothing solution here either. It should be possible to say "I am happy with this breakpoint, don't keep looking" as well as to keep looking. > >> When we are loading shared libraries, the function >> re_enable_breakpoints_in_shlibs() gets called. I have added code in >> there >> to attempt to reparse any pending break command. If successful, a new >> breakpoint is created by basically reissing the command with saved >> state >> accounted for. After creating the new breakpoint(s), I delete the >> pending >> place holder breakpoint. > > This raises an unpleasant question. If one of the two functions above > doesn't have adequate debug information to evaluate the condition, what > do we do? Punt? What's punting in this case - making one of them > unconditional, making both of them unconditional, not breakpointing the > one? Warning the user presumably. > > One of many sticky interface problems I've thought of but not come up > with a good answer for. Did you move the cond field of the breakpoint part out of the umbrella breakpoint structure in your patch, I don't remember. That will be necessary here because even if the condition is parseable in two contexts the struct expression that results is different. > >> Ideally, I would liked to have reused the same breakpoint structure >> that >> was initially allocated but in my code there still was the >> possibility of >> one command generating multiple breakpoints so I took the >> aforementioned >> strategy. I have been informed that the newer breakpoint model will >> eliminate that problem and I should be able to reuse the breakpoint >> number, >> etc... > > Yes, this should be OK. > >> A problem I didn't solve yet has to do with the issuing of error >> messages >> for pending and disabled shared-library breakpoints when the >> reenablement >> is attempted and it fails. This can be very annoying when you have a >> large >> number of shared libraries loaded each time (e.g. Eclipse). >> >> I have included a gdb session below along with the patch I used so >> folks >> can see how it currently works. >> >> What I would like to do is get some discussion going: >> >> 1. Is the user interface on the right track? >> 2. What gotchas do I need to think about? >> 3. Any design recommendations for implementing this better? > >> (gdb) b printf >> Function "printf" not defined. >> Make breakpoint pending? (y or n) y >> Breakpoint 1 (printf) pending. > > The wording needs to be improved. If I hadn't been working on pending > breakpoints I'd have no idea what it meant. How about something like > this (still very awkward): > > (gb) b printf > Function "printf" not currently defined. > Create a pending breakpoint for later definitions of "printf" loaded > from shared libraries? (y or n) y > Breakpoint 1 (printf) pending. Note that an IDE (presumably through the mi) will most likely want to be able to always answer "yes" to this without having to answer back. That will work in the code that you currently have, but only because query answers yes when you are not a tty. This seems to me a fragile form of control here. It would be better if there were a way for the mi command to explicitly override the question with a yes or no answer. Jim -- Jim Ingham jingham@apple.com Developer Tools Apple Computer