Update to 9.3.0
This commit is contained in:
parent
211f9c452c
commit
7c19ffddf0
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,3 +13,5 @@
|
||||
/Testsuite-9.1.0.tgz
|
||||
/dyninst-9.2.0.tar.gz
|
||||
/Testsuite-9.2.0.zip
|
||||
/dyninst-9.3.0.tar.gz
|
||||
/testsuite-9.3.0.tar.gz
|
||||
|
@ -1,78 +0,0 @@
|
||||
commit 6e1b36f62c0830978ab4db44f763e030cc74a18d (from 6cca9d0ee6a4676028e511e2c5384ed959b1816f)
|
||||
Merge: 6cca9d0ee6a4 0be0ab88a5d9
|
||||
Author: Josh Stone <cuviper@gmail.com>
|
||||
Date: Tue Aug 9 16:33:52 2016 -0700
|
||||
|
||||
Merge pull request #147 from cuviper/attach-no-exe
|
||||
|
||||
proccontrol: fix process attachment without an exe
|
||||
|
||||
diff --git a/proccontrol/src/linux.C b/proccontrol/src/linux.C
|
||||
index 4502e357f79f..407a77ec6ecf 100644
|
||||
--- a/proccontrol/src/linux.C
|
||||
+++ b/proccontrol/src/linux.C
|
||||
@@ -884,8 +884,9 @@ int linux_process::computeAddrWidth()
|
||||
* of name word will be 0x0 on 64 bit processes. On 32-bit process this
|
||||
* word will contain a value, of which some should be non-zero.
|
||||
*
|
||||
- * We'll thus check every word that is 1 mod 4. If all are 0x0 we assume we're
|
||||
- * looking at a 64-bit process.
|
||||
+ * We'll thus check every word that is 1 mod 4 for little-endian machines,
|
||||
+ * or 0 mod 4 for big-endian. If all words of either stripe are 0x0, we
|
||||
+ * assume we're looking at a 64-bit process.
|
||||
**/
|
||||
uint32_t buffer[256];
|
||||
char auxv_name[64];
|
||||
@@ -898,25 +899,21 @@ int linux_process::computeAddrWidth()
|
||||
return -1;
|
||||
}
|
||||
|
||||
- long int result = read(fd, buffer, sizeof(buffer));
|
||||
- long int words_read = result / sizeof(uint32_t);
|
||||
- int word_size = 8;
|
||||
+ ssize_t result = read(fd, buffer, sizeof(buffer));
|
||||
+ ssize_t words_read = (result / sizeof(uint32_t)) & ~3;
|
||||
+ close(fd);
|
||||
|
||||
// We want to check the highest 4 bytes of each integer
|
||||
// On big-endian systems, these come first in memory
|
||||
- SymReader *objSymReader = getSymReader()->openSymbolReader(getExecutable());
|
||||
- int start_index = objSymReader->isBigEndianDataEncoding() ? 0 : 1;
|
||||
-
|
||||
- for (long int i=start_index; i<words_read; i+= 4)
|
||||
+ bool be_zero = true, le_zero = true;
|
||||
+ for (ssize_t i=0; i<words_read; i+= 4)
|
||||
{
|
||||
- if (buffer[i] != 0) {
|
||||
- word_size = 4;
|
||||
- break;
|
||||
- }
|
||||
+ be_zero &= buffer[i] == 0;
|
||||
+ le_zero &= buffer[i+1] == 0;
|
||||
}
|
||||
- close(fd);
|
||||
|
||||
- pthrd_printf("computeAddrWidth: Offset set to %d, word size is %d\n", start_index, word_size);
|
||||
+ int word_size = (be_zero || le_zero) ? 8 : 4;
|
||||
+ pthrd_printf("computeAddrWidth: word size is %d\n", word_size);
|
||||
return word_size;
|
||||
}
|
||||
|
||||
diff --git a/proccontrol/src/loadLibrary/codegen.C b/proccontrol/src/loadLibrary/codegen.C
|
||||
index 9d545a7a5f70..a29b61450a04 100644
|
||||
--- a/proccontrol/src/loadLibrary/codegen.C
|
||||
+++ b/proccontrol/src/loadLibrary/codegen.C
|
||||
@@ -33,9 +33,11 @@ bool Codegen::generate() {
|
||||
|
||||
buffer_.initialize(codeStart_, size);
|
||||
|
||||
- SymReader *objSymReader = proc_->llproc()->getSymReader()->openSymbolReader(proc_->llproc()->getExecutable());
|
||||
abimajversion_ = abiminversion_ = 0;
|
||||
- objSymReader->getABIVersion(abimajversion_, abiminversion_);
|
||||
+ auto exe = proc_->libraries().getExecutable();
|
||||
+ SymReader *objSymReader = proc_->llproc()->getSymReader()->openSymbolReader(exe->getName());
|
||||
+ if (objSymReader)
|
||||
+ objSymReader->getABIVersion(abimajversion_, abiminversion_);
|
||||
|
||||
if (!generateInt()) return false;
|
||||
|
@ -1,526 +0,0 @@
|
||||
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;
|
19
dyninst.spec
19
dyninst.spec
@ -2,22 +2,19 @@ Summary: An API for Run-time Code Generation
|
||||
License: LGPLv2+
|
||||
Name: dyninst
|
||||
Group: Development/Libraries
|
||||
Release: 5%{?dist}
|
||||
Release: 1%{?dist}
|
||||
URL: http://www.dyninst.org
|
||||
Version: 9.2.0
|
||||
Version: 9.3.0
|
||||
# Dyninst only has full support for a few architectures.
|
||||
# It has some preliminary support for aarch64 and ppc64le,
|
||||
# but we're waiting for those to be feature-complete.
|
||||
ExclusiveArch: %{ix86} x86_64 ppc ppc64
|
||||
|
||||
Source0: https://github.com/dyninst/dyninst/archive/v9.2.0.tar.gz#/%{name}-%{version}.tar.gz
|
||||
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
|
||||
Source0: https://github.com/dyninst/dyninst/archive/v%{version}/dyninst-%{version}.tar.gz
|
||||
Source1: https://github.com/dyninst/testsuite/archive/v%{version}/testsuite-%{version}.tar.gz
|
||||
|
||||
%global dyninst_base dyninst-%{version}
|
||||
%global testsuite_base testsuite-master
|
||||
%global testsuite_base testsuite-%{version}
|
||||
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: libdwarf-devel >= 20111030
|
||||
@ -86,9 +83,6 @@ making sure that dyninst works properly.
|
||||
%setup -q -n %{name}-%{version} -c
|
||||
%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
|
||||
|
||||
cd %{dyninst_base}
|
||||
@ -177,6 +171,9 @@ find %{buildroot}%{_libdir}/dyninst/testsuite/ \
|
||||
%attr(644,root,root) %{_libdir}/dyninst/testsuite/*.a
|
||||
|
||||
%changelog
|
||||
* Mon Jan 09 2017 Josh Stone <jistone@redhat.com> - 9.3.0-1
|
||||
- Update to 9.3.0
|
||||
|
||||
* Tue Nov 22 2016 Josh Stone <jistone@redhat.com> - 9.2.0-5
|
||||
- Backport fixes for rhbz1373197, attach thread races.
|
||||
|
||||
|
4
sources
4
sources
@ -1,2 +1,2 @@
|
||||
ad023f85e8e57837ed9de073b59d6bab dyninst-9.2.0.tar.gz
|
||||
df8173412a7123f8a47b47e50eabc35b Testsuite-9.2.0.zip
|
||||
SHA512 (dyninst-9.3.0.tar.gz) = 27b99a15c9aea102f9575b6dad46cf1a3f50c1490b5ea6bb0b67d3c65f692583f4c96f852fab840caeec413ca0feb72be6f094d2ddc9a19ed2311a9120a1d11d
|
||||
SHA512 (testsuite-9.3.0.tar.gz) = b4a53c1a214882d7823f7a67fad5aee51a7f2fd692abdaecc9658cd01e991b6ac9b031b0f9bb94e3bd3e147ed4d362305882439bb422ff6b48bc35f1acbcdc2e
|
||||
|
Loading…
Reference in New Issue
Block a user