{"id":34,"date":"2009-07-01T01:07:36","date_gmt":"2009-07-01T00:07:36","guid":{"rendered":"http:\/\/slack.codemaniacs.com\/blog\/?p=34"},"modified":"2009-07-01T01:07:53","modified_gmt":"2009-07-01T00:07:53","slug":"crash-handling","status":"publish","type":"post","link":"https:\/\/slack.codemaniacs.com\/blog\/2009\/07\/01\/crash-handling\/","title":{"rendered":"crash handling"},"content":{"rendered":"<p>Estaba yo pregunt\u00c3\u00a1ndome esta tarde si ser\u00c3\u00ada posible lanzar de forma autom\u00c3\u00a1tica <code>gdb<\/code> cuando un programa cascara, sin necesidad de ponerse a depurar despu\u00c3\u00a9s, reproducir el bug, etc, al estilo del manejador de errores que instala Visual Studio en Windows que pregunta si se desea depurar la aplicaci\u00c3\u00b3n.<\/p>\n<p>Me ha salido algo como esto (HTML horrible para el coloreado de sintaxis patrocinado por Vim):<br \/>\n<font face=\"monospace\"><br \/>\n<\/font><font color=\"#a020f0\">#include <\/font><font color=\"#ff00ff\">&lt;sys\/types.h&gt;<\/font><br \/>\n<font color=\"#a020f0\">#include <\/font><font color=\"#ff00ff\">&lt;unistd.h&gt;<\/font><br \/>\n<font color=\"#a020f0\">#include <\/font><font color=\"#ff00ff\">&lt;signal.h&gt;<\/font><br \/>\n<font color=\"#a020f0\">#include <\/font><font color=\"#ff00ff\">&lt;stdio.h&gt;<\/font><br \/>\n<font color=\"#a020f0\">#include <\/font><font color=\"#ff00ff\">&lt;stdlib.h&gt;<\/font><\/p>\n<p><font color=\"#2e8b57\"><b>void<\/b><\/font>&nbsp;attach_gdb(<font color=\"#2e8b57\"><b>int<\/b><\/font>&nbsp;signum)<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;pid_t gdbpid;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;pid_t debuggee_pid = getpid();<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"#2e8b57\"><b>int<\/b><\/font>&nbsp;gdb_exit_status;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"#2e8b57\"><b>char<\/b><\/font>&nbsp;pidbuf[<font color=\"#ff00ff\">100<\/font>];<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"#2e8b57\"><b>char<\/b><\/font>&nbsp;exebuf[<font color=\"#ff00ff\">100<\/font>]; <font color=\"#0000ff\">\/\/ should be safe unless PIDs reach ~90 digits ;P<\/font><br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pidbuf, <font color=\"#ff00ff\">&quot;<\/font><font color=\"#6a5acd\">%d<\/font><font color=\"#ff00ff\">&quot;<\/font>, debuggee_pid);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sprintf(exebuf, <font color=\"#ff00ff\">&quot;\/proc\/<\/font><font color=\"#6a5acd\">%d<\/font><font color=\"#ff00ff\">\/exe&quot;<\/font>, debuggee_pid);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;printf(<font color=\"#ff00ff\">&quot;Signal <\/font><font color=\"#6a5acd\">%d<\/font><font color=\"#ff00ff\">&nbsp;received. Attaching GDB to process. PID=<\/font><font color=\"#6a5acd\">%d<\/font><font color=\"#6a5acd\">\\n<\/font><font color=\"#ff00ff\">&quot;<\/font>, signum, debuggee_pid);<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"#a52a2a\"><b>if<\/b><\/font>&nbsp;((gdbpid = fork()) == <font color=\"#ff00ff\">0<\/font>)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;execlp(<font color=\"#ff00ff\">&quot;gdb&quot;<\/font>, <font color=\"#ff00ff\">&quot;gdb&quot;<\/font>, exebuf, pidbuf, <font color=\"#ff00ff\">NULL<\/font>);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(<font color=\"#ff00ff\">&quot;execlp&quot;<\/font>);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(<font color=\"#ff00ff\">1<\/font>);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;waitpid(gdbpid, &amp;gdb_exit_status, <font color=\"#ff00ff\">0<\/font>); <font color=\"#0000ff\">\/\/ hold on, we want to be debugged<\/font><br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;exit(<font color=\"#ff00ff\">1<\/font>);<br \/>\n}<\/p>\n<p><font color=\"#2e8b57\"><b>void<\/b><\/font>&nbsp;__attribute__((constructor)) setup_handler()<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"#2e8b57\"><b>struct<\/b><\/font>&nbsp;sigaction sa, old_sa;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sa.sa_handler = attach_gdb;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sigemptyset(&amp;sa.sa_mask);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sa.sa_flags=<font color=\"#ff00ff\">0<\/font>;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"#0000ff\">\/\/ Register the handler for all actions which dump core by default<\/font><br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color=\"#ff00ff\">SIGSEGV<\/font>, &amp;sa, &amp;old_sa);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color=\"#ff00ff\">SIGFPE<\/font>, &amp;sa, &amp;old_sa);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color=\"#ff00ff\">SIGABRT<\/font>, &amp;sa, &amp;old_sa);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color=\"#ff00ff\">SIGILL<\/font>, &amp;sa, &amp;old_sa);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color=\"#ff00ff\">SIGQUIT<\/font>, &amp;sa, &amp;old_sa);<br \/>\n}<\/p>\n<p>Si se compila como librer\u00c3\u00ada din\u00c3\u00a1mica y se enlaza a cualquiera de nuestros programas (o se precarga con <code>LD_PRELOAD<\/code>) lanza un <code>gdb<\/code> asociado al proceso al recibir cualquiera de las se\u00c3\u00b1ales que causar\u00c3\u00adan un core dump y terminaci\u00c3\u00b3n del programa :D.<\/p>\n<p>\u00c2\u00bfAlguna idea para mejorarlo y que sea pr\u00c3\u00a1ctico? \u00c2\u00bfExiste ya algo asi en un paquete Debian que hace mil cosas molonas m\u00c3\u00a1s? (seguro que s\u00c3\u00ad XD).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Estaba yo pregunt\u00c3\u00a1ndome esta tarde si ser\u00c3\u00ada posible lanzar de forma autom\u00c3\u00a1tica gdb cuando un programa cascara, sin necesidad de ponerse a depurar despu\u00c3\u00a9s, reproducir el bug, etc, al estilo del manejador de errores que instala Visual Studio en Windows que pregunta si se desea depurar la aplicaci\u00c3\u00b3n. Me ha salido algo como esto (HTML [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts\/34"}],"collection":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":11,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions"}],"predecessor-version":[{"id":45,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions\/45"}],"wp:attachment":[{"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/media?parent=34"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/categories?post=34"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/slack.codemaniacs.com\/blog\/wp-json\/wp\/v2\/tags?post=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}