[GDB] 使用 gdb 設定字串值與檢查函式返回值

[GDB] 使用 gdb 設定字串值與檢查函式返回值

算是延續上一篇 使用 gdb 除錯 fork 出來的子進程

想要查 fork 之後的 child process 為什麼會掛掉,

看了一下 fork 後的程式,最後就是一行 execve() 執行另一個執行檔,

不過執行 execve() 後,什麼事都沒發生,

而直接跳到了下一行的 exit(0) 的程式碼:

631  execve(prog_path, new_argv, __environ);
(gdb) n
634  exit(0);

 

想看一下 execve() 的傳回值,可以看一下 eax 暫存器的值,

也可以看一下 errno 的值:

(gdb) p $eax
$3 = -1
(gdb) p errno
$4 = 13

 

對照一下 errno.h,可以看到 errno 13 代表的是 EACCES,

再對照一下 man execve, EACCESS 有幾種可能的原因,

最接近的就是 “The file or a script interpreter is not a regular file”,

為什麼呢?可以看一下 prog_path 的值:

(gdb) p prog_path
$7 = "/root/test\000myprogram", '\0' <repeats 4052 times>

 

嗯~真奇怪了, prog_path 本來應該是要指向一個可執行檔的路徑,

在本例中是/root/test/myprogram,

結果現在是變成了 /root/test,看來是被截斷了…

截斷的原因可以再另外查,不過想測試一下如果 prog_path 是正確的話,

是否 execve() 就正常了呢?

這時可以用 gdb 的 set 指令來將字串指定給變數,

不過要自己注意字串是否會超過原本的 buffer 長度:

(gdb) set prog_path = "/root/test/myprogram"
(gdb) p prog_path
$7 = "/root/test/myprogram", '\0' <repeats 4052 times>

 

設定完之後,再繼續執行看看,果然 execve() 就正常執行了:

(gdb) n
[New process 1890]
Executing new program: /root/test/myprogram
[Thread debugging using libthread_db enabled]

 

參考資料:

stackoverflow: Inspect the return value of a function in gdb

stackoverflow: In gdb, how can I write a string to memory?

(本頁面已被瀏覽過 50 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料