I want to build my own debugger, from scratch, so I am trying to pick up some of the concepts behind it. First, I am starting easy, using the ptrace library. But even at this point I am having some issues, let me run through this code:
int main(int argc, char** argv)
{
pid_t child_pid;
if (argc < 2) {
fprintf(stderr, "Expected a program name as argument\n");
return -1;
}
child_pid = fork();
if (child_pid == 0)
run_target(argv[1]);
else if (child_pid > 0)
run_debugger(child_pid);
else {
perror("fork");
return -1;
}
return 0;
}
this is nothing really special, I am creating a child process using fork() the next function is what really I cannot understand
void run_target(const char* programname)
{
procmsg("target started. will run '%s'\n", programname);
/* Allow tracing of this process */
if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
perror("ptrace");
return;
}
/* Replace this process's image with the given program */
execl(programname, programname, 0);
}
The last call is the issue. this call represents the concept of overlaying process image.I am not fully getting what is happening. This is what the author says:
I've highlighted the part that interests us in this example. Note that the very next thing run_target does after ptrace is invoke the program given to it as an argument with execl. This, as the highlighted part explains, causes the OS kernel to stop the process just before it begins executing the program in execl and send a signal to the parent.To run the debugger basically the parent process must trace the child process, which acknowledges that it wants to be traced using PTRACEME. But I can’t figure out what that execl is doing. I can understand the purpose and the output but can’t figure out HOW. I consulted the man pages but could not wrap my head around this. I would appreciate if someone could give me a clear explanation of what’s going on with this execl function.