Better error message for attaching to a process already being debugged

Hi,

My colleague is trying to use our lldb IDE attaching to app run/build from Xcode which failed. I can reproduce this with lldb console:

jeffreytan-mbp:$ ps aux | grep iOSApp
jeffreytan 61816 0.0 0.0 2432772 676 s002 S+ 3:00PM 0:00.00 grep iOSApp
jeffreytan 61806 0.0 0.2 2721120 38600 ?? SXs 3:00PM 0:00.24 /Users/jeffreytan/Library/Developer/CoreSimulator/Devices/EF17E202-3981-4DB0-87C9-2A9345C1E713/data/Containers/Bundle/Application/CAEBA7D7-D284-4489-8A53-A88E56F9BB04/iOSAppTest.app/iOSAppTest
jeffreytan-mbp:$ lldb -p 61806
(lldb) process attach --pid 61806
error: attach failed: attach failed: unable to attach

My theory is:

  1. Xcode does not have the concept of run without debugger and run under debugger, so it always run app with debugger enabled.(Is this true?)
  2. And you can’t have two native debuggers debugging the same process on Mac(this is true on Windows, is it true for Mac or Linux?)

If both are true, can we report meaningful message like “inferior is already being debugged” or something similar instead of the generic error message like “attach failed: unable to attach”?

Btw: I found I can still use gdb to attach to the process(with a permission elevation dialog pop-up) and see the callstack. How does gdb do that?

Jeffrey

Did you follow the instructions and you have made your "lldb_codesign" code signing certificate?:

svn cat http://llvm.org/svn/llvm-project/lldb/trunk/docs/code-signing.txt

If you don't do this, your debugserver won't have the ability to debug anything. If you don't want to do this, you can remove the "debugserver" binary from your LLDB.framework that you built and are running with, and then we will fall back to using the one that is installed inside /Applications/Xcode.app as that one is Apple code signed.

Greg

Hi Greg, I am using the lldb(/usr/bin/lldb) installed by Xcode not self-built one. For example, I can use lldb to attach to chrome without any problem. And I can see the debugserver it uses is from “/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/debugserver”. Do I still need to sign it?
Only the app launched from Xcode IDE can’t be attached from this lldb.

Hi,

My colleague is trying to use our lldb IDE attaching to app run/build from Xcode which failed. I can reproduce this with lldb console:

jeffreytan-mbp:$ ps aux | grep iOSApp
jeffreytan 61816 0.0 0.0 2432772 676 s002 S+ 3:00PM 0:00.00 grep iOSApp
jeffreytan 61806 0.0 0.2 2721120 38600 ?? SXs 3:00PM 0:00.24 /Users/jeffreytan/Library/Developer/CoreSimulator/Devices/EF17E202-3981-4DB0-87C9-2A9345C1E713/data/Containers/Bundle/Application/CAEBA7D7-D284-4489-8A53-A88E56F9BB04/iOSAppTest.app/iOSAppTest
jeffreytan-mbp:$ lldb -p 61806
(lldb) process attach --pid 61806
error: attach failed: attach failed: unable to attach

My theory is:
1. Xcode does not have the concept of run without debugger and run under debugger, so it always run app with debugger enabled.(Is this true?)

That is not true. In the Run Scheme, uncheck the "Debug Executable" checkbox. But running with the debugger is the default.

Note, an X in the status field for ps means the app is being debugged. So in this case, the app you were trying to attach to WAS already being debugged.

2. And you can't have two native debuggers debugging the same process on Mac(this is true on Windows, is it true for Mac or Linux?)

That is true for Mac, and in general for ptrace based debugging. I don't know much about procfs.

If both are true, can we report meaningful message like "inferior is already being debugged" or something similar instead of the generic error message like "attach failed: unable to attach"?

That should be possible, there's code to eliminate already debugged processes in the "Attach to process by name" functionality. So if you specify a PID and the attach fails, we could check after the fact and see if it is already being traced. Please file a bug for this, and/or take a whack at fixing it if you feel like it.

Btw: I found I can still use gdb to attach to the process(with a permission elevation dialog pop-up) and see the callstack. How does gdb do that?

I haven't looked at the FSF gdb OS X support for years, so I can't really comment on it. But it is not possible to ptrace something that is already ptraced, so if gdb is still doing it this way, then it should also fail. Maybe it is only getting the mach task and exception ports and debugging just with them? You can have multiple readers for the task port, and you can steal the exception port from someone else. But if it did that, the other debugger should stop working.

Jim

Thanks for the info Jim. That answers my questions. I will file a bug for lldb error message.

Hi Greg, I am using the lldb(/usr/bin/lldb) installed by Xcode not self-built one. For example, I can use lldb to attach to chrome without any problem. And I can see the debugserver it uses is from "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/debugserver". Do I still need to sign it?

No, this one is code signed with an Apple certificate which is trusted by the system.

Only the app launched from Xcode IDE can't be attached from this lldb.

Try using "xcrun lldb" instead of /usr/bin/lldb.