{"id":255692,"date":"2016-12-21T12:11:20","date_gmt":"2016-12-21T04:11:20","guid":{"rendered":"http:\/\/blog.zhenglei.net\/?p=255692"},"modified":"2016-12-21T12:12:23","modified_gmt":"2016-12-21T04:12:23","slug":"debug-forks-with-gdb","status":"publish","type":"post","link":"https:\/\/blog.zhenglei.net\/?p=255692","title":{"rendered":"Debug Fork with gdb"},"content":{"rendered":"<p><span style=\"color: #0000ff\"><strong>Two\u00a0 Methods<\/strong><\/span>:<\/p>\n<ol>\n<li>Add sleep in the entry of main loop<\/li>\n<li>With GDB command:<\/li>\n<\/ol>\n<p><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <em>set follow-fork-mode <\/em><\/code><em><var>mode<\/var> (parent\/child)<\/em><br \/>\n<em><code>set detach-on-fork <\/code><\/em><var><em>mode (on\/off)<\/em><br \/>\n<\/var><\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/sourceware.org\/gdb\/onlinedocs\/gdb\/Forks.html\">https:\/\/sourceware.org\/gdb\/onlinedocs\/gdb\/Forks.html<\/a><\/p>\n<p><!--more--><\/p>\n<h3 class=\"section\">4.11 Debugging Forks<\/h3>\n<p><a name=\"index-fork_002c-debugging-programs-which-call-197\"><\/a><a name=\"index-multiple-processes-198\"><\/a><a name=\"index-processes_002c-multiple-199\"><\/a>On most systems, <span class=\"sc\">gdb<\/span> has no special support for debugging programs which create additional processes using the <code>fork<\/code> function. When a program forks, <span class=\"sc\">gdb<\/span> will continue to debug the parent process and the child process will run unimpeded. If you have set a breakpoint in any code which the child then executes, the child will get a <code>SIGTRAP<\/code> signal which (unless it catches the signal) will cause it to terminate.<\/p>\n<p>However, if you want to debug the child process there is a workaround which isn&#8217;t too painful. Put a call to <code>sleep<\/code> in the code which the child process executes after the fork. It may be useful to sleep only if a certain environment variable is set, or a certain file exists, so that the delay need not occur when you don&#8217;t want to run <span class=\"sc\">gdb<\/span> on the child. While the child is sleeping, use the <code>ps<\/code> program to get its process ID. Then tell <span class=\"sc\">gdb<\/span> (a new invocation of <span class=\"sc\">gdb<\/span> if you are also debugging the parent process) to attach to the child process (see <a href=\"https:\/\/sourceware.org\/gdb\/onlinedocs\/gdb\/Attach.html#Attach\">Attach<\/a>). From that point on you can debug the child process just like any other process which you attached to.<\/p>\n<p>On some systems, <span class=\"sc\">gdb<\/span> provides support for debugging programs that create additional processes using the <code>fork<\/code> or <code>vfork<\/code> functions. On <span class=\"sc\">gnu<\/span>\/Linux platforms, this feature is supported with kernel version 2.5.46 and later.<\/p>\n<p>The fork debugging commands are supported in native mode and when connected to <code>gdbserver<\/code> in either <code>target remote<\/code> mode or <code>target extended-remote<\/code> mode.<\/p>\n<p>By default, when a program forks, <span class=\"sc\">gdb<\/span> will continue to debug the parent process and the child process will run unimpeded.<\/p>\n<p>If you want to follow the child process instead of the parent process, use the command <code>set\u00a0follow-fork-mode<\/code>. <a name=\"index-set-follow_002dfork_002dmode-200\"><\/a><\/p>\n<dl>\n<dt><code>set follow-fork-mode <\/code><var>mode<\/var><\/dt>\n<dd>Set the debugger response to a program call of <code>fork<\/code> or <code>vfork<\/code>. A call to <code>fork<\/code> or <code>vfork<\/code> creates a new process. The <var>mode<\/var> argument can be:<\/p>\n<dl>\n<dt><code>parent<\/code><\/dt>\n<dd>The original process is debugged after a fork. The child process runs unimpeded. This is the default.<\/dd>\n<dt><code>child<\/code><\/dt>\n<dd>The new process is debugged after a fork. The parent process runs unimpeded.<\/dd>\n<\/dl>\n<p><a name=\"index-show-follow_002dfork_002dmode-201\"><\/a><\/p>\n<\/dd>\n<dt><code>show follow-fork-mode<\/code><\/dt>\n<dd>Display the current debugger response to a <code>fork<\/code> or <code>vfork<\/code> call.<\/dd>\n<\/dl>\n<p><a name=\"index-debugging-multiple-processes-202\"><\/a>On Linux, if you want to debug both the parent and child processes, use the command <code>set\u00a0detach-on-fork<\/code>. <a name=\"index-set-detach_002don_002dfork-203\"><\/a><\/p>\n<dl>\n<dt><code>set detach-on-fork <\/code><var>mode<\/var><\/dt>\n<dd>Tells gdb whether to detach one of the processes after a fork, or retain debugger control over them both.<\/p>\n<dl>\n<dt><code>on<\/code><\/dt>\n<dd>The child process (or parent process, depending on the value of <code>follow-fork-mode<\/code>) will be detached and allowed to run independently. This is the default.<\/dd>\n<dt><code>off<\/code><\/dt>\n<dd>Both processes will be held under the control of <span class=\"sc\">gdb<\/span>. One process (child or parent, depending on the value of <code>follow-fork-mode<\/code>) is debugged as usual, while the other is held suspended.<\/dd>\n<\/dl>\n<p><a name=\"index-show-detach_002don_002dfork-204\"><\/a><\/p>\n<\/dd>\n<dt><code>show detach-on-fork<\/code><\/dt>\n<dd>Show whether detach-on-fork mode is on\/off.<\/dd>\n<\/dl>\n<p>If you choose to set \u2018<samp><span class=\"samp\">detach-on-fork<\/span><\/samp>\u2019 mode off, then <span class=\"sc\">gdb<\/span> will retain control of all forked processes (including nested forks). You can list the forked processes under the control of <span class=\"sc\">gdb<\/span> by using the <code>info\u00a0inferiors<\/code> command, and switch from one fork to another by using the <code>inferior<\/code> command (see <a href=\"https:\/\/sourceware.org\/gdb\/onlinedocs\/gdb\/Inferiors-and-Programs.html#Inferiors-and-Programs\">Debugging Multiple Inferiors and Programs<\/a>).<\/p>\n<p>To quit debugging one of the forked processes, you can either detach from it by using the <code>detach\u00a0inferiors<\/code> command (allowing it to run independently), or kill it using the <code>kill\u00a0inferiors<\/code> command. See <a href=\"https:\/\/sourceware.org\/gdb\/onlinedocs\/gdb\/Inferiors-and-Programs.html#Inferiors-and-Programs\">Debugging Multiple Inferiors and Programs<\/a>.<\/p>\n<p>If you ask to debug a child process and a <code>vfork<\/code> is followed by an <code>exec<\/code>, <span class=\"sc\">gdb<\/span> executes the new target up to the first breakpoint in the new target. If you have a breakpoint set on <code>main<\/code> in your original program, the breakpoint will also be set on the child process&#8217;s <code>main<\/code>.<\/p>\n<p>On some systems, when a child process is spawned by <code>vfork<\/code>, you cannot debug the child or parent until an <code>exec<\/code> call completes.<\/p>\n<p>If you issue a <code>run<\/code> command to <span class=\"sc\">gdb<\/span> after an <code>exec<\/code> call executes, the new target restarts. To restart the parent process, use the <code>file<\/code> command with the parent executable name as its argument. By default, after an <code>exec<\/code> call executes, <span class=\"sc\">gdb<\/span> discards the symbols of the previous executable image. You can change this behaviour with the <code>set\u00a0follow-exec-mode<\/code> command. <a name=\"index-set-follow_002dexec_002dmode-205\"><\/a><\/p>\n<dl>\n<dt><code>set follow-exec-mode <\/code><var>mode<\/var><\/dt>\n<dd>Set debugger response to a program call of <code>exec<\/code>. An <code>exec<\/code> call replaces the program image of a process.<code>follow-exec-mode<\/code> can be:<\/p>\n<dl>\n<dt><code>new<\/code><\/dt>\n<dd><span class=\"sc\">gdb<\/span> creates a new inferior and rebinds the process to this new inferior. The program the process was running before the <code>exec<\/code> call can be restarted afterwards by restarting the original inferior.For example:<\/p>\n<pre class=\"smallexample\">               (gdb) info inferiors\r\n               (gdb) info inferior\r\n                 Id   Description   Executable\r\n               * 1    &lt;null&gt;        prog1\r\n               (gdb) run\r\n               process 12020 is executing new program: prog2\r\n               Program exited normally.\r\n               (gdb) info inferiors\r\n                 Id   Description   Executable\r\n                 1    &lt;null&gt;        prog1\r\n               * 2    &lt;null&gt;        prog2\r\n<\/pre>\n<\/dd>\n<dt><code>same<\/code><\/dt>\n<dd><span class=\"sc\">gdb<\/span> keeps the process bound to the same inferior. The new executable image replaces the previous executable loaded in the inferior. Restarting the inferior after the <code>exec<\/code> call, with e.g., the <code>run<\/code> command, restarts the executable the process was running after the <code>exec<\/code> call. This is the default mode.For example:<\/p>\n<pre class=\"smallexample\">               (gdb) info inferiors\r\n                 Id   Description   Executable\r\n               * 1    &lt;null&gt;        prog1\r\n               (gdb) run\r\n               process 12020 is executing new program: prog2\r\n               Program exited normally.\r\n               (gdb) info inferiors\r\n                 Id   Description   Executable\r\n               * 1    &lt;null&gt;        prog2\r\n<\/pre>\n<\/dd>\n<\/dl>\n<\/dd>\n<\/dl>\n<p><code>follow-exec-mode<\/code> is supported in native mode and <code>target extended-remote<\/code> mode.<\/p>\n<p>You can use the <code>catch<\/code> command to make <span class=\"sc\">gdb<\/span> stop whenever a <code>fork<\/code>, <code>vfork<\/code>, or <code>exec<\/code> call is made. See <a href=\"https:\/\/sourceware.org\/gdb\/onlinedocs\/gdb\/Set-Catchpoints.html#Set-Catchpoints\">Setting Catchpoints<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Two\u00a0 Methods: Add sleep in the entry of  &hellip; <a href=\"https:\/\/blog.zhenglei.net\/?p=255692\">\u7ee7\u7eed\u9605\u8bfb <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[342,343,341],"class_list":["post-255692","post","type-post","status-publish","format-standard","hentry","category-linux","tag-debug","tag-fork","tag-gdb"],"_links":{"self":[{"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=\/wp\/v2\/posts\/255692","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=255692"}],"version-history":[{"count":3,"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=\/wp\/v2\/posts\/255692\/revisions"}],"predecessor-version":[{"id":255695,"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=\/wp\/v2\/posts\/255692\/revisions\/255695"}],"wp:attachment":[{"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=255692"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=255692"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zhenglei.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=255692"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}