簡體   English   中英

為什么_do_fork()的kretprobe只返回一次?

[英]Why does the kretprobe of the _do_fork() only return once?

當我用fork編寫一個小腳本時,syscall返回兩次進程(每個進程一次):

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int pid = fork();

    if (pid == 0) {
        // child
    } else if (pid > 0) {
        // parent
    }
}

如果我使用systemtap進行檢測,我只找到一個返回值:

// fork() in libc calls clone on Linux
probe syscall.clone.return {
    printf("Return from clone\n")
}

SystemTap在_do_fork上安裝探測而不是克隆,但不應該改變任何東西。)

這讓我很困惑。 幾個相關的問題:

  • 為什么系統調用只返回一次?
  • 如果我正確理解了_do_fork代碼 ,則會在函數中間克隆該進程。 copy_processwake_up_new_task )。 后續代碼不應該在兩個進程中運行嗎?
  • 系統調用之后的內核代碼是否在與系統調用之前的用戶代碼相同的線程/進程中運行?
  1. 孩子的創造可能失敗,因此必須檢測和處理錯誤
  2. 孩子有不同的回報值,這也必須處理
  3. 它可能是父母有清理/額外的行動要做

因此,代碼必須區分執行父項和子項。 但是沒有關於排序的檢查,這已經強烈暗示孩子首先不執行此代碼。 因此,應該尋找新孩子回歸的專用場所。

由於代碼非常大而且毛茸茸,人們可以嘗試作弊,只需在特定於arch的代碼中查找“fork”,這會快速顯示ret_from_fork。

它設置了一個起點 - > do_fork - > copy_process - > copy_thread_tls http://lxr.free-electrons.com/source/arch/x86/kernel/process_64.c#L158

從而

為什么系統調用只返回一次?

它不會返回一次。 有2個返回線程,除了另一個使用不同的代碼路徑。 由於探針僅安裝在第一個探針上,因此您看不到另一個探針。 另見下文。

如果我正確理解了_do_fork代碼,則會在函數中間克隆該進程。 (copy_process和wake_up_new_task)。 后續代碼不應該在兩個進程中運行嗎?

我之前提到這是錯誤的。 真正的問題是讓孩子與父母一起回歸的好處是什么。 我沒有看到任何它會麻煩(額外的特殊外殼,如上所述)。 要重新說明:讓孩子返回別人,讓來電者不必處理返回的孩子。 他們只需要檢查錯誤。

系統調用之后的內核代碼是否在與系統調用之前的用戶代碼相同的線程/進程中運行?

什么是'系統調用后的內核代碼'? 如果你是線程X並進入內核,你仍然是線程X.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM