Cpp debug
Il programma DDD é un'alternativa decente a gdb senza perderne funzionalità utili e simili a quelle disponibili nel debugger di VisualStudio. Il problema é che cose come divisione per zero non generano exceptions in Linux, ma segnali che possono essere catturati con strumenti più 'antichi' e che non garantiscono che il programma continui normalmente.
Il problema fondamentale non é la divisione per zero, ma che un programmatore non ha testato questa eventualità e scelto cosa fare (in questo caso ha perfettamente senso che il programma non continui!). In queste situazioni è necessario che il programma segnali il problema prima di terminare, in questo modo il programmatore potrá individuare e correggere il problema.
Quello che si potrebbe fare è generare un dump della memoria e analizzarlo. In Linux è semplice ottenere il dump, è necessario indicare
ulimit -c unlimited
prima di eseguire il programma.
Per Windows dovrebbe esserci uno strumento simile. Quello che segue é un estratto di una discussione su Usenet:
On Nov 6, 10:44 am, t1t0 <t...@noemail.not> wrote: > On Sun, 06 Nov 2011 01:15:05 +0000, Kaz Kylheku wrote: > > You can catch an exception (in every thread) and then use the API to > > list the modules, snapshot the thread state and such. > > But what about signal error (like zero division)? Did Windows produce a > signal error or a exception for this kind of error? yes divide by zero generates on exception on Windows. There are ways to turn this into text. > > I wrote a crash dump reporter on Windows CE quite a few years ago. It > > was very helpful, because crashing programs would just "disappear > > without a trace" on that platform > > Nice, this is exactly what I want to avoid at all costs: the death of the > application without trace! > So, on Windows there is an API to create a core dump, or is it a 'manual' > implementation ? search MSDN. I found MiniDumpWriteDump(),though my experience of Windows minidumps is that they're a bit too limited.
From http://www.codeproject.com/Articles/6230/Auto-Memory-Dump-on-Crash-of-an-Application
We can make a debugger automatically pop up whenever an application crashes. This type of debugger is called a post mortem or JIT Debugger and they can also automatically generate a crash memory dump [...] To set WinDbg to automatically generate a memory dump file when a program crashes, it is necessary to edit the registry. On an x86 computer, the postmortem settings are stored in the \\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug key.
Sembra sia possibile automatizzare il processo di creazione del dump:
- http://kb.acronis.com/content/6265
- http://kb.acronis.com/content/2191
- http://kb.acronis.com/content/2192
Una soluzione quasi ideale sarebbe creare un Guardian, ovvero un programma minimale (confidabile, che non abbia errori) che preparerebbe l'ambiente e inizierebbe l'applicazione e in caso di crash invierebbe un email con il crashdump e reinizierebbe l'applicazione di nuovo.
Resta il fatto che per ottenere informazioni utili dal coredump, il programma dovrebbe essere compilato con le informazioni di debug, cosa che permetterebbe di ottenerne il codice sorgente. Una soluzione in Linux é compilare con le informazioni di debug e usare in produzione una copia 'pulita' con il comando strip:
from http://stackoverflow.com/questions/2251391/core-dump-in-linux
The usual solution is to build with -g and to strip off the debug information before releasing the file. Look for the 'strip' command. You keep the file with debug information and use it to debug core dumps you get from customers.
from http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html
gdb allows you to put a program's debugging information in a file separate from the executable itself, in a way that allows gdb to find and load the debugging information automatically. [...] The gnu binary utilities (Binutils) package includes the `objcopy' utility that can produce the separated executable / debugging information file pairs using the following commands: objcopy --only-keep-debug foo foo.debug strip -g foo
GDB
gcc -g -O0 src/main.c -o ./main # compile with debug info and without optimization ulimit -c unlimited # enable core dump objdump --syms ./main | less # test debug symbols existance ./main # run the program with a fatal error, producing a core archive e.g. core.27133 gdb -tui ./main -c ./core.27133 -d ./src # run the debuger bt full # see the full callstack
For more GDB commands, see GDB quick reference card, version 5.
- from
- http://stackoverflow.com/a/22711917
- http://stackoverflow.com/a/22711917
- http://sourceware.org/gdb/current/onlinedocs/gdb/TUI.html
libSegFault.so
from http://groleo.wordpress.com/2010/05/04/when-you-cant-use-gdb-or-valgrind-there-is-liblibsegfault-so/
Under certain conditions I can’t get gdb or valgrind to work on my binary and I don’t want any delays from them. And I just wanted to see where the binary segfaulted so I remembered of /lib/libSegFault.so. LD_PRELOAD=/lib/libSegFault.so executable Backtrace: /lib/libSegFault.so(+0x206f)[0x11206f] [0x9d1400] executable[0x805994d] executable[0x8059a0d] executable[0x805d043] executable[0x8057d59] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xae5bd6] executable[0x8048e81] Now I use addr2line to translate the addresses to locations in binary: addr2line -e executable 0x805994d 0x8059a0d 0x805d043 0x8057d59 sm.c:505 sm.c:564 tmr.c:104 main.c:155 Thats it .
For more details, see linux_LD_PRELOAD
Get human readable signal message
#include <signal.h> #include <stdio.h> #include <stdlib.h> static void catch_function(int signal) { extern const char *const sys_siglist[]; printf( "Interactive attention signal caught: '%d', message: '%s'\n", signal, sys_siglist[signal] ); } int main(void) { if (signal(SIGINT, catch_function) == SIG_ERR) { fputs("An error occurred while setting a signal handler.\n", stderr); return EXIT_FAILURE; } puts("Raising the interactive attention signal."); if (raise(SIGINT) != 0) { fputs("Error raising the signal.\n", stderr); return EXIT_FAILURE; } puts("Exiting."); return 0; }