po $arg1 no longer working in Xode 6.4

I had set a breakpoint on objc_exception_throw, and added the debugger command po $arg1 (as mentioned in the latest WWDC, or http://natashatherobot.com/xcode-debugging-trick/


For a while it worked great, but I recently updated Xcode and now I get


error: use of undeclared identifier '$arg1'

Is there a new way to get the actual exception when you hit it?

This is working for me in Xcode 6.4. Perhaps it's a platform-specific issue. I was testing an iOS app in the iPhone 6 simulator. What are you testing?

Share and Enjoy

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

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

Po $arg1 work on iOS 8 Simulator


and crash on iOS 7.1 Simulaotor when using Xcode 6.4.



error: use of undeclared identifier '$arg1'

error: 1 errors parsing expression


That's how it should be or a bug ?

and crash on iOS 7.1 Simulaotor when using Xcode 6.4.

In my testing it works with the 7.1 simulator if you target a 64-bit CPU (like iPhone 5s) but fails, as you’ve described, when targeting a 32-bit CPU.

I suspect you’re being bitten by a limitation of

$arg1
, namely, that it always maps to a register. On i386, which is what the 32-bit simulator uses, parameters are passed on the stack, not in a registers, and thus aren’t available via
$argXXX
notation. Rather, you have to dump the stack and work things out from there.

Here’s an example, assuming you’re stopped at the first instruction of

objc_exception_throw
:
(lldb) po $arg1
error: use of undeclared identifier '$arg1'
error: 1 errors parsing expression
(lldb) # Dump 8 4-bit words in hex from the top of the stack.
(lldb) m r -c 8 -s 4 -f x $esp
0xbff3454c: 0x007d5fbb 0x79c55090 0x008de3d0 0x000cc038
0xbff3455c: 0x79c55110 0x00000000 0x008dd82c 0x0091b940
(lldb) # The first word is the return address; the second is the first
(lldb) # parameter, so dump that.
(lldb) po 0x79c55090
test
(lldb) # Alternatively, calculate its value using C-style code.
(lldb) po *(void **)($esp+4)
test

Share and Enjoy

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

let myEmail = "eskimo" + "1" + "@apple.com"
Four years later (2020) this is a different problem with a different fix (at least in my experience).

I work almost entirely in Objective-C, writing apps for iOS. For years I've had the command
Code Block
po $arg1

saved as a user breakpoint so that when Xcode threw an exception it would print the exception message to its console.

At some point after I began using Xcode 11, this started failing with the message
Code Block
Stopped due to an error evaluating condition of breakpoint 1.1: "po $arg1"
Couldn't parse conditional expression:
error: use of undeclared identifier 'po'

After a fresh dive into the Googleverse today, I stumbled upon an answer.

Xcode 11's debugger stops with its stack-view selection on the line of my code that threw the exception
Code Block
[self.termsVC.presentingVC presentViewController:nav animated:YES completion:nil];

Here 'po $arg1' fails as I've described (for me).

If I select the top line in the stack view (in the exception code, where the debugger is actually stopped)
Code Block
objc_exception_throw

and repeat the command, it works as before
Code Block
(lldb) po $arg1
The specified modal presentation style doesn't have a corresponding presentation controller.

Yet Xcode's stack view was always selecting my code, not the exception code. That hasn't changed. What changed was Xcode 11's ability to evaluate "po $arg1" from that line.

Details: MacBook Pro (13-inch 2019), 16GB RAM, macOS Mojave 10.14.6, Xcode 11.3.1. Both iOS Simulator and devices.

Happens both in new projects created with Xcode 11 and older projects created with Xcode 9 and earlier. Was happening in earlier versions of Xcode 11 and in earlier versions of Mojave. Not yet tested in Catalina.


I tried reproducing your problem today and couldn’t. I can’t run the exact steps you reported because I don’t have your view controllers and so on. Instead I did the following:
  1. Using Xcode 11.5 on macOS 10.15.5, I created a new project from the iOS > Application > Single View App template.

  2. I added a Test button to the main view controller and wired it up to the code pasted in at the end of this post.

  3. In the Breakpoint navigator (View > Navigators > Show Breakpoint Navigator) I clicked the add (+) button at the bottom left and chose Exception Breakpoint.

  4. In the breakpoint editor, I clicked Add Action.

  5. This defaults to adding a Debugger Command action, whereupon I entered po $arg1.

  6. I ran the app on the iOS 13.5 simulator.

  7. I clicked the Test button.

I stopped in the debugger and in the Xcode console (View > Debug Areas > Activate Console) I saw this:

Code Block
*** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: abc)


Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"



