Backport fixes for rhbz1373197, attach thread races.
This commit is contained in:
parent
eafaeab37f
commit
211f9c452c
526
dyninst-9.2.0-proccontrol-thread-races.patch
Normal file
526
dyninst-9.2.0-proccontrol-thread-races.patch
Normal file
@ -0,0 +1,526 @@
|
||||
Backported fixes for rhbz1373197 / issue208
|
||||
* https://bugzilla.redhat.com/show_bug.cgi?id=1373197
|
||||
* https://github.com/dyninst/dyninst/issues/208
|
||||
|
||||
* https://github.com/dyninst/dyninst/pull/212
|
||||
* https://github.com/dyninst/dyninst/pull/214
|
||||
* https://github.com/dyninst/dyninst/pull/259
|
||||
* https://github.com/dyninst/dyninst/pull/261
|
||||
|
||||
|
||||
commit 251b5549217f716c5ad11509417b3f780d54114c
|
||||
Author: Matthew LeGendre <legendre1@llnl.gov>
|
||||
Date: Tue Oct 25 16:13:05 2016 -0700
|
||||
|
||||
Fix errors when thread disappears during attach
|
||||
|
||||
diff --git a/proccontrol/src/linux.C b/proccontrol/src/linux.C
|
||||
index 4502e357f79f..c55295d836ed 100644
|
||||
--- a/proccontrol/src/linux.C
|
||||
+++ b/proccontrol/src/linux.C
|
||||
@@ -1012,17 +1012,28 @@ bool linux_process::plat_getOSRunningStates(std::map<Dyninst::LWP, bool> &runnin
|
||||
snprintf(proc_stat_name, 128, "/proc/%d/stat", *i);
|
||||
FILE *sfile = fopen(proc_stat_name, "r");
|
||||
|
||||
- if (sfile == NULL) {
|
||||
+ if (*i == getPid() && sfile == NULL) {
|
||||
pthrd_printf("Failed to open /proc/%d/stat file\n", *i);
|
||||
setLastError(err_noproc, "Failed to find /proc files for debuggee");
|
||||
return false;
|
||||
}
|
||||
- if( fread(sstat, 1, 256, sfile) == 0 ) {
|
||||
+ else if (sfile == NULL) {
|
||||
+ //thread died between the above getThreadLWPs and the /proc/pid/stat open
|
||||
+ // just drop it from the to-attach list.
|
||||
+ continue;
|
||||
+ }
|
||||
+ size_t result = fread(sstat, 1, 256, sfile);
|
||||
+ if (*i == getPid() && result == 0) {
|
||||
pthrd_printf("Failed to read /proc/%d/stat file \n", *i);
|
||||
setLastError(err_noproc, "Failed to find /proc files for debuggee");
|
||||
fclose(sfile);
|
||||
return false;
|
||||
}
|
||||
+ else if (result == 0) {
|
||||
+ fclose(sfile);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
fclose(sfile);
|
||||
|
||||
sstat[255] = '\0';
|
||||
|
||||
commit 6c690a487a18798dac1bf663e027a3e21354418a
|
||||
Author: Josh Stone <jistone@redhat.com>
|
||||
Date: Fri Oct 28 18:09:16 2016 -0700
|
||||
|
||||
proccontrol: refactor plat_getOSRunningStates
|
||||
|
||||
- The file is now opened with ifstream for RAII.
|
||||
- The former paren_level logic is removed to instead scan for ") R ".
|
||||
(If there were parens in the command, they might not be balanced!)
|
||||
|
||||
diff --git a/proccontrol/src/linux.C b/proccontrol/src/linux.C
|
||||
index c55295d836ed..56ac407bad1c 100644
|
||||
--- a/proccontrol/src/linux.C
|
||||
+++ b/proccontrol/src/linux.C
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <iostream>
|
||||
+#include <fstream>
|
||||
|
||||
#include "common/h/dyn_regs.h"
|
||||
#include "common/h/dyntypes.h"
|
||||
@@ -1004,51 +1005,38 @@ bool linux_process::plat_getOSRunningStates(std::map<Dyninst::LWP, bool> &runnin
|
||||
for(vector<Dyninst::LWP>::iterator i = lwps.begin();
|
||||
i != lwps.end(); ++i)
|
||||
{
|
||||
+ const auto ignore_max = std::numeric_limits<std::streamsize>::max();
|
||||
char proc_stat_name[128];
|
||||
- char sstat[256];
|
||||
- char *status;
|
||||
- int paren_level = 1;
|
||||
|
||||
snprintf(proc_stat_name, 128, "/proc/%d/stat", *i);
|
||||
- FILE *sfile = fopen(proc_stat_name, "r");
|
||||
+ ifstream sfile(proc_stat_name);
|
||||
|
||||
- if (*i == getPid() && sfile == NULL) {
|
||||
- pthrd_printf("Failed to open /proc/%d/stat file\n", *i);
|
||||
- setLastError(err_noproc, "Failed to find /proc files for debuggee");
|
||||
- return false;
|
||||
- }
|
||||
- else if (sfile == NULL) {
|
||||
- //thread died between the above getThreadLWPs and the /proc/pid/stat open
|
||||
- // just drop it from the to-attach list.
|
||||
- continue;
|
||||
- }
|
||||
- size_t result = fread(sstat, 1, 256, sfile);
|
||||
- if (*i == getPid() && result == 0) {
|
||||
- pthrd_printf("Failed to read /proc/%d/stat file \n", *i);
|
||||
- setLastError(err_noproc, "Failed to find /proc files for debuggee");
|
||||
- fclose(sfile);
|
||||
- return false;
|
||||
- }
|
||||
- else if (result == 0) {
|
||||
- fclose(sfile);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- fclose(sfile);
|
||||
+ while (sfile.good()) {
|
||||
|
||||
- sstat[255] = '\0';
|
||||
- status = sstat;
|
||||
+ // The stat looks something like: 123 (command) R 456...
|
||||
+ // We'll just look for the ") R " part.
|
||||
+ if (sfile.ignore(ignore_max, ')').peek() == ' ') {
|
||||
+ char space, state;
|
||||
|
||||
- while (*status != '\0' && *(status++) != '(') ;
|
||||
- while (*status != '\0' && paren_level != 0) {
|
||||
- if (*status == '(') paren_level++;
|
||||
- if (*status == ')') paren_level--;
|
||||
- status++;
|
||||
- }
|
||||
+ // Eat the space we peeked and grab the state char.
|
||||
+ if (sfile.get(space).get(state).peek() == ' ') {
|
||||
+ // Found the state char -- 'T' means it's already stopped.
|
||||
+ runningStates.insert(make_pair(*i, (state != 'T')));
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- while (*status == ' ') status++;
|
||||
+ // Restore the state char and try again
|
||||
+ sfile.unget();
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- runningStates.insert(make_pair(*i, (*status != 'T')));
|
||||
+ if (!sfile.good() && (*i == getPid())) {
|
||||
+ // Only the main thread is treated as an error. Other threads may
|
||||
+ // have exited between getThreadLWPs and /proc/pid/stat open or read.
|
||||
+ pthrd_printf("Failed to read /proc/%d/stat file\n", *i);
|
||||
+ setLastError(err_noproc, "Failed to find /proc files for debuggee");
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
commit f95c058505eb606e0e2f0ce47d0dcf6990bc41ff
|
||||
Author: Josh Stone <jistone@redhat.com>
|
||||
Date: Fri Nov 4 18:31:28 2016 -0700
|
||||
|
||||
proccontrol: Synchronize additional threads found during attach
|
||||
|
||||
When additional threads are found during the attach process, we should
|
||||
synchronize to their stopping point, and check for new threads again,
|
||||
until no new threads are found. This keeps a more consistent state if
|
||||
threads are racing to start while we're attaching.
|
||||
|
||||
diff --git a/proccontrol/src/int_process.h b/proccontrol/src/int_process.h
|
||||
index f389175a0a13..20a8648a79ea 100644
|
||||
--- a/proccontrol/src/int_process.h
|
||||
+++ b/proccontrol/src/int_process.h
|
||||
@@ -271,7 +271,9 @@ 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();
|
||||
+ bool attachThreadsSync();
|
||||
virtual async_ret_t post_attach(bool wasDetached, std::set<response::ptr> &aresps);
|
||||
async_ret_t initializeAddressSpace(std::set<response::ptr> &async_responses);
|
||||
|
||||
diff --git a/proccontrol/src/process.C b/proccontrol/src/process.C
|
||||
index d231e9ee6d36..c6b0dad80e25 100644
|
||||
--- a/proccontrol/src/process.C
|
||||
+++ b/proccontrol/src/process.C
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
@@ -242,13 +244,56 @@ 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);
|
||||
+}
|
||||
+
|
||||
+// Attach any new threads and synchronize, until there are no new threads
|
||||
+bool int_process::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;
|
||||
+
|
||||
+ pthrd_printf("Wait again for attach from process %d\n", pid);
|
||||
+ bool proc_exited = false;
|
||||
+ result = waitAndHandleForProc(true, this, proc_exited);
|
||||
+ if (!result) {
|
||||
+ perr_printf("Internal error calling waitAndHandleForProc on %d\n", getPid());
|
||||
+ setLastError(err_internal, "Error while calling waitAndHandleForProc for attached threads\n");
|
||||
+ 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 int_process::attach(int_processSet *ps, bool reattach)
|
||||
{
|
||||
bool had_error = false, should_sync = false;
|
||||
@@ -443,10 +488,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->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;
|
||||
|
||||
commit 7041993caa9d022eac7b17018ddd3daa5cfe0696
|
||||
Author: Josh Stone <jistone@redhat.com>
|
||||
Date: Wed Nov 9 18:13:28 2016 -0800
|
||||
|
||||
proccontrol: move thread sync to linux_process, and count neonatal
|
||||
|
||||
diff --git a/proccontrol/src/int_process.h b/proccontrol/src/int_process.h
|
||||
index 20a8648a79ea..0c292f297b2a 100644
|
||||
--- a/proccontrol/src/int_process.h
|
||||
+++ b/proccontrol/src/int_process.h
|
||||
@@ -273,7 +273,8 @@ class int_process
|
||||
|
||||
bool attachThreads(bool &found_new_threads);
|
||||
bool attachThreads();
|
||||
- bool attachThreadsSync();
|
||||
+ 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);
|
||||
|
||||
diff --git a/proccontrol/src/linux.C b/proccontrol/src/linux.C
|
||||
index 56ac407bad1c..f230967af034 100644
|
||||
--- a/proccontrol/src/linux.C
|
||||
+++ b/proccontrol/src/linux.C
|
||||
@@ -1113,6 +1113,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];
|
||||
diff --git a/proccontrol/src/linux.h b/proccontrol/src/linux.h
|
||||
index 4972fb71143f..56326ad9e6a8 100644
|
||||
--- a/proccontrol/src/linux.h
|
||||
+++ b/proccontrol/src/linux.h
|
||||
@@ -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();
|
||||
diff --git a/proccontrol/src/process.C b/proccontrol/src/process.C
|
||||
index c6b0dad80e25..945bc35744ba 100644
|
||||
--- a/proccontrol/src/process.C
|
||||
+++ b/proccontrol/src/process.C
|
||||
@@ -257,41 +257,16 @@ bool int_process::attachThreads()
|
||||
return attachThreads(found_new_threads);
|
||||
}
|
||||
|
||||
-// Attach any new threads and synchronize, until there are no new threads
|
||||
-bool int_process::attachThreadsSync()
|
||||
+bool int_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;
|
||||
-
|
||||
- pthrd_printf("Wait again for attach from process %d\n", pid);
|
||||
- bool proc_exited = false;
|
||||
- result = waitAndHandleForProc(true, this, proc_exited);
|
||||
- if (!result) {
|
||||
- perr_printf("Internal error calling waitAndHandleForProc on %d\n", getPid());
|
||||
- setLastError(err_internal, "Error while calling waitAndHandleForProc for attached threads\n");
|
||||
- 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;
|
||||
- }
|
||||
+ // 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;
|
||||
}
|
||||
|
||||
bool int_process::attach(int_processSet *ps, bool reattach)
|
||||
@@ -488,7 +463,7 @@ bool int_process::attach(int_processSet *ps, bool reattach)
|
||||
int_process *proc = *i;
|
||||
if (proc->getState() == errorstate)
|
||||
continue;
|
||||
- bool result = proc->attachThreadsSync();
|
||||
+ bool result = proc->plat_attachThreadsSync();
|
||||
if (!result) {
|
||||
pthrd_printf("Failed to attach to threads in %d--now an error\n", proc->pid);
|
||||
procs.erase(i++);
|
||||
|
||||
commit ce0f92e8a61aeb8ca0fea7bb2d2d6a76d38ec6d2
|
||||
Author: Josh Stone <jistone@redhat.com>
|
||||
Date: Wed Nov 16 13:44:37 2016 -0800
|
||||
|
||||
proccontrol: scrub newly created threads that fail to attach
|
||||
|
||||
If `int_thread::createThread` failed to actually attach to the thread,
|
||||
it was leaving the thread object in the process in the `neonatal` state.
|
||||
This failed assertions later when trying to stop all of the process's
|
||||
threads, as it would have handler `stopped` and generator `neonatal`.
|
||||
|
||||
Now when a thread attach fails, it is set to `errorstate` and removed
|
||||
from the active thread pools. The assumption is that this thread simply
|
||||
exited before we could attach, but we can't be sure of that without
|
||||
having access to the ptrace return code (`ESRCH`).
|
||||
|
||||
diff --git a/proccontrol/src/process.C b/proccontrol/src/process.C
|
||||
index 945bc35744ba..66397f5ad93d 100644
|
||||
--- a/proccontrol/src/process.C
|
||||
+++ b/proccontrol/src/process.C
|
||||
@@ -3495,8 +3495,14 @@ int_thread *int_thread::createThread(int_process *proc,
|
||||
bool result = newthr->attach();
|
||||
if (!result) {
|
||||
pthrd_printf("Failed to attach to new thread %d/%d\n", proc->getPid(), lwp_id);
|
||||
+ newthr->getUserState().setState(errorstate);
|
||||
+ newthr->getHandlerState().setState(errorstate);
|
||||
+ newthr->getGeneratorState().setState(errorstate);
|
||||
+ ProcPool()->rmThread(newthr);
|
||||
+ proc->threadPool()->rmThread(newthr);
|
||||
return NULL;
|
||||
}
|
||||
+
|
||||
if (newthr->isUser() && newthr->getUserState().getState() == neonatal) {
|
||||
newthr->getUserState().setState(neonatal_intermediate);
|
||||
newthr->getHandlerState().setState(neonatal_intermediate);
|
||||
|
||||
commit dae2e3d9856c9245e37e1fc3d81ab59be67f932b
|
||||
Author: Josh Stone <jistone@redhat.com>
|
||||
Date: Fri Nov 18 14:49:41 2016 -0800
|
||||
|
||||
proccontrol: fix double-increment while erasing a dead process
|
||||
|
||||
In the attach loop over waitfor_startup(), processes which fail are
|
||||
erased from the set. However, the iterator was getting incremented
|
||||
again, which will skip the next process or even cause undefined behavior
|
||||
if already at the end of the list.
|
||||
|
||||
With GCC 6.2.1, that UB manifested as an infinite loop on a self-
|
||||
referential rbtree node.
|
||||
|
||||
The simple solution is to `continue` the loop after `erase(i++)`, as is
|
||||
done in many other places with this same pattern.
|
||||
|
||||
diff --git a/proccontrol/src/process.C b/proccontrol/src/process.C
|
||||
index 66397f5ad93d..32bfc8fb2a5c 100644
|
||||
--- a/proccontrol/src/process.C
|
||||
+++ b/proccontrol/src/process.C
|
||||
@@ -453,6 +453,7 @@ bool int_process::attach(int_processSet *ps, bool reattach)
|
||||
pthrd_printf("Error waiting for attach to %d\n", proc->pid);
|
||||
procs.erase(i++);
|
||||
had_error = true;
|
||||
+ continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
commit cb81d5342d9b99143312186ef558e49bcb37cd65
|
||||
Author: Josh Stone <jistone@redhat.com>
|
||||
Date: Mon Nov 21 11:52:48 2016 -0800
|
||||
|
||||
proccontrol: fix another process erasure during attach
|
||||
|
||||
If a process initially failed to attach threads, a `pthrd_printf` was
|
||||
indicating that it would try again, but the process was getting erased
|
||||
from the set while incorrectly causing the iterator to double-increment.
|
||||
|
||||
Now the messages about "will try again" and "now an error" are changed
|
||||
to simply report an immediate error, and it continus the loop after
|
||||
process erasure to avoid incrementing the iterator again.
|
||||
|
||||
diff --git a/proccontrol/src/process.C b/proccontrol/src/process.C
|
||||
index 32bfc8fb2a5c..548f6908f9d1 100644
|
||||
--- a/proccontrol/src/process.C
|
||||
+++ b/proccontrol/src/process.C
|
||||
@@ -381,8 +381,10 @@ bool int_process::attach(int_processSet *ps, bool reattach)
|
||||
pthrd_printf("Attaching to threads for %d\n", proc->getPid());
|
||||
bool result = proc->attachThreads();
|
||||
if (!result) {
|
||||
- pthrd_printf("Could not attach to threads in %d--will try again\n", proc->pid);
|
||||
+ pthrd_printf("Failed to attach to threads in %d\n", proc->pid);
|
||||
procs.erase(i++);
|
||||
+ had_error = true;
|
||||
+ continue;
|
||||
}
|
||||
|
||||
if (reattach) {
|
||||
@@ -466,7 +468,7 @@ bool int_process::attach(int_processSet *ps, bool reattach)
|
||||
continue;
|
||||
bool result = proc->plat_attachThreadsSync();
|
||||
if (!result) {
|
||||
- pthrd_printf("Failed to attach to threads in %d--now an error\n", proc->pid);
|
||||
+ pthrd_printf("Failed to attach to threads in %d\n", proc->pid);
|
||||
procs.erase(i++);
|
||||
had_error = true;
|
||||
continue;
|
@ -2,7 +2,7 @@ Summary: An API for Run-time Code Generation
|
||||
License: LGPLv2+
|
||||
Name: dyninst
|
||||
Group: Development/Libraries
|
||||
Release: 4%{?dist}
|
||||
Release: 5%{?dist}
|
||||
URL: http://www.dyninst.org
|
||||
Version: 9.2.0
|
||||
# Dyninst only has full support for a few architectures.
|
||||
@ -14,6 +14,7 @@ Source0: https://github.com/dyninst/dyninst/archive/v9.2.0.tar.gz#/%{name}-%{ver
|
||||
Source1: https://github.com/dyninst/dyninst/releases/download/v9.2.0/Testsuite-9.2.0.zip
|
||||
|
||||
Patch1: dyninst-9.2.0-proccontrol-attach-no-exe.patch
|
||||
Patch2: dyninst-9.2.0-proccontrol-thread-races.patch
|
||||
|
||||
%global dyninst_base dyninst-%{version}
|
||||
%global testsuite_base testsuite-master
|
||||
@ -86,6 +87,7 @@ making sure that dyninst works properly.
|
||||
%setup -q -T -D -a 1
|
||||
|
||||
%patch1 -p1 -d %{dyninst_base} -b .attach-no-exe
|
||||
%patch2 -p1 -d %{dyninst_base} -b .attach-thread-races
|
||||
|
||||
%build
|
||||
|
||||
@ -175,6 +177,9 @@ find %{buildroot}%{_libdir}/dyninst/testsuite/ \
|
||||
%attr(644,root,root) %{_libdir}/dyninst/testsuite/*.a
|
||||
|
||||
%changelog
|
||||
* Tue Nov 22 2016 Josh Stone <jistone@redhat.com> - 9.2.0-5
|
||||
- Backport fixes for rhbz1373197, attach thread races.
|
||||
|
||||
* Wed Sep 14 2016 Josh Stone <jistone@redhat.com> - 9.2.0-4
|
||||
- Fix rhbz1373239, process attach without exe specified.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user