Xcode 10 debugger stops on some breakpoints and doesn't on some others

The breakpoints that are working are defined twice (I don't know how or why they were created twice). When editing those breakpoints the condition item has two radio buttons. The first one is on with the text: "Use parent breakpoint condition, which is not set". The other radio button is near the "classical" text field for the condition. The breakpoints that don't work have only the text field for the condition. I can't find any documentation for this.

My questions : What makes I produce one kind of breakpoint and the other one ? Is it a bug ? (Only the working one, with radio buttons should be produced ?). It is not clear for me. What means the text: "Use parent breakpoint condition, which is not set" ? What is a parent breakpoint ? Why are they -when working- produced by pair ? Actually setting a working breakpoint seems to work randomly for me. Does anyone have the same problems ?

Replies

LLDB has the concept of parent and child breakpoints. This is necessary because the breakpoint specification (what to actually break on) can match multiple locations in memory, and that list of locations can vary over time as code is loaded and unloaded.

The parent breakpoint is identified by a number (1, 2, and so on) and the child breakpoints are identified by a pair of numbers (1.1, 1.2, 1.3, 2.1, and so on).

For an extreme example of this, use the Xcode user interface to set a symbolic breakpoint on open. When you run your program, it’ll hit a breakpoint almost immediately. Now dump the list of breakpoints using

br list
:
(lldb) br list
Current breakpoints:
1: name = 'open', locations = 132, resolved = 132, hit count = 1

  1.1: where = xxst`Darwin.open(Swift.UnsafePointer<Swift.Int8>, Swift.Int32, Swift.UInt16) -> Swift.Int32, address = 0x0000000100008b20, resolved, hit count = 0 
  1.2: where = xxst`Darwin.open(Swift.UnsafePointer<Swift.Int8>, Swift.Int32) -> Swift.Int32, address = 0x0000000100008b10, resolved, hit count = 0 
  1.3: where = libc++.1.dylib`std::__1::messages<char>::open(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::locale const&) const, address = 0x00007fff69658af0, resolved, hit count = 0 
  1.4: where = libc++.1.dylib`std::__1::messages<wchar_t>::open(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::locale const&) const, address = 0x00007fff69658cfe, resolved, hit count = 0 
  1.5: where = Foundation`-[NSStream(NSStream) open], address = 0x00007fff4127bcd5, resolved, hit count = 0 
  1.6: where = Foundation`-[NSCFInputStream open], address = 0x00007fff4127bf1f, resolved, hit count = 0 
  1.7: where = Foundation`-[NSCFOutputStream open], address = 0x00007fff4127c260, resolved, hit count = 0 
  1.8: where = CoreFoundation`-[__NSCFOutputStream open], address = 0x00007fff3edab3e7, resolved, hit count = 0 
  1.9: where = CoreFoundation`-[__NSCFInputStream open], address = 0x00007fff3edbf88e, resolved, hit count = 0 
  1.10: where = libsystem_kernel.dylib`__open, address = 0x00007fff6c539148, resolved, hit count = 1 
  1.11: where = CFNetwork`std::__1::basic_ifstream<char, std::__1::char_traits<char> >::open(char const*, unsigned int), address = 0x00007fff3dbc7c82, resolved, hit count = 0 
  … lots of other entries elided …

(lldb)

That’s a lot of breakpoints!

This list is also reflected in Xcode. If you go to the breakpoints navigator and disclose the twiddle triangle next to open, you’ll see 132 items. Normally I just collapse the twiddle triangle to hide all of these items and move on, but in some cases it’s nice to work with specific ones. To continue the example above, I’d probably want to disable all of the breakpoints except 1.10.

As to what’s going on in your specific case, it’s hard to say without knowing more details. I suspect that the above might be enough to get you going, but if not you should post the result from

br list
and I’ll take a look.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

One problem I have found with breakpoints is that multi-line statements really confuse them. When you set a breakpoint, always set it on a statement that has only a single line.


Conditional breakpoints are tricky. If I ever do a test, just to see if they work, they work 100% of the time. But if I'm debugging for real, they will fail maybe 60% of the time. If they work, they are likely to leave me deep in assembly code in some state where it is impossible to get back out to the symbolic code.


It is usually easy enough to find a single-line statement and put a break point on that. It is relatively rare that I need to break on a condition. And when I do, it is usually because of some difficult-to-debug condition that I don't want to attempt twice. I just add an if statement to the code and break on an NSLog() statement. This is a little more work that setting a breakpoint condition, but it is works perfectly 100% of the time.

One problem I have found with breakpoints is that multi-line statements really confuse them.

Indeed. I find closures (in Swift, blocks in Objective-C) to be especially annoying here. For example, in this code:

autoreleasepool {
    … some code …
}

if I set a breakpoint on line 1, I’ll hit that twice, once outside the call to

autoreleasepool(_:)
and once inside the closure. This makes some degree of sense (the closure does extend to line 1) but it’s somewhat annoying (r. 48194534).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for your answers. I did not yet resolve my problem. Here are some screenshots of the two kinds of breapoints :

The one that is working (i.e. debugger stops on it):
https://ibb.co/hK8mSqc

The one that didn't work (debugger doesn't stop) :

https://ibb.co/tK82KFp

(As the forum refuses me to insert images in the message, I posted images on an external server. I'm not sure it will work ... If not I 'll come back later.)

Does anyone know how to produce one kind and the other ? (I just clicked on the line number to create the breakpoint and it makes (randomly?) one or the other kind.

I have to say I'm developping two projects here : a framework and an application. I send the breakpoints to "User" so I expected the debugger to stop in the framework and in the app.

Is that C++ code? That's going to be tricky. It looks like the non-working breakpoints are in a header file. I don't know how well Xcode is going to handle those things. Code in C++ header files has always been a mess. I wouldn't fault Xcode for giving up on it.

Thank you, John. Your answer helped me.

I splitted the definitions of related classes into several files that I included in common files.

It seems the debugger doesn't deal with this. So I pasted all my code for the different classes into one "classical" duet .h/.cpp (yes it's C++ for use in audio units). Now the debugger seems to stop on each breakpoint.

I’m glad that you found a way around this. If you can extract the problematic part of your project into a small test program that reproduces the issue, I’m sure that our Clang++ and LLDB engineers would love to have a bug report about it.

If you do file a a bug, please post the bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

XCode 10.2.1


I am jumping into this thread because it keeps coming up in my DuckDuckGo searches, and because it features the comments of Quinn -- someone who over the years I have come to associate with excellent information. So...


Is there any way to have LLDB _NOT_ add all of the child breakpoints? I am getting numerous spurious "child" breakpoints added to my code, and I have not found any way to prevent this.


I have inserted a screenshot from XCode showing a typical such event. I set a breakpoint at line 240, and LLDB has decided to set an additional breakpoint at line 243.


I have tried adding dummy code between the various closing braces, but that just moves the problem around. LLDB still insists on breaking at a point that is not in the same flow path as the intentional breakpoint. If, for example, I add dummy code between the @catch closing brace and the method closing brace, the undesired child breakpoint moves to the @catch closing brace.


This mostly seems to occur with @try-@catch blocks.


So is this a LLDB bug?

If so, is there a known workaround?

There is no screenshot in your post.


You really shouldn't be using Objective-C exception handling in your code logic. You can, and should, use it in those cases where an Apple API could throw an exception. But the only thing you should be doing is reporting the error and immediately quitting the app. That's Apple's official line. I don't agree with that approach myself, but that's what Apple wants and Apple writes the compiler and debugger.

>I have inserted a screenshot...


You can add them...others aren't allowed to view them. It's a silent fail. See FAQ 2 here:For Best Results - Read the Label

john daniel wrote:

You really shouldn't be using Objective-C exception handling in your code logic.

That’s good advice. Specifically, be aware that Objective-C ARC makes no attempt to clean up object references in the presence of an exception, and thus if you have any ARC code in the backtrace from the exception thrower to the exception catcher you are likely to leak.

Beyond that, it’s hard to offer concrete advice without seeing the screen shot you posted. Or, better yet, post a code snippet as text (use the

<>
icon to format it as code) and then just reference the line numbers.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
@jldb I had a similar problem in Xcode 12.3 when working with one of my projects. Basically, the Debugger would not Stop on the Breakpoints I enabled in the gutter in one project, but it worked fine in other projects... I finally checked the Project Scheme and noted that the project with the problem did not have the "Debug executable" checkbox selected. Once I checked this box the Debugging operation worked normally. I hope this post helps anyone with a similar issue.

Cheers,
Mark