In Eclipse, is there a way to disable a breakpoint until another breakpoint is hit first? - eclipse

In Eclipse, is there a way to disable a breakpoint until another breakpoint is hit first?

This is a big hack, but it is a functional workaround:
Call the 'trigger' location breakpoint 1 and the target location breakpoint 2. We want breakpoint 2 to fire if-and-only-if execution has passed breakpoint 1.
Set conditional breakpoints at each.
For breakpoint 1, set the condition as System.setProperty("breaknow", "breaknow") == "". This condition will never be true, but will set a system property which we can read at breakpoint 2.
For breakpoint 2, set the condition as System.clearProperty("breaknow") != null. This condition will trigger when the system property is set, and also clear it (so we can repeat if needed).
As I said, it's a hack, but it seems to work. I submitted an Eclipse enhancement request to implement linking or chaining breakpoints as a native feature (https://bugs.eclipse.org/bugs/show_bug.cgi?id=390590). Unfortunately, I don't have bandwidth to implement it myself, but perhaps we'll get support for a cleaner solution someday.
One caveat (which applies to all conditional breakpoints, not just to this trick): From my experience, it appears that a setting a conditional breakpoint prevents the JIT from compiling the method of interest, running it in interpreted mode instead. Or perhaps, it allows the first C1 JIT stage but prevents the second-stage C2 compiler from optimizing?
In either case, you should be aware that the method you’re debugging will run considerably slower with a conditional breakpoint in place. This isn’t usually a problem, but when debugging very tight inner loops, I’ve found it better to fall back to the (sloppy) if (x) { // Do somthing useless and set a breakpoint here} method.

No. But you can have conditional breakpoints. I guess that hitting the other breakpoint indicates some change of state.
So, Right click the breakpoint -> Breakpoint properties -> check "conditional"

If you know the condition at which the other break point will be hit, then you can add that condition to the new breakpoint.

Conditional breakpoints are one possibility, and you can also set a Hit Count so that the breakpoint is only triggered after being hit the specified number of times.
But no, there is no way to do what you are asking.

Another idea is to disable your breakpoint and enable it once the other breakpoint is hit.

Related

breakpoint with debugger Commend jump in xcode

I made a breakpoint in Xcode with the jump commend to force passing some condition, but when it execute to line 168 it crash with message
"Thread 1: EXC_BAD_ACCESS (code=1, address=0x1)"
why did that happen?
the console logged:
warning: MoreMultitypeCollectionViewCell.swift:178 appears multiple times in this function, selecting the first location:
MoreMultitypeCollectionViewCell.(updateButtonStateCkeck in _9A12557DCAB30EEB52DC7C2EA09487CD)() -> () + 1580 at MoreMultitypeCollectionViewCell.swift:178
MoreMultitypeCollectionViewCell.(updateButtonStateCkeck in _9A12557DCAB30EEB52DC7C2EA09487CD)() -> () + 1600 at MoreMultitypeCollectionViewCell.swift:178
my questions are:
How should I type in lldb to select location?
Is there a better way to force passing into If Statement without change code and rebuild project?
sometimes when I type 'po' in lldb or click print description in variable view, it will show fail message, how is that?
1) In lldb, the equivalent command is thread jump and you can specify an address as well as a line number there.
2) thread jump or the Xcode equivalent is an inherently dangerous operation. If you jump over the initialization of some variable, you will be dealing with bad data now and will likely crash. That sort of thing you can sometimes spot by eye - though Swift is lazy about initialization so the actual initialization of a variable may not happen where you think it does in the source. There are more subtle problems as well. For instance, if you jump over some code that as a byproduct of its operation retains or releases an object, the object will end up under or over retained. The former will cause crashes, the latter memory leaks. These retains & releases are generated by the compiler, so you can't see them in your source code, though you could if you look at the disassembly of the code you are jumping over.
Without looking at the code in question, I can't tell why this particular jump caused a crash.
But you can't 100% safely skip some of the code the compiler choose to emit. Looking at the disassembly you might be able to spot either (a) a better place to stop before the jump - i.e. stop past some retain or release that is causing a problem or jump to an address in the middle of a line so you still call a retain that's needed. You'll have to figure this out by hand.
3) There's not enough info to answer this question.
BTW, your image links don't seem to resolve.

Debug breakpoint in Swift Playground?

I'm trying to add a breakpoint in the line # gutter, but no breakpoint is added when I do this in the playground. Is this possible or is there another way to set breakpoints in the playground?
There's no debugger so you can't add any breakpoints.
Matt, I could not enter code in the comments so here is a better view of using a variable on a line by itself to "debug" it.
for index in 1...5 {
dosomething(foo);
foo;
}
Then you can click the eyeball on the right hand side to see a history of foo as it was modified in the loop.
If you want to pause execution of a playground to have a peek at what's going on, you can use sleep. The information you can get isn't nearly as granular as what you can get from lldb.
To do this, you'll need to add import Foundation at the top of your playground.
Then, wherever you want to pause execution, you can add this:
sleep(10) // 10 second pause...you can make the number whatever you want
I'm just getting my feet wet in Swift, but I think the playground idea is to show the changing state as if you ran in debug and recorded all the variable changes. There's no actual need for a breakpoint as you can see the state at any "point in time". I think it'll take me a while to get used to it, having used a debugger for > 30 years, but should be quite useful for small bits of isolated test code, especially while I'm learning the language.

