# 调试原理

```c
void run_target(const char* 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);
}


main:

child_pid = fork();
    if (child_pid == 0)
        run_target(argv[1]);
    else if (child_pid > 0)
        {
        wait(&wait_status);
        check_SIG(WIFSTOPPED(wait_status));
        do_debug(pid_t child_pid);
        }
    else {
        perror("fork");
        return -1;
        }
```

\[模拟GDB]

由父进程 `fork()` 一个子进程，在子进程中调用`ptrace(PTRACE_TRACEME, 0, 0, 0)`,表明这个进程由它的父进程来跟踪，然后执行`execl(programname)`用新程序替换子进程映像。

子进程被父进程所跟踪时，任何发给这个进程的信号（除了SIGKILL）将导致该进程停止运行，而它的父进程会通过wait()获得通知。另外，该进程之后所有对exec()的调用都将使操作系统产生一个SIGTRAP信号发送给它，这让父进程有机会在新程序开始执行之前获得对子进程的控制权。如果不希望由父进程来跟踪的话，那就不应该使用这个请求。（pid、addr、data被忽略）

一旦子进程开始执行exec调用，它就会停止然后接收到一个SIGTRAP信号。父进程通过第一个wait调用正在等待这个事件发生。一旦子进程停止（如果子进程由于发送的信号而停止运行，WIFSTOPPED就返回true），父进程就去检查这个事件。

父进程 就可以从新程序第一条指令执行前获得控制权，去继续ptrace 操作子进程。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://b0ldfrev.gitbook.io/note/linux_operating_system/tiao-shi-yuan-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
