Improve/Cleanup ptrace wrapper and remove dependency on user.h

Patch by Ashok Thirumurthi.

llvm-svn: 176558
This commit is contained in:
Matt Kopec 2013-03-06 17:20:48 +00:00
parent 15225aee17
commit 7de484640e
6 changed files with 103 additions and 72 deletions

View File

@ -58,6 +58,8 @@ Get_PT_IO_OP(int op)
}
}
// Wrapper for ptrace to catch errors and log calls.
// Note that ptrace sets errno on error because -1 is reserved as a valid result.
extern long
PtraceWrapper(int req, ::pid_t pid, void *addr, int data,
const char* reqName, const char* file, int line)
@ -84,7 +86,7 @@ PtraceWrapper(int req, ::pid_t pid, void *addr, int data,
//PtraceDisplayBytes(req, data);
if (log && (result == -1 || errno != 0))
if (log && errno != 0)
{
const char* str;
switch (errno)
@ -112,10 +114,21 @@ PtraceWrapper(int req, ::pid_t pid, void *addr, int data,
return result;
}
// Wrapper for ptrace when logging is not required.
// Sets errno to 0 prior to calling ptrace.
extern long
PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data)
{
long result = 0;
errno = 0;
result = ptrace(req, pid, addr, data);
return result;
}
#define PTRACE(req, pid, addr, data) \
PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
#else
#define PTRACE ptrace
PtraceWrapper((req), (pid), (addr), (data))
#endif
//------------------------------------------------------------------------------
@ -1104,7 +1117,8 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
{
ProcessMessage message;
assert(info->si_signo == SIGTRAP && "Unexpected child signal!");
assert(monitor);
assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
switch (info->si_code)
{
@ -1443,7 +1457,7 @@ ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
}
bool
ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf)
ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
ReadGPROperation op(buf, result);
@ -1452,7 +1466,7 @@ ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf)
}
bool
ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf)
ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
ReadFPROperation op(buf, result);
@ -1461,7 +1475,7 @@ ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf)
}
bool
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf)
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
WriteGPROperation op(buf, result);
@ -1470,7 +1484,7 @@ ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf)
}
bool
ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf)
ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
WriteFPROperation op(buf, result);

View File

@ -124,19 +124,19 @@ public:
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
ReadGPR(lldb::tid_t tid, void *buf);
ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Reads all floating point registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
ReadFPR(lldb::tid_t tid, void *buf);
ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all general purpose registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
WriteGPR(lldb::tid_t tid, void *buf);
WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all floating point registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order

View File

