How to debug a native application on MacOS

I’m working on a new project and am trying to do native unit testing of shared code.

Environment details

MacOS 11.6.2
VSCode: 1.63.2
PlatformIO extension: 2.4.0
PlatformIO Core: 5.2.4

Getting the unit test project set up and building was straightforward enough, but trying to debug in VSCode is proving very difficult.

I’ve installed gdb from Homebrew, and changed my project environment to be ‘native’. However, whenever I try to start a debugging session I get an error like this:

Processing native (platform: native)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 1 compatible libraries
Scanning dependencies...
Building in debug mode
Reading symbols from /XXX/.pio/build/native/program...
Warning: 'set target-async', an alias for the command 'set mi-async', is deprecated.
Use 'set mi-async'.
PlatformIO Unified Debugger -> https://bit.ly/pio-debug
PlatformIO: debug_tool = None
PlatformIO: Initializing remote target...
Temporary breakpoint 1 at 0x100004ec4: file test/test_native/main.cpp, line 6.
PlatformIO: Initialization completed
PlatformIO: Resume the execution to `debug_init_break = tbreak main`
PlatformIO: More configuration options -> https://bit.ly/pio-debug
Unable to find Mach task port for process-id XXXX: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))

I see similar errors if using pio debug -e native --interface gdb

I tried the obvious fix here (code signing gdb with a self-signed certificate), but that doesn’t actually resolve the issue. Trying a hack where I symlink gdb to lldb doesn’t work either as lldb uses different command line options.

Has anybody actually been able to get this kind of native debugging working in PlatformIO on a Mac?

I’m going to answer my own question here since I think I finally figured it out.

I wasn’t signing gdb properly. The steps I had been following on line weren’t up-to-date with the moving target that is MacOS’s security requirements.

The command I had been running:
codesign -fs gdb_codesign $(which gdb)

Doesn’t seem to be enough.

What I needed to do was to create an entitlement XML with text like this:

<?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.debugger</key>
    <true/>
  </dict>
</plist>

And then run this command to codesign gdb:
codesign --entitlements gdb-entitlement.xml -fs gdb_codesign $(which gdb)

Finally, I’m able to get the integrated debugging experience in VSCode on MacOS with my native project.

1 Like