23

I've written some code that dumps all ivars of a class into a dictionary in Objective C. This uses valueForKey: to get the data from the class. Sometimes, KVC throws an internal exception that is also captured properly - but this disrupts lldb's feature and all I get is:

error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3).. The process has been returned to the state before expression evaluation.

There are no breakpoints set. I even tried with -itrue -ufalse as expression options, but it doesn't make a difference. This totally defeats for what I want to use lldb for, and it seems like such a tiny issue. How can I bring clang to simply ignore if there are internal, captured ObjC exceptions while calling a method?

I tried this both from within Xcode, and directly via calling clang from the terminal and connecting to a remote debug server - no difference.

Varun Kumar
  • 344
  • 2
  • 24
steipete
  • 7,581
  • 5
  • 47
  • 81

4 Answers4

21

I ran into the same issue. My solution was to wrap a try/catch around it (I only use this code for debugging). See: DALIntrospection.m line #848

NSDictionary *DALPropertyNamesAndValuesMemoryAddressesForObject(NSObject *instance)

Or, if you're running on iOS 7, the private instance method _ivarDescription will print all the ivars for you (similar instance methods are _methodDescription and _shortMethodDescription).

steipete
  • 7,581
  • 5
  • 47
  • 81
haShalosh
  • 234
  • 2
  • 2
  • 4
    The try/catch doesn't solve my original problem - you just work around it by only getting the value if it's an object. But I'll accept the answer because these new iOS 7 helpers are simply amazingly useful and will solve my problem. Thanks! – steipete Jan 11 '14 at 09:15
4

I met the same problem.

My solution is simply alloc init the property before assigning it to the value which caused the crash.

Varun Kumar
  • 344
  • 2
  • 24
mollysmile.ye
  • 51
  • 1
  • 3
3

Myself and coworkers ran into this today, and we eventually found a workaround using lldb's python API. The manual way is to run script, and enter:

options = lldb.SBExpressionOptions()
options.SetTrapExceptions(False)
print lldb.frame.EvaluateExpression('ThisThrowsAndCatches()', options).value

This could be packaged into its own command via command script add.

Dave Lee
  • 6,299
  • 1
  • 36
  • 36
  • (working w/ swift ifacing objc) now, this helped in my wrapper of `expression` but i skipped `.value` and to replicate original's `--object-description` (aka `-O` / `po`) I added `.GetObjectDescription()` in its place, ie `print lldb.frame.EvaluateExpression(expression, options).GetObjectDescription()`. Oddly, this seems to be the only of SBExpressionOptions not controllable by `expression` options (see lldb `help`). – vike Oct 07 '19 at 03:04
3

error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3).. The process has been returned to the state before expression evaluation.

Note that lldb specifically points to the internal breakpoint -3 that caused the interruption.

To see the list of all internal breakpoints, run:

(lldb) breakpoint list --internal
...
Kind: ObjC exception
-3: Exception breakpoint (catch: off throw: on) using: name = 'objc_exception_throw', module = libobjc.A.dylib, locations = 1 
  -3.1: where = libobjc.A.dylib`objc_exception_throw, address = 0x00007ff81bd27be3, unresolved, hit count = 4

Internal breakpoints can be disabled like regular ones:

(lldb) breakpoint disable -3
1 breakpoints disabled.

In case lldb continues getting interrupted you might also need to disable the conditions of the breakpoint:

(lldb) breakpoint disable -3.*
1 breakpoints disabled.

In my particular case there were multiple exception breakpoints I had to disable before I finally got the expected result:

(lldb) breakpoint disable -4 -4.* -5 -5.*
6 breakpoints disabled.
dalazx
  • 149
  • 3