@ -18,7 +18,6 @@
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/wait.h>
// C++ Includes
@ -64,7 +63,7 @@ DisplayBytes (lldb_private::StreamString &s, void *bytes, uint32_t count)
}
}
static void PtraceDisplayBytes(__ptrace_request &req, void *data)
static void PtraceDisplayBytes(__ptrace_request &req, void *data, size_t data_size)
{
StreamString buf;
LogSP verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (
@ -94,13 +93,13 @@ static void PtraceDisplayBytes(__ptrace_request &req, void *data)
}
case PTRACE_SETREGS:
{
DisplayBytes(buf, data, sizeof(user_regs_struct));
DisplayBytes(buf, data, data_size);
verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
break;
}
case PTRACE_SETFPREGS:
{
DisplayBytes(buf, data, sizeof(user_fpregs_struct));
DisplayBytes(buf, data, data_size);
verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
break;
}
@ -118,8 +117,9 @@ static void PtraceDisplayBytes(__ptrace_request &req, void *data)
}
// Wrapper for ptrace to catch errors and log calls.
// Note that ptrace sets errno on error because -1 is a valid result for PTRACE_PEEK*
extern long
PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data,
PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, size_t data_size,
const char* reqName, const char* file, int line)
{
long int result;
@ -127,17 +127,17 @@ PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data,
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
if (log)
log->Printf("ptrace(%s, %u, %p, %p) called from file %s line %d",
reqName, pid, addr, data, file, line);
log->Printf("ptrace(%s, %u, %p, %p, %zu) called from file %s line %d",
reqName, pid, addr, data, data_size, file, line);
PtraceDisplayBytes(req, data);
PtraceDisplayBytes(req, data, data_size);
errno = 0;
result = ptrace(req, pid, addr, data);
PtraceDisplayBytes(req, data);
PtraceDisplayBytes(req, data, data_size);
if (log && (result == -1 || errno != 0))
if (log && errno != 0)
{
const char* str;
switch (errno)
@ -154,10 +154,20 @@ PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data,
return result;
}
#define PTRACE(req, pid, addr, data) \
PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
// Wrapper for ptrace when logging is not required.
// Sets errno to 0 prior to calling ptrace.
extern long
PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, size_t data_size)
{
errno = 0;
long result = ptrace(req, pid, addr, data);
return result;
}
#define PTRACE(req, pid, addr, data, data_size) \
PtraceWrapper((req), (pid), (addr), (data), (data_size), #req, __FILE__, __LINE__)
#else
#define PTRACE ptrace
PtraceWrapper((req), (pid), (addr), (data), (data_size))
#endif
//------------------------------------------------------------------------------
@ -187,8 +197,8 @@ DoReadMemory(lldb::pid_t pid,
for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
{
errno = 0;
data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, NULL);
if (data == -1L && errno)
data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, NULL, 0);
if (errno)
{
error.SetErrorToErrno();
if (log)
@ -261,7 +271,7 @@ DoWriteMemory(lldb::pid_t pid,
log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
(void*)vm_addr, *(unsigned long*)src, data);
if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data))
if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0))
{
error.SetErrorToErrno();
if (log)
@ -434,8 +444,8 @@ ReadRegOperation::Execute(ProcessMonitor *monitor)
// Set errno to zero so that we can detect a failed peek.
errno = 0;
lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, NULL);
if (data == -1UL && errno)
lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, NULL, 0);
if (errno)
m_result = false;
else
{
@ -483,7 +493,7 @@ WriteRegOperation::Execute(ProcessMonitor *monitor)
if (log)
log->Printf ("ProcessMonitor::%s() reg %s: %p", __FUNCTION__,
POSIXThread::GetRegisterNameFromOffset(m_offset), buf);
if (PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf))
if (PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0))
m_result = false;
else
m_result = true;
@ -495,8 +505,8 @@ WriteRegOperation::Execute(ProcessMonitor *monitor)
class ReadGPROperation : public Operation
{
public:
ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
: m_tid(tid), m_buf(buf), m_result(result)
ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@ -504,13 +514,14 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
bool &m_result;
};
void
ReadGPROperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_GETREGS, m_tid, NULL, m_buf) < 0)
if (PTRACE(PTRACE_GETREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@ -522,8 +533,8 @@ ReadGPROperation::Execute(ProcessMonitor *monitor)
class ReadFPROperation : public Operation
{
public:
ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
: m_tid(tid), m_buf(buf), m_result(result)
ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@ -531,13 +542,14 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
bool &m_result;
};
void
ReadFPROperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_GETFPREGS, m_tid, NULL, m_buf) < 0)
if (PTRACE(PTRACE_GETFPREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@ -549,8 +561,8 @@ ReadFPROperation::Execute(ProcessMonitor *monitor)
class WriteGPROperation : public Operation
{
public:
WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
: m_tid(tid), m_buf(buf), m_result(result)
WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@ -558,13 +570,14 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
bool &m_result;
};
void
WriteGPROperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf) < 0)
if (PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@ -576,8 +589,8 @@ WriteGPROperation::Execute(ProcessMonitor *monitor)
class WriteFPROperation : public Operation
{
public:
WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
: m_tid(tid), m_buf(buf), m_result(result)
WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
: m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@ -585,13 +598,14 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
size_t m_buf_size;
bool &m_result;
};
void
WriteFPROperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf) < 0)
if (PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@ -622,7 +636,7 @@ ResumeOperation::Execute(ProcessMonitor *monitor)
if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
data = m_signo;
if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data))
if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data, 0))
m_result = false;
else
m_result = true;
@ -653,7 +667,7 @@ SingleStepOperation::Execute(ProcessMonitor *monitor)
if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
data = m_signo;
if (PTRACE(PTRACE_SINGLESTEP, m_tid, NULL, (void*)data))
if (PTRACE(PTRACE_SINGLESTEP, m_tid, NULL, (void*)data, 0))
m_result = false;
else
m_result = true;
@ -680,7 +694,7 @@ private:
void
SiginfoOperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info)) {
if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info, 0)) {
m_result = false;
m_err = errno;
}
@ -708,7 +722,7 @@ private:
void
EventMessageOperation::Execute(ProcessMonitor *monitor)
{
if (PTRACE(PTRACE_GETEVENTMSG, m_tid, NULL, m_message))
if (PTRACE(PTRACE_GETEVENTMSG, m_tid, NULL, m_message, 0))
m_result = false;
else
m_result = true;
@ -733,7 +747,7 @@ KillOperation::Execute(ProcessMonitor *monitor)
{
lldb::pid_t pid = monitor->GetPID();
if (PTRACE(PTRACE_KILL, pid, NULL, NULL))
if (PTRACE(PTRACE_KILL, pid, NULL, NULL, 0))
m_result = false;
else
m_result = true;
@ -824,9 +838,9 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
lldb_private::Error &error)
: m_process(static_cast<ProcessLinux *>(process)),
m_operation_thread(LLDB_INVALID_HOST_THREAD),
m_monitor_thread(LLDB_INVALID_HOST_THREAD),
m_pid(LLDB_INVALID_PROCESS_ID),
m_terminal_fd(-1),
m_monitor_thread(LLDB_INVALID_HOST_THREAD),
m_client_fd(-1),
m_server_fd(-1)
{
@ -883,9 +897,10 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
lldb_private::Error &error)
: m_process(static_cast<ProcessLinux *>(process)),
m_operation_thread(LLDB_INVALID_HOST_THREAD),
m_monitor_thread(LLDB_INVALID_HOST_THREAD),
m_pid(LLDB_INVALID_PROCESS_ID),
m_terminal_fd(-1),
m_monitor_thread(LLDB_INVALID_HOST_THREAD),
m_client_fd(-1),
m_server_fd(-1)
{
@ -1023,7 +1038,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
if (pid == 0)
{
// Trace this process.
if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL) < 0)
if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL, 0) < 0)
exit(ePtraceFailed);
// Do not inherit setgid powers.
@ -1108,7 +1123,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
// Have the tracer trace threads which spawn in the inferior process.
ptrace_opts |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE;
if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts) < 0)
if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts, 0) < 0)
{
args->m_error.SetErrorToErrno();
goto FINISH;
@ -1197,7 +1212,7 @@ ProcessMonitor::Attach(AttachArgs *args)
}
// Attach to the requested process.
if (PTRACE(PTRACE_ATTACH, pid, NULL, NULL) < 0)
if (PTRACE(PTRACE_ATTACH, pid, NULL, NULL, 0) < 0)
{
args->m_error.SetErrorToErrno();
goto FINISH;
@ -1610,7 +1625,8 @@ ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
}
bool
ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, unsigned size, RegisterValue &value)
ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset,
unsigned size, RegisterValue &value)
{
bool result;
ReadRegOperation op(tid, offset, value, result);
@ -1619,7 +1635,8 @@ ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, unsigned siz
}
bool
ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset, const RegisterValue &value)
ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
const RegisterValue &value)
{
bool result;
WriteRegOperation op(tid, offset, value, result);
@ -1628,37 +1645,37 @@ ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset, const Regis
}
bool
ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf)
ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
ReadGPROperation op(tid, buf, result);
ReadGPROperation op(tid, buf, buf_size, result);
DoOperation(&op);
return result;
}
bool
ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf)
ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
ReadFPROperation op(tid, buf, result);
ReadFPROperation op(tid, buf, buf_size, result);
DoOperation(&op);
return result;
}
bool
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf)
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
WriteGPROperation op(tid, buf, result);
WriteGPROperation op(tid, buf, buf_size, result);
DoOperation(&op);
return result;
}
bool
ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf)
ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
WriteFPROperation op(tid, buf, result);
WriteFPROperation op(tid, buf, buf_size, result);
DoOperation(&op);
return result;
}

