The C-API, debugging, and you!

I’m curious if anyone has had success debugging games written with the C-API and SDK 0.10.1.

The documentation briefly covers debugging and Xcode, but I have a strong suspicion that the information predates Catalina and/or Xcode 11. I reached for the example projects in the C_API tree to validate my setup, but most of those won’t actually build due to obsolete Xcode project settings (32bit targeting, etc) and non-portable paths.

I know I’m largely off the reservation for using C, but I figure it makes sense to surface these problems now for sanding and buffing.

Semi-orthogonally: I’d love instructions for debugging with lldb directly rather than Xcode because it unlocks superpowers for CLion users and archaic Vim luddites.

3 Likes

When compiling for the Playdate simulator, you create a .dylib that has debug symbols. The simulator loads it dynamically from the resulting .pdx. Attaching your debugging to PlaydateSDK/bin/Playdate\ Simulator.app/Contents/MacOS/Playdate\ Simulator when launching you .pdx should allow you to debug your .dylib.

For CLion specifically, the instructions in “Inside Playdate with C” worked without any problems for me. After assigning the simulator binary to my target, I can click the debug button, set breakpoints, inspect variables, etc.

edit: this is on macOS Mojave, I cannot speak for Catalina but this binary and .dylib are definitely 64bit:

$ file pdex.dylib
pdex.dylib: Mach-O 64-bit dynamically linked shared library x86_64
2 Likes

Unfortunately CLion fails to debug in the same manner as Xcode on both of my development machines. The debugger gets a generic error code when attempting to attach to the Playdate Simulator process — the error is consistent between Xcode, CLion, and lldb (which may all just be lldb under the hood?)

I’m charging up a very old pre-Catalina Mac to see if my project will build and debug as-is, but I’d still love to hear if anyone on Catalina is having success where I am not.

TL;DR: this comes down to entitlements, but you can work around them by re-signing the simulator with your own certificate.

I had to update a poor 2015 MBP from High Sierra to Mojave to check whether this is a Catalina-ism — it’s not. Attaching a debugger to the simulator is disallowed on both Mojave and Catalina because the simulator is not signed with the com.apple.security.get-task-allow entitlement. You can get a rough overview here.

@hbehrens is it possible that you’re running an older copy of the simulator binary that was unsigned or signed with different capabilities? I’d be curious to see the output of the following command:

codesign -d --entitlements - ~/Developer/PlaydateSDK/bin/Playdate\ Simulator.app

Panic is in a tough spot here because they can’t ship a notarized simulator binary with this entitlement per Apple restrictions, so the options seem to be:

  • Ship unsigned builds! Let chaos reign!
  • Ship signed but non-notarized builds with the entitlement present.
  • (maybe) Ship a notarized binary with the Hardened Runtime option disabled so that Developer Mode can be used to override the lack of entitlements. I’m not completely sure this would work.
  • Ship a notarized binary; no debugging allowed.

In the meantime, it’s actually possible to re-sign the distributed simulator application with your own certificate and expanded entitlements. I’ll hold off on providing instructions until someone from Panic can weigh-in to avoid starting a cargo cult.

@brandon These issues will be addressed in the next update.

Can you elaborate on what you mean by “non-portable paths”?

Hey @james, I meant Xcodeproj files with references absolute paths like /Users/dave/... that aren’t valid on most developer systems. In fairness, I don’t know that you can resolve $HOME in those fields, but the example projects might be able to use relative paths to be buildable in-place.

(Also: I understand if Xcode-compat for examples is a non-priority, I’d rather not use it!)

I’d be curious to see the output

$ codesign -d --entitlements - ~/Developer/PlaydateSDK/bin/Playdate\ Simulator.app/Contents/MacOS/Playdate\ Simulator
Executable=/Users/behrens/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/Playdate Simulator
��qqE<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.cs.disable-library-validation</key>
	<true/>
	<key>com.apple.security.device.audio-input</key>
	<true/>
</dict>
</plist>

$ ~/Developer/PlaydateSDK/bin/Playdate\ Simulator.app/Contents/MacOS/Playdate\ Simulator 2>&1| head -1
2020-05-21 16:19:22.572 Playdate Simulator[11257:1753931] GIT_COMMIT: 0701adf80845-Release/0.10.1-buildbot

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G4032

$ /usr/sbin/DevToolsSecurity -status
Developer mode is currently enabled.

@hbehrens thanks! I’m even more stymied in that case.

% codesign -d --entitlements - ~/Developer/PlaydateSDK/bin/Playdate\ Simulator.app
Executable=/Users/brandon/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/Playdate Simulator
��qqE<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.cs.disable-library-validation</key>
	<true/>
	<key>com.apple.security.device.audio-input</key>
	<true/>
</dict>
</plist>

% ~/Developer/PlaydateSDK/bin/Playdate\ Simulator.app/Contents/MacOS/Playdate\ Simulator 2>&1 | head -n 1
2020-05-21 16:28:26.070 Playdate Simulator[681:6944] GIT_COMMIT: 0701adf80845-Release/0.10.1-buildbot

% sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G103

% DevToolsSecurity
Developer mode is already enabled.

% lldb ~/Developer/PlaydateSDK/bin/Playdate\ Simulator.app -- HelloWorld.pdx
(lldb) target create "/Users/brandon/Developer/PlaydateSDK/bin/Playdate Simulator.app"
Current executable set to '/Users/brandon/Developer/PlaydateSDK/bin/Playdate Simulator.app' (x86_64).
(lldb) settings set -- target.run-args  "HelloWorld.pdx"
(lldb) run
error: process exited with status -1 (unable to attach)

% lldb ~/Developer/PlaydateSDK/bin/Resigned\ Simulator.app -- HelloWorld.pdx
(lldb) target create "/Users/brandon/Developer/PlaydateSDK/bin/Resigned Simulator.app"
Current executable set to '/Users/brandon/Developer/PlaydateSDK/bin/Resigned Simulator.app' (x86_64).
(lldb) settings set -- target.run-args  "HelloWorld.pdx"
(lldb) run
Process 758 launched: '/Users/brandon/Developer/PlaydateSDK/bin/Resigned Simulator.app/Contents/MacOS/Playdate Simulator' (x86_64)
2020-05-21 16:30:40.308916-0700 Playdate Simulator[758:8170] GIT_COMMIT: 0701adf80845-Release/0.10.1-buildbot
...

Perhaps it’s SIP? Is yours disabled, by chance?

% csrutil status
System Integrity Protection status: enabled.

edit: yes, integrity protection is indeed disabled (odd, as I try to re-enable that each time I make changes that require it)

works for me:

$ lldb --version
lldb-1001.0.13.3
  Swift-5.0

$ lldb ~/Developer/PlaydateSDK/bin/Playdate\ Simulator.app
(lldb) target create "/Users/behrens/Developer/PlaydateSDK/bin/Playdate Simulator.app"
Current executable set to '/Users/behrens/Developer/PlaydateSDK/bin/Playdate Simulator.app' (x86_64).
(lldb) run
Process 12329 launched: '/Users/behrens/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/Playdate Simulator' (x86_64)
2020-05-21 16:49:25.209616-0700 Playdate Simulator[12329:1871093] GIT_COMMIT: 0701adf80845-Release/0.10.1-buildbot
...

Version of lldb should not matter as Clion ships with its own. It sound as if the issue is already understood though

These issues will be addressed in the next update.

Maybe you can shed some light, @james?

As mentioned above, the Simulator is lacking the get-task-allow entitlement. I’ve added that and it will be debuggable in the next SDK release.

3 Likes

Thank you!

(and hi brandon)

1 Like

Is this possible in Nova?