Always Change value of a variable at a certain line of code

I know that a variable value can be changed in the debug mode of Eclipse. But can I make that change happen every time a certain line is getting executed?
What I want to do is to make the change every time without manually having to do it.
If I got you right, I might have a solution that suits your needs here (or at least "might have suited", for I must admit this thread is pretty old by now ... ;-):
I had a similar issue this morning, detouring a "mailTo" (just a variable holding the recipients adress). I came to use a conditional breakpoint with the following condition:
"42" != (mailTo = "a#bc.de")
You always hit the breakpoint because "42" (or whatever value ;-) will never be equal to the assignment on the right - which yet does the main-job here.
Its also possible to make it "really conditional" (if needed) by using {real condition} && {fake condition} (because the fake is then depending on a preceding 'true')

During debugging, how to evaluate a piece of code in the debug target VM?

During debugging, e.g. in Eclipse, one can evaluate Watch Expressions or Conditional Breakpoints. Typically, these are evaluated on the client side. For instance, when debugging from within Eclipse, it is Eclipse itself, not the debug target VM that evaluates these expressions. This can be quite costly, especially in the case of conditional breakpoints because the debugging VM (i.e. Eclipse) needs to become active on every breakpoint hit, even if the condition evaluates to false.
My question is now whether the debug protocol permits it to instead evaluate such expressions or conditional breakpoints in the debug target VM, such that the target VM only notifies the debugging VM when the expression/condition really evaluated to TRUE.
Apart from the IDE (ab)using Hot Code Replacement to replace the method body by a body with an empty if block and putting the (conditional) breakpoint in there, I cannot find anything in http://download.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html that might help for doing this.
There is an exprId in EventRequest.Set which is documented as "for the future" and not exposed wia JDI BreakpointRequest, so I don't think this has or will ever work.
By the way, the evaluation happens inside the target VM (i. e. if you use equals() in your expression, equals() will run in your target vm), but the evaluation will be triggered from the debugging VM.

Why does assert simply terminate a program compiled for iPhone?

I'm debugging a heavily assert()'ed iPhone app (Xcode, Objective-C++, and device simulator). In some cases, the assert failure would just terminate the app, instead of breaking into the debugger as I'd expect.
I made a workaround by implementing my own kinda-assert to the effect of:
#define AssertLite(b) if(!(b)) {asm {int 3}}
(fluff omitted), but I wonder if anyone ever encountered this. I could not determine a pattern as to when does it break and when does it terminate. The code is not threaded; all it does is done in event handlers.
Why does this happen and how do I make vanilla assert() behave like a conditional breakpoint it should be?
First off, since you are working on an iPhone app, you should probably use NSAssert() instead of the vanilla BSD assert function.
e.g. NSAssert(the_object, #"NIL object encountered");
The NSAssert macro will throw an Objective-C exception (NSInternalInconsistencyException) if the assertion fails.
Since your goal is to break on the exception, the next step is to make the Xcode debugger break on Objective-C exceptions. This is probably a good thing to do anyway.
In the Breakpoints window (Run->Show->Breakpoints menu item), click where it says "Double-Click for Symbol" to enter the symbol -[NSException raise]
The last thing to be careful off is that NSAsserts do not compile out in a release build. That means that you have to either be prepared to handle the exception in your application, or you need to create your own macro that does compile out in release builds.
Here's the macro I use to compile out assertions in runtime code (note that I then use HMAssert in my code instead of NSAssert):
#ifdef DEBUG
# define HMAssert(A,B) NSAssert(A,B)
#else
# define HMAssert(A,B)
#endif
This requires a DEBUG preprocessor macro to be defined. Here's how to set that up:
Right-click on your project in Xcode. That will be the top item in the left panel where your projects files are listed
Select "Get Info" from the context menu that pops up.
Go to the "Build" tab.
Make sure the "Configuration" is set to "Debug".
Type DEBUG into the field next to "Preprocessor Macros" under "GCC 4.2 - Preprocessing".
First of all, if you "Add Exception Breakpoint..." in the Breakpoint Navigator (⌘6), the debugger will stop on NSAssert's failures, allowing you to look at the stack and understand what went wrong.
You should use the standard NSAssert. If you use it correctly, there is not a lot that you need to manually create -- everything Mike mention is similar to the default NSAssert implementation.
You should run you release configuration with NS_BLOCK_ASSERTIONS set in your precompiled headers (follow Mike's steps), to disable assertions. If you need more info on why to do so, check out: http://myok12.wordpress.com/2010/10/10/to-use-or-not-to-use-assertions/
In Xcode 4 and new iOS, NSAssert may actually take a variable list of parameters. This may be useful to log some values together with the assert. The compiling-out assert (see answer by Mike above) could be defined like this:
#ifdef DEBUG
# define DAssert(A, B, ...) NSAssert(A, B, ##__VA_ARGS__);
#else
# define DAssert(...);
#endif
Also, there is no longer Run → Show → Breakpoints menu item. See this post to set up Xcode 4 to break on an assert as defined above.
One time I saw a different behavior from the assert() calls once. It was caused by the compiler picking up different macro definitions at different portions of the build process.
Once the include paths were straightened out, they all worked the same.