Skip to content

Commit

Permalink
Merge pull request #214 from cuviper/attach-thread-sync
Browse files Browse the repository at this point in the history
proccontrol: Synchronize additional threads found during attach
  • Loading branch information
wrwilliams committed Nov 10, 2016
2 parents a79ba00 + 897f0c4 commit 09e5827
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 7 deletions.
3 changes: 3 additions & 0 deletions proccontrol/src/int_process.h
Expand Up @@ -271,7 +271,10 @@ class int_process
static bool reattach(int_processSet *pset);
virtual bool plat_attach(bool allStopped, bool &should_sync) = 0;

bool attachThreads(bool &found_new_threads);
bool attachThreads();
virtual bool plat_attachThreadsSync();

virtual async_ret_t post_attach(bool wasDetached, std::set<response::ptr> &aresps);
async_ret_t initializeAddressSpace(std::set<response::ptr> &async_responses);

Expand Down
38 changes: 38 additions & 0 deletions proccontrol/src/linux.C
Expand Up @@ -1110,6 +1110,44 @@ bool linux_process::plat_attach(bool, bool &)
return true;
}

// Attach any new threads and synchronize, until there are no new threads
bool linux_process::plat_attachThreadsSync()
{
while (true) {
bool found_new_threads = false;

ProcPool()->condvar()->lock();
bool result = attachThreads(found_new_threads);
if (found_new_threads)
ProcPool()->condvar()->broadcast();
ProcPool()->condvar()->unlock();

if (!result) {
pthrd_printf("Failed to attach to threads in %d\n", pid);
setLastError(err_internal, "Could not get threads during attach\n");
return false;
}

if (!found_new_threads)
return true;

while (Counter::processCount(Counter::NeonatalThreads, this) > 0) {
bool proc_exited = false;
pthrd_printf("Waiting for neonatal threads in process %d\n", pid);
result = waitAndHandleForProc(true, this, proc_exited);
if (!result) {
perr_printf("Internal error calling waitAndHandleForProc on %d\n", getPid());
return false;
}
if (proc_exited) {
perr_printf("Process exited while waiting for user thread stop, erroring\n");
setLastError(err_exited, "Process exited while thread being stopped.\n");
return false;
}
}
}
}

bool linux_process::plat_attachWillTriggerStop() {
char procName[64];
char cmd[256];
Expand Down
1 change: 1 addition & 0 deletions proccontrol/src/linux.h
Expand Up @@ -111,6 +111,7 @@ class linux_process : public sysv_process, public unix_process, public thread_db
virtual bool plat_create();
virtual bool plat_create_int();
virtual bool plat_attach(bool allStopped, bool &);
virtual bool plat_attachThreadsSync();
virtual bool plat_attachWillTriggerStop();
virtual bool plat_forked();
virtual bool plat_execed();
Expand Down
33 changes: 26 additions & 7 deletions proccontrol/src/process.C
Expand Up @@ -211,8 +211,10 @@ void int_process::plat_threadAttachDone()
{
}

bool int_process::attachThreads()
bool int_process::attachThreads(bool &found_new_threads)
{
found_new_threads = false;

if (!needIndividualThreadAttach())
return true;

Expand All @@ -224,9 +226,9 @@ bool int_process::attachThreads()
* a list of LWPs, but then new threads are created before we attach to
* all the existing threads.
**/
bool found_new_threads;
bool loop_new_threads;
do {
found_new_threads = false;
loop_new_threads = false;
vector<Dyninst::LWP> lwps;
bool result = getThreadLWPs(lwps);
if (!result) {
Expand All @@ -242,10 +244,28 @@ bool int_process::attachThreads()
}
pthrd_printf("Creating new thread for %d/%d during attach\n", pid, *i);
thr = int_thread::createThread(this, NULL_THR_ID, *i, false, int_thread::as_needs_attach);
found_new_threads = true;
found_new_threads = loop_new_threads = true;
}
} while (found_new_threads);
} while (loop_new_threads);

return true;
}

bool int_process::attachThreads()
{
bool found_new_threads = false;
return attachThreads(found_new_threads);
}

bool int_process::plat_attachThreadsSync()
{
// By default, platforms just call the idempotent attachThreads().
// Some platforms may override, e.g. Linux should sync with all threads.
if (!attachThreads()) {
pthrd_printf("Failed to attach to threads in %d\n", pid);
setLastError(err_internal, "Could not get threads during attach\n");
return false;
}
return true;
}

Expand Down Expand Up @@ -443,10 +463,9 @@ bool int_process::attach(int_processSet *ps, bool reattach)
int_process *proc = *i;
if (proc->getState() == errorstate)
continue;
bool result = proc->attachThreads();
bool result = proc->plat_attachThreadsSync();
if (!result) {
pthrd_printf("Failed to attach to threads in %d--now an error\n", proc->pid);
proc->setLastError(err_internal, "Could not get threads during attach\n");
procs.erase(i++);
had_error = true;
continue;
Expand Down

0 comments on commit 09e5827

Please sign in to comment.