Dear all,
With the newest Ubuntu (and thus new linux kernel), the PIN version Sniper is using, has some issues, especially regarding multi-threading.
I managed to fix it with the following changes:
- Extract, Rename and replace the downloaded directory to pin_kit inside Sniper.
- Apply the patch underneath.
I did not test this extensively, so I cannot guarantee that it will solve all issues. But hopefully this helps you out somehow.
Jaime Roelandts - Ugent
---------------------------------------------------------------
diff --git a/sift/recorder/emulation.cc b/sift/recorder/emulation.cc
index 4d55a19af..d5277c2f9 100644
--- a/sift/recorder/emulation.cc
+++ b/sift/recorder/emulation.cc
@@ -9,7 +9,7 @@
static AFUNPTR ptr_exit = NULL;
-static void handleRdtsc(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gdx)
+static void handleRdtsc(THREADID threadid, ADDRINT * gax, ADDRINT * gdx)
{
if (!thread_data[threadid].output)
return;
@@ -21,12 +21,12 @@ static void handleRdtsc(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gd
if (emulated)
{
// Return in eax and edx
- gdx->dword[0] = res.rdtsc.cycles >> 32;
- gax->dword[0] = res.rdtsc.cycles & 0xffffffff;
+ *gdx = res.rdtsc.cycles >> 32;
+ *gax = res.rdtsc.cycles & 0xffffffff;
}
}
-static void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gbx, PIN_REGISTER * gcx, PIN_REGISTER * gdx)
+static void handleCpuid(THREADID threadid, ADDRINT * gax, ADDRINT * gbx, ADDRINT * gcx, ADDRINT * gdx)
{
if (!thread_data[threadid].output)
return;
@@ -34,15 +34,15 @@ static void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gb
Sift::EmuRequest req;
Sift::EmuReply res;
- req.cpuid.eax = gax->dword[0];
- req.cpuid.ecx = gcx->dword[0];
+ req.cpuid.eax = *gax;
+ req.cpuid.ecx = *gcx;
bool emulated = thread_data[threadid].output->Emulate(Sift::EmuTypeCpuid, req, res);
sift_assert(emulated);
- gax->dword[0] = res.cpuid.eax;
- gbx->dword[0] = res.cpuid.ebx;
- gcx->dword[0] = res.cpuid.ecx;
- gdx->dword[0] = res.cpuid.edx;
+ *gax = res.cpuid.eax;
+ *gbx = res.cpuid.ebx;
+ *gcx = res.cpuid.ecx;
+ *gdx = res.cpuid.edx;
}
static ADDRINT emuGetNprocs(THREADID threadid)
diff --git a/sift/recorder/makefile.rules b/sift/recorder/makefile.rules
index a3b78eafc..9a3fbbdfc 100644
--- a/sift/recorder/makefile.rules
+++ b/sift/recorder/makefile.rules
@@ -115,7 +115,7 @@ else
endif
COMPILE_PIN_FLAGS := -g -std=c++0x $(PINPLAY_CXXFLAGS) $(TOOL_CXXFLAGS)
-LINK_FLAGS := -g $(TOOL_LDFLAGS)
+LINK_FLAGS := -g $(TOOL_LDFLAGS_NOOPT)
LINK_LIBS = sift/libsift.a $(PINPLAY_LIBS)
diff --git a/sift/recorder/syscall_modeling.cc b/sift/recorder/syscall_modeling.cc
index 57a850b90..4b8b59549 100644
--- a/sift/recorder/syscall_modeling.cc
+++ b/sift/recorder/syscall_modeling.cc
@@ -103,6 +103,25 @@ VOID emulateSyscallFunc(THREADID threadid, CONTEXT *ctxt)
// Handle SYS_clone child tid capture for proper pthread_join emulation.
// When the CLONE_CHILD_CLEARTID option is enabled, remember its child_tidptr and
// then when the thread ends, write 0 to the tid mutex and futex_wake it
+ case SYS_clone3:
+ {
+ if (args[0] && CLONE_THREAD) //TODO not sure if enough, but it works for now
+ {
+ struct clone_args* clone3_args = (struct clone_args*)args[0];
+ ADDRINT tidptr = clone3_args->parent_tid;
+ PIN_GetLock(&new_threadid_lock, threadid);
+ tidptrs.push_back(tidptr);
+ PIN_ReleaseLock(&new_threadid_lock);
+ /* New thread */
+ thread_data[threadid].output->NewThread();
+ }
+ else
+ {
+ /* New process */
+ // Nothing to do there, handled in fork() -> to check SYS_clone3 is new
+ }
+ break;
+ }
case SYS_clone:
{
if (args[0] & CLONE_THREAD)
diff --git a/sift/sift_reader.cc b/sift/sift_reader.cc
index 479e5162c..e1d4e7620 100644
--- a/sift/sift_reader.cc
+++ b/sift/sift_reader.cc
@@ -154,7 +154,7 @@ bool Sift::Reader::initResponse()
std::cerr << "[SIFT:" << m_id << "] Response filename not set\n";
return false;
}
- response = new vofstream(m_response_filename, std::ios::out);
+ response = new vofstream(m_response_filename, std::ios::out | std::ios::binary | std::ios::trunc);
}
if ((!response->is_open()) || (response->fail()))
@@ -310,7 +310,7 @@ bool Sift::Reader::Read(Instruction &inst)
hexdump((char*)bytes, size);
#endif
#if VERBOSE > 1
- for (int i = 0 ; i < (size/8) ; i++)
+ for (uint32_t i = 0 ; i < (size/8) ; i++)
{
std::cerr << __FUNCTION__ << ": syscall args[" << i << "] = " << ((uint64_t*)bytes)[i] << std::endl;
}
diff --git a/sift/sift_writer.cc b/sift/sift_writer.cc
index 62d1beb75..b24a6b545 100644
--- a/sift/sift_writer.cc
+++ b/sift/sift_writer.cc
@@ -115,7 +115,7 @@ void Sift::Writer::initResponse()
if (!response)
{
sift_assert(strcmp(m_response_filename, "") != 0);
- response = new vifstream(m_response_filename, std::ios::in);
+ response = new vifstream(m_response_filename, std::ios::in | std::ios::binary);
sift_assert(!response->fail());
}
}
@@ -813,7 +813,7 @@ bool Sift::Writer::Emulate(Sift::EmuType type, Sift::EmuRequest &req, Sift::EmuR
output->write(reinterpret_cast<char*>(&_type), sizeof(uint16_t));
output->write(reinterpret_cast<char*>(&req), sizeof(EmuRequest));
output->flush();
-
+
initResponse();
// wait for reply
-------------------------------------------------------------------------------