Thanks @eskimo for your detailed help on these topics, here and elsewhere. I think it is worth mentioning that (at least on Big Sur) the reason why the debuggee wants com.apple.security.get-task-allow, is that in the lldb workflow, there is no run vs. attach distinction (in gdb parlance) — lldb always wants to attach to an already-running process (through its debugserver helper).
I determined experimentally today¹ that gdb only needs the com.apple.security.cs.debugger in order to debug a process that it starts up itself (presumably corresponding to the is a declared debugger verbiage in the kernel logs). However, lldb never does that; instead, it runs the process un-debugged and then attempts to have something called debugserver attach to it — As it turns out, debugserver also has com.apple.security.cs.debugger entitlement (as it should).
As that would enable something called a lateral-move attack, attaching to an already-running process is an operation that is obviously more appealing to malware than creating a subprocess (which is unlikely to gain privilege) and debugging it; therefore it makes sense that that action requires additional checks, i.e. an com.apple.security.get-task-allow signed entitlement on the target (the debuggee, not the debugger) — Under the justification that one should only want to (attach to and) debug programs that one wrote oneself.
Long story short — This works:
shell
cat debuggee-entitlement.xml ENTITLEMENT
?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
keycom.apple.security.get-task-allow/key
true/
/dict
/plist
ENTITLEMENT
codesign --entitlements debuggee-entitlement.xml -fs gdb-cert ./ls
lldb ./ls
(where gdb-cert should be replaced with the name of whichever certificate you usually sign code with)
¹ I did run into more bugs though, e.g. 24069 which I unfortunately cannot seem to link to here — Different story.