SBTarget::AttachToProcessWithID hangs

I am trying to attach to a stopped process on our dsp target using the SBTarget interface but the call hangs.
What I understand is that it is waiting for events on the “lldb.process” broadcaster using the “lldb.Target.Attach.attach.hijack” listener.

Enabling the logs, I see that the process is attached successfully and that the stop event is generated. It just seems that the event is not seen by the listener.

1442428969.321000000 004B9590 Listener::WaitForEventsInternal (timeout = { 00000000 }) for lldb.Target.Attach.attach.hijack
1442428969.321000000 004BC7F4 Broadcaster(“opus.remote”)::BroadcastEvent (event_sp = {00A72050 Event: broadcaster = 004BC7F4 (opus.remote), type = 0x00010000, data = }, unique =0) hijack = 00000000
1442428969.341000000 0049AC50 Broadcaster(“lldb.target”)::BroadcastEvent (event_sp = {00A70C78 Event: broadcaster = 0049AC50 (lldb.target), type = 0x00000002 (modules-loaded), data = {}}, unique =0) hijack = 00000000
1442428969.341000000 004BC7F4 Broadcaster(“opus.remote”)::BroadcastEvent (event_sp = {00A723C8 Event: broadcaster = 004BC7F4 (opus.remote), type = 0x00010000, data = }, unique =0) hijack = 00000000
1442428969.450000000 004BC394 Broadcaster(“lldb.process.internal_state_broadcaster”)::BroadcastEvent (event_sp = {00A723C8 Event: broadcaster = 004BC394 (lldb.process.internal_state_broadcaster), type = 0x00000001, data = { process = 004BC308 (pid = 1), state = stopped}}, unique =0) hijack = 00000000
1442428969.452000000 004BC42C Listener(‘lldb.process.internal_state_listener’)::AddEvent (event_sp = {00A723C8})
1442428969.453000000 031CF700 Listener::WaitForEventsInternal (timeout = { 00000000 }) for ProcessOpusRemote::AsyncThread
1442428969.453000000 004BC42C ‘lldb.process.internal_state_listener’ Listener::FindNextEventInternal(broadcaster=00000000, broadcaster_names=00000000[0], event_type_mask=0x00000000, remove=1) event 00A723C8
1442428969.459000000 0309F8D4 Listener::StartListeningForEvents (broadcaster = 004BC5F4, mask = 0x00000020) acquired_mask = 0x00000020 for Communication::SyncronizeWithReadThread
1442428969.470000000 Process::ShouldBroadcastEvent (00A723C8) => new state: stopped, last broadcast state: stopped - YES
1442428969.471000000 004BC318 Broadcaster(“lldb.process”)::BroadcastEvent (event_sp = {00A723C8 Event: broadcaster = 004BC318 (lldb.process), type = 0x00000001(state-changed), data = { process = 004BC308 (pid = 1), state = stopped}}, unique =0) hijack = 00000000
1442428969.473000000 00402598 Listener(‘lldb.Debugger’)::AddEvent (event_sp = {00A723C8})
1442428969.474000000 004BC42C Listener::WaitForEventsInternal (timeout = { 00000000 }) for lldb.process.internal_state_listener

Here’s the code I use to attach.

SBDebugger::Initialize();

SBDebugger debugger = lldb::SBDebugger::Create(false);

debugger.SetAsync(true);

const char* categories = { “process”, “events”, 0 };
if (!debugger.EnableLog(“lldb”, categories))
return -1;

pid_t pid = 1;

SBTarget target = debugger.CreateTargetWithFileAndArch(elffile_name, “opus2”);

SBError error;
SBListener listener(“test_listener”);

SBProcess process = target.AttachToProcessWithID(listener, pid, error);

if (!process.IsValid())
{

I would be grateful for any insight on the cause of this behavior.

Thanks,
-Philippe

Did you try waiting for an event on the listener you've passed to AttachToProcess? The last event after everything is done should be the notification to the public listener (i.e. your test_listener) that the process you attached to has stopped, and nobody is fetching that.

Jim

A few questions:

Which process plug-in does your debugging target use?
Is it a GDB Remote based debug session?
   If so is it using lldb-server?
   a custom GDB server?

In general, we expect to receive a eStateStopped process event if the attach is successful and this is what we are waiting for. If you have a custom Process subclass, you will need to make sure you stop your target and broadcast a eStateStopped event. If you are using GDB remote, please enable logging with the following line before calling AttachToProcessWithID:

debugger.HandleCommand("log enable -f /tmp/packets.txt gdb-remote packets");

Then run and watch things fail, and attach the log.

Greg Clayton

It is a custom process plug-in using a proprietary protocol to communicate with the debug target.

In the process plugin's AsyncThread, I set the process private state to eStateStopped by calling process->SetPrivateState.
Is it enough to broadcast the state change?

The event is in the events log:

1442428969.471000000 004BC318 Broadcaster("lldb.process")::BroadcastEvent (event_sp = {00A723C8 Event: broadcaster = 004BC318 (lldb.process), type = 0x00000001(state-changed), data = { process = 004BC308 (pid = 1), state = stopped}}, unique =0) hijack = 00000000

-Philippe

It is the AttachToProcessWithID that hangs and never returns, so I cannot use my listener yet.

-Philippe

Here is the output of attaching to a process with ProcessGDBRemote:

(lldb) log enable lldb state
(lldb) attach 12406
Process::SetPublicState (state = attaching, restarted = 0)
Process::SetPrivateState (stopped)
Process::SetPrivateState (stopped) stop_id = 1
Process::SetPublicState (state = stopped, restarted = 0)
Process 12406 stopped
* thread #1: tid = 0x6f2673, 0x00007fff99688682 libsystem_kernel.dylib read + 10, stop reason = signal SIGSTOP, queue = com.apple.main-thread
    frame #0: 0x00007fff99688682 libsystem_kernel.dylib read + 10
libsystem_kernel.dylib`read:
-> 0x7fff99688682 <+10>: jae 0x7fff9968868c ; <+20>
    0x7fff99688684 <+12>: movq %rax, %rdi
    0x7fff99688687 <+15>: jmp 0x7fff99682c78 ; cerror
    0x7fff9968868c <+20>: retq

So we see the public state was set to eStateAttaching and then it was set to eStateStopped. Try this out and let me know what you are seeing.

Greg

I am missing the final SetPublicState call.

1442509021.490000000 Process::SetPrivateState (connected)
1442509021.492000000 Process::SetPublicState (state = attaching, restarted = 0)
1442509021.627000000 Process::SetPrivateState (stopped)
1442509021.628000000 Process::SetPrivateState (stopped) stop_id = 1

This sounds like you don't have a private state thread running. The private state thread watches for private state changes in Process and promotes them into public state changes as needed. Can you check if Process::PrivateStateThread() is running? This should be triggered by a call to StartPrivateStateThread() in "Error Process::Attach(ProcessAttachInfo &)".

Greg

Ah! The issue was in my custom Platform's Attach. It is based on PlatformGDB, but it seems I bulldozed through a little too fast.

I was missing a call to Process::HijackProcessEvents before calling Process::Attach

            auto listener = attach_info.GetHijackListener();
            if (listener != nullptr)
              process_sp->HijackProcessEvents(listener.get());

Thanks,
-Philippe

Yep, that'll do it!

Are you up and running now?

Yes, it is working now. I can set breakpoints, step, wait for events, etc.

Thanks for your help!

-Philippe