-
Notifications
You must be signed in to change notification settings - Fork 0
CxxDebuggingTutorial
Preliminary version.
The C library uses a couple of environment variables to turn on/off debugging of malloc/free: check http://www.scratchbox.org/documentation/general/tutorials/glibcenv.html and http://tr.opensuse.org/SDB:Debugging_with_Glibc
The GNU Debugger is a valuable tool to debug programs. Check out the guide to debugging with gdb . Enter the gdb shell with
$ gdb myprog
GNU gdb (GDB) 7.2-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from myprog...(no debugging symbols found)...done.
(gdb) run
Starting program: myprog
[Thread debugging using libthread_db enabled]
... output of myprog ...
Program received signal SIGABRT, Aborted.
0x00007ffff5fa6ba5 in raise (sig=<value optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
in ../nptl/sysdeps/unix/sysv/linux/raise.c
(gdb) backtrace
#0 0x00007ffff5fa6ba5 in raise (sig=<value optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff5faa6b0 in abort () at abort.c:92
#2 0x00007ffff5fe043b in __libc_message (do_abort=<value optimized out>, fmt=<value optimized out>) at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#3 0x00007ffff5fea4b6 in malloc_printerr (action=3, str=0x7ffff60baca2 "corrupted double-linked list", ptr=<value optimized out>) at malloc.c:6283
#4 0x00007ffff5fed921 in _int_free (av=0x7ffff62f1e40, p=0x7f0510) at malloc.c:4973
#5 0x00007ffff5ff0c83 in __libc_free (mem=<value optimized out>) at malloc.c:3738
#6 0x00007ffff5fac525 in __run_exit_handlers (status=1) at exit.c:87
#7 exit (status=1) at exit.c:100
#8 0x00007ffff5f91d95 in __libc_start_main (main=<value optimized out>, argc=<value optimized out>, ubp_av=<value optimized out>,
init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>, stack_end=0x7fffffffe088) at libc-start.c:258
#9 0x0000000000411569 in _start ()
(gdb) quit
Inside the shell, you can set breakpoints, step through the computation, and much more. The GDB refcard gives you a quick overview of available operations.
Valgrind helps you detect memory errors.
$ valgrind --leak-check=full myprog ==30691== Memcheck, a memory error detector ==30691== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. ==30691== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==30691== Command: myprog ==30691== [...] # output of myprog ==30691== ==30691== HEAP SUMMARY: ==30691== in use at exit: 0 bytes in 0 blocks ==30691== total heap usage: 1,711 allocs, 1,711 frees, 140,800 bytes allocated ==30691== ==30691== All heap blocks were freed -- no leaks are possible ==30691== ==30691== For counts of detected and suppressed errors, rerun with: -v ==30691== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
The valgrind manual is available here: http://valgrind.org/docs/manual/. Impatient people can check http://valgrind.org/docs/manual/quick-start.html.
strace is a linux tool that traces system calls. A manual is available at http://linux.die.net/man/1/strace
$ strace myprog
[...]
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(5001), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(38548), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
close(3) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 12), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb325701000
epoll_create(20000) = 3
eventfd2(0, 0) = 4
fcntl(4, F_SETFL, O_RDONLY|O_NONBLOCK) = 0
epoll_ctl(3, EPOLL_CTL_ADD, 4, {EPOLLIN|EPOLLERR, {u32=4, u64=4}}) = 0
write(2, "Client::Client() ", 18Client::Client() ) = 18
write(2, "127.0.0.1:5001", 14127.0.0.1:5001) = 14
write(2, "\n", 1
[...]
On OS X, you can use dtruss instead.
As part of the binutils, gprof is used to show profiling information of your program (check also the gprof manual). Here is how. Just compile your code with gcc option -pg. If you are using autoconf/automake, just run:
$ ./configure CXXFLAGS="-pg" $ make
Alternatively, you can run
$ make -e CXXFLAGS="-pg"
Then, execute your program as usual:
$ myprog
myprog will then automagically generate a file called gmon.out which logs call information. You can then analyze the calls of above program run using
$ gprof myprog Flat profile: Each sample counts as 0.01 seconds. no time accumulated % cumulative self self total time seconds seconds calls Ts/call Ts/call name 0.00 0.00 0.00 562 0.00 0.00 boost::detail::atomic_exchange_and_add(int*, int) 0.00 0.00 0.00 485 0.00 0.00 boost::detail::sp_counted_base::release() 0.00 0.00 0.00 212 0.00 0.00 boost::detail::shared_count::~shared_count() 0.00 0.00 0.00 161 0.00 0.00 boost::detail::shared_count::shared_count(boost::detail::shared_count const&) 0.00 0.00 0.00 132 0.00 0.00 boost::detail::atomic_increment(int*) 0.00 0.00 0.00 131 0.00 0.00 boost::detail::sp_counted_base::add_ref_copy() 0.00 0.00 0.00 77 0.00 0.00 boost::detail::sp_counted_base::weak_release() 0.00 0.00 0.00 77 0.00 0.00 boost::detail::sp_counted_base::destroy() 0.00 0.00 0.00 34 0.00 0.00 boost::detail::sp_counted_base::sp_counted_base() 0.00 0.00 0.00 34 0.00 0.00 boost::detail::sp_counted_base::~sp_counted_base() 0.00 0.00 0.00 33 0.00 0.00 boost::detail::sp_enable_shared_from_this(...) 0.00 0.00 0.00 27 0.00 0.00 boost::unit_test::ut_detail::bcs_char_traits_impl<char const>::eq(char, char) 0.00 0.00 0.00 19 0.00 0.00 boost::noncopyable_::noncopyable::noncopyable() 0.00 0.00 0.00 19 0.00 0.00 boost::detail::shared_count::shared_count() 0.00 0.00 0.00 18 0.00 0.00 boost::mutex::mutex() 0.00 0.00 0.00 17 0.00 0.00 boost::noncopyable_::noncopyable::~noncopyable() 0.00 0.00 0.00 17 0.00 0.00 boost::condition_variable::condition_variable() 0.00 0.00 0.00 15 0.00 0.00 boost::condition_variable::~condition_variable() 0.00 0.00 0.00 15 0.00 0.00 boost::mutex::~mutex() 0.00 0.00 0.00 15 0.00 0.00 std::exception::exception() 0.00 0.00 0.00 14 0.00 0.00 boost::date_time::int_adapter<long>::int_adapter(long) [...]
static code analysis tools include cppcheck, splint, clang
Using clang is easy. Just run
$ ./configure CC=clang CXX=clang++ $ make
and you will automatically compile your sourcecode with clang.
mutextrace, leakcheck, electric-fence, google-perftools