{"id":734,"date":"2012-02-14T22:04:29","date_gmt":"2012-02-14T22:04:29","guid":{"rendered":"http:\/\/tromey.com\/blog\/?p=734"},"modified":"2012-02-14T22:04:29","modified_gmt":"2012-02-14T22:04:29","slug":"debugging-multiple-programs-at-once","status":"publish","type":"post","link":"https:\/\/tromey.com\/blog\/?p=734","title":{"rendered":"Debugging multiple programs at once"},"content":{"rendered":"<p>Consider this Makefile:<\/p>\n<pre>all: runit\r\n\r\nrunit: crasher\r\n\t.\/crasher\r\n\r\ncrasher: crasher.c\r\n\tgcc -g -o crasher crasher.c<\/pre>\n<p>And, here is the program it is building:<\/p>\n<pre>int *x = 0;\r\n\r\nint main ()\r\n{\r\n  *x = 52;\r\n}<\/pre>\n<p>Now, if you run &#8220;<code>make<\/code>&#8220;, eventually you will see a crash.\u00a0 But how to debug the crash?<\/p>\n<p>Well, obviously, this is a trivial example so you&#8217;d just debug the program.\u00a0 But what if you had a complex script involving extensive and obscure initialization?\u00a0 Say, in your test suite?\u00a0 The traditional answer is logging plus cut and paste into gdb; or perhaps hacking an invocation of <code>gdb --args<\/code> into your script.\u00a0 Nowadays you can do better, though.<\/p>\n<p>Let&#8217;s start by debugging make:<\/p>\n<pre>$ gdb -quiet make\r\nReading symbols from \/usr\/bin\/make...(no debugging symbols found)...done.\r\nMissing separate debuginfos, use: debuginfo-install make-3.82-8.fc16.x86_64<\/pre>\n<p>Now set things up for multi-inferior debugging:<\/p>\n<pre>(gdb) set detach-on-fork off\r\n(gdb) set target-async on\r\n(gdb) set non-stop on\r\n(gdb) set pagination off<\/pre>\n<p>(Yes, it is silly how many settings you have to tweak; and yes, we&#8217;re going to fix this.)<\/p>\n<p>Now do it:<\/p>\n<pre>(gdb) run\r\nStarting program: \/usr\/bin\/make\r\ngcc -g -o crasher crasher.c\r\n[New inferior 9694]\r\n[New process 9694]\r\nprocess 9694 is executing new program: \/usr\/bin\/gcc\r\n[New inferior 9695]\r\n[New process 9695]\r\nprocess 9695 is executing new program: \/usr\/libexec\/gcc\/x86_64-redhat-linux\/4.6.2\/cc1\r\nMissing separate debuginfos, use: debuginfo-install gcc-4.6.2-1.fc16.x86_64\r\n[Inferior 3 (process 9695) exited normally]\r\n[Inferior 9695 exited]\r\nMissing separate debuginfos, use: debuginfo-install cpp-4.6.2-1.fc16.x86_64\r\n(gdb) [New inferior 9696]\r\n[New process 9696]\r\nprocess 9696 is executing new program: \/usr\/bin\/as\r\n[Inferior 4 (process 9696) exited normally]\r\n[Inferior 9696 exited]\r\n[New inferior 9697]\r\n[New process 9697]\r\nprocess 9697 is executing new program: \/usr\/libexec\/gcc\/x86_64-redhat-linux\/4.6.2\/collect2\r\nMissing separate debuginfos, use: debuginfo-install binutils-2.21.53.0.1-6.fc16.x86_64\r\n[New inferior 9698]\r\n[New process 9698]\r\nprocess 9698 is executing new program: \/usr\/bin\/ld.bfd\r\nMissing separate debuginfos, use: debuginfo-install gcc-4.6.2-1.fc16.x86_64\r\n[Inferior 6 (process 9698) exited normally]\r\n[Inferior 9698 exited]\r\n[Inferior 5 (process 9697) exited normally]\r\n[Inferior 9697 exited]\r\n[Inferior 2 (process 9694) exited normally]\r\n[Inferior 9694 exited]\r\n.\/crasher\r\n[New inferior 9699]\r\n[New process 9699]\r\nprocess 9699 is executing new program: \/tmp\/crasher\r\nMissing separate debuginfos, use: debuginfo-install binutils-2.21.53.0.1-6.fc16.x86_64\r\n\r\nProgram received signal SIGSEGV, Segmentation fault.\r\n0x000000000040047f in main () at crasher.c:5\r\n5\u00a0\u00a0 \u00a0\u00a0 *x = 52;<\/pre>\n<p>Cool stuff.\u00a0 Now you can inspect the crashed program:<\/p>\n<pre>(gdb) info inferior\r\nNum\u00a0 Description\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Executable\r\n  7\u00a0\u00a0\u00a0 process 9699\u00a0\u00a0\u00a0\u00a0\u00a0 \/tmp\/crasher\r\n* 1\u00a0\u00a0\u00a0 process 9691\u00a0\u00a0\u00a0\u00a0\u00a0 \/usr\/bin\/make\r\n(gdb) inferior 7\r\n[Switching to inferior 7 [process 9699] (\/tmp\/crasher)]\r\n[Switching to thread 7 (process 9699)]\r\n#0\u00a0 0x000000000040047f in main () at crasher.c:5\r\n5\u00a0\u00a0 \u00a0\u00a0 *x = 52;<\/pre>\n<p>There is still a lot of work to do here &#8212; it is still a bit too slow, setting breakpoints is still a pain, etc. These are all things we&#8217;re going to be cleaning up in the coming year.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Consider this Makefile: all: runit runit: crasher .\/crasher crasher: crasher.c gcc -g -o crasher crasher.c And, here is the program it is building: int *x = 0; int main () { *x = 52; } Now, if you run &#8220;make&#8220;, eventually you will see a crash.\u00a0 But how to debug the crash? Well, obviously, this [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,2],"tags":[],"class_list":["post-734","post","type-post","status-publish","format-standard","hentry","category-gdb","category-software"],"_links":{"self":[{"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/734","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=734"}],"version-history":[{"count":7,"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/734\/revisions"}],"predecessor-version":[{"id":797,"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/734\/revisions\/797"}],"wp:attachment":[{"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tromey.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}