gpt4 book ai didi

c - 如何跟踪多线程应用程序?

转载 作者:太空狗 更新时间:2023-10-29 17:25:21 25 4
gpt4 key购买 nike

编辑(取得进展):

我正在尝试跟踪 vsftpd 守护进程。我有以下附加到守护进程的代码。然后它成功显示第一个派生进程的 PID。但是,对于这个衍生进程的子进程,它返回 PID 作为 2,3,.. 该程序确实捕获了衍生进程的退出,这让我觉得我很接近。

有什么想法吗?

void * trace_process(void * pid){
pid_t child = atoi((char *) pid);
long orig_eax, eax;
int status;
int callmade = FALSE;
long opt = PTRACE_O_TRACEFORK;
long newpid;

long trace = ptrace(PTRACE_ATTACH,child,NULL,NULL);
ptrace(PTRACE_SETOPTIONS,child,NULL,opt);
if(trace == FALSE)
printf("Attached to %d\n",child);

while(TRUE) {
child = waitpid(-1, &status, __WALL);

if (status >> 16 == PTRACE_EVENT_FORK) {
ptrace(PTRACE_GETEVENTMSG, child, NULL, (long) &newpid);
ptrace(PTRACE_SYSCALL, newpid, NULL, NULL);

printf("Attached to offspring %ld\n", newpid);
}
else{
if(WIFEXITED(status))
printf("Child %d exited\n", child);
}

ptrace(PTRACE_SYSCALL,child, NULL, NULL);
}
}

示例输出:

Attached to 2015 // daemon
Attached to offspring 5302 // new connection handler
Attached to offspring 2 // should be authenticator
Child 5303 exited // authenticator exiting on successful login
Attached to offspring 3 // should be process serving files
Child 5304 exited // logout: process serving files
Child 5302 exited // connection closed
Attached to offspring 5305 // new connection handler
Attached to offspring 2 // ... repeat
Child 5306 exited
Attached to offspring 3
Child 5307 exited
Child 5305 exited

最佳答案

在阅读 Playing with ptrace 时文章,我找到了this comment来自也为此苦苦挣扎的用户:

/* After struggled a long time, I got a true way to make my ptrace worked 
* correct with multi-thread application. Here're my sample codes, hope it
* can help others whom have the same confusion. */

char trapCode[] = {0, 0, 0, 0};
int status;

ptrace(PTRACE_ATTACH, childProcess, NULL, NULL); //childProcess is the main thread
wait(NULL);

printf("\nchild %d created\n", childProcess);
fflush(stdout);

long ptraceOption = PTRACE_O_TRACECLONE;
ptrace(PTRACE_SETOPTIONS, childProcess, NULL, ptraceOption);

struct user_regs_struct regs;

for(unsigned int i = 0; i < m_breakPoints.size(); i++)
{
BreakPoint_Info breakPointInfo = m_breakPoints[i];
if(!breakPointInfo.m_enabled)
continue;

unsigned int index = breakPointInfo.m_checkPointIndex;
if(m_bytesBackup.find(m_checkPoints[index].m_offset) != m_bytesBackup.end())
continue;

unsigned long readAddr = m_checkPoints[index].m_offset;
One_Byte_With_Result *oneByte = new One_Byte_With_Result;
getData(childProcess, readAddr, trapCode, 4);
oneByte->m_char = trapCode[0];
trapCode[0] = 0xcc;
putData(childProcess, readAddr, trapCode, 4);

m_bytesBackup.insert(std::make_pair(m_checkPoints[index].m_offset, oneByte));
}

std::set allThreads;
std::set::iterator allThreadsIter;
allThreads.insert(childProcess);

int rec = ptrace(PTRACE_CONT, childProcess, NULL, NULL);

while(true)
{
pid_t child_waited = waitpid(-1, &status, __WALL);

if(child_waited == -1)
break;

if(allThreads.find(child_waited) == allThreads.end())
{
printf("\nreceived unknown child %d\t", child_waited);
break;
}

if(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
{
pid_t new_child;
if(((status >> 16) & 0xffff) == PTRACE_EVENT_CLONE)
{
if(ptrace(PTRACE_GETEVENTMSG, child_waited, 0, &new_child) != -1)
{
allThreads.insert(new_child);
ptrace(PTRACE_CONT, new_child, 0, 0);

printf("\nchild %d created\t", new_child);
}

ptrace(PTRACE_CONT, child_waited, 0, 0);
continue;
}
}

if(WIFEXITED(status))
{
allThreads.erase(child_waited);
printf("\nchild %d exited with status %d\t", child_waited, WEXITSTATUS(status));

if(allThreads.size() == 0)
break;
}
else if(WIFSIGNALED(status))
{
allThreads.erase(child_waited);
printf("\nchild %d killed by signal %d\t", child_waited, WTERMSIG(status));

if(allThreads.size() == 0)
break;
}
else if(WIFSTOPPED(status))
{
int stopCode = WSTOPSIG(status);
if(stopCode == SIGTRAP)
{
ptrace(PTRACE_GETREGS, child_waited, NULL, &regs);
unsigned long currentEip = regs.eip;
//printf("%d\t%08x\n", child_waited, currentEip);

Address_Bytes_Map::iterator iter = m_bytesBackup.find(currentEip - 1);
if(iter != m_bytesBackup.end())
{
iter->second->m_result = true;

regs.eip = regs.eip - 1;
getData(child_waited, regs.eip, trapCode, 4);
trapCode[0] = iter->second->m_char;
putData(child_waited, regs.eip, trapCode, 4);
rec = ptrace(PTRACE_SETREGS, child_waited, NULL, &regs);
}
}
}

rec = ptrace(PTRACE_CONT, child_waited, 1, NULL);

continue;
}

关于c - 如何跟踪多线程应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5477976/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com