View File

@ -120,19 +120,19 @@ public:
/// Reads all general purpose registers into the specified buffer.
bool
ReadGPR(lldb::tid_t tid, void *buf);
ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Reads all floating point registers into the specified buffer.
bool
ReadFPR(lldb::tid_t tid, void *buf);
ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all general purpose registers into the specified buffer.
bool
WriteGPR(lldb::tid_t tid, void *buf);
WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all floating point registers into the specified buffer.
bool
WriteFPR(lldb::tid_t tid, void *buf);
WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.
@ -169,10 +169,10 @@ private:
ProcessLinux *m_process;
lldb::thread_t m_operation_thread;
lldb::thread_t m_monitor_thread;
lldb::pid_t m_pid;
int m_terminal_fd;
lldb::thread_t m_monitor_thread;
lldb_private::Mutex m_server_mutex;
int m_client_fd;

View File

@ -535,7 +535,7 @@ RegisterContext_i386::ReadGPR()
bool result;
ProcessMonitor &monitor = GetMonitor();
result = monitor.ReadGPR(m_thread.GetID(), &user.regs);
result = monitor.ReadGPR(m_thread.GetID(), &user.regs, sizeof(user.regs));
LogGPR("RegisterContext_i386::ReadGPR()");
return result;
}
@ -544,5 +544,5 @@ bool
RegisterContext_i386::ReadFPR()
{
ProcessMonitor &monitor = GetMonitor();
return monitor.ReadFPR(m_thread.GetID(), &user.i387);
return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
}

View File

@ -952,26 +952,26 @@ bool
RegisterContext_x86_64::ReadGPR()
{
ProcessMonitor &monitor = GetMonitor();
return monitor.ReadGPR(m_thread.GetID(), &user.regs);
return monitor.ReadGPR(m_thread.GetID(), &user.regs, sizeof(user.regs));
}
bool
RegisterContext_x86_64::ReadFPR()
{
ProcessMonitor &monitor = GetMonitor();
return monitor.ReadFPR(m_thread.GetID(), &user.i387);
return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
}
bool
RegisterContext_x86_64::WriteGPR()
{
ProcessMonitor &monitor = GetMonitor();
return monitor.WriteGPR(m_thread.GetID(), &user.regs);
return monitor.WriteGPR(m_thread.GetID(), &user.regs, sizeof(user.regs));
}
bool
RegisterContext_x86_64::WriteFPR()
{
ProcessMonitor &monitor = GetMonitor();
return monitor.WriteFPR(m_thread.GetID(), &user.i387);
return monitor.WriteFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
}