Code Block
- (IBAction)testAction:(id)sender {
#pragma unused(sender)
NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
[dict setObject:nil forKey:@"abc"];
}

Found the answer. Operator error. (Of course.)

Xcode's exception-breakpoints editor changed in version 11. It added a 'Condition' file that was not present in Xcode 10.

The new field is highlighted on open. The text cursor is blinking. It commands your attention. (A screenshot would help here.)

Entering 'po $arg1' here looks so similar to what I recall from past Xcodes that I failed to recognize this is not where it belongs.

And the misplaced command behaves as I've described. Unrecognized when an exception is throw, recognized when I move the stack selection to the exception code itself.

So the fix is, as you described, clicking the 'Add Action' button and entering 'po $arg1' as a new Debugger Command.

Thanks for your help, Quinn.

The text cursor is blinking. It commands your attention.

Yeah, I’ve made that mistake myself numerous times!

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Xcode 13.2.1 the problem still exists (swift code): why? :(

`po $arg1
error: <EXPR>:8:1: error: cannot find '$arg1' in scope
$arg1
^~~~~
(lldb) register read -A
General Purpose Registers:
       rax = 0x0000000000000036
       rbx = 0x00007fa8a0f081e0
      arg4 = 0x0000000000000000
      arg3 = 0x0000000000000000
      arg1 = 0x00007fa8a0f081e0
      arg2 = 0x00007fff6dd7499e
        fp = 0x00007ffeef3b6f30
        sp = 0x00007ffeef3b6f20
      arg5 = 0x00007fff864a40a0  libsystem_pthread.dylib`_pthread_keys
      arg6 = 0x00007fa8a483bc90
       r10 = 0x00000001008562a8  (void *)0x0000000100857588: _TtC6***29XXXViewController
       r11 = 0x00007fff248cd65c  UIKitCore`-[UIViewController(UIKitManual) release]
       r12 = 0x0000000000000278
       r13 = 0x00007fa8a0f081e0
       r14 = 0x0000000000000000
       r15 = 0x00007fff201833c0  libobjc.A.dylib`objc_msgSend
        pc = 0x000000010084a8e4  ***`***.***.Controller.setup() -> () + 20 at ViewController.swift:33:9
     flags = 0x0000000000000202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000
(lldb) po $arg1
error: <EXPR>:8:1: error: cannot find '$arg1' in scope
$arg1

^~~~~`

Xcode 13.2.1 the problem still exists

That’s not my experience. I reran my earlier test on the latest systems and it worked as expected. Specifically:

  1. Using Xcode 13.2.1 on macOS 12.1, I created a new project from the iOS > App template, selecting Storyboard as the UI.

  2. I added a Test button to the main view controller and wired it up to this code:

    @IBAction
    private func testAction(_ sender: Any) {
        let array = NSArray()
        _ = array.object(at: -1)
    }
    

    This is different from the previous Objective-C code because Swift makes it hard to misuse NSDictionary (-:

  3. In the Breakpoint navigator (View > Navigators > Show Breakpoint Navigator) I clicked the add (+) button at the bottom left and chose Exception Breakpoint.

  4. In the breakpoint editor, I clicked Add Action.

  5. I switched this to a Debugger Command action and entered po $arg1.

  6. I ran the app on the iOS 15.2 simulator.

  7. I clicked the Test button. The app stopped at my breakpoint and printed:

    *** -[__NSArray0 objectAtIndex:]: index 18446744073709551615 beyond bounds for empty NSArray
    

Please run through these steps in your environment and let me know what you see.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

po $arg1 no longer working in Xode 6.4
 
 
Q