GDB kasutamine

Allikas: Digilabor

Tüüpiline mure C programmeerimises, et programm kukub kokku ning me ei tea, miks. See peaks olema kiire õpetus, kuidas antud olukorras debuggerit kasutada. Kogu siinse õpetuse toimimiseks on üks suur eeldus - oma programm tuleb kokku kompileerida -g võtmega. Selle võtmega lisab kompilaator/linkur info sümbolite kohta binaarfaili lõppu. "Sümbolid" siis antud juhul on informatsioon, et mis on mingi muutuja nimi ning mis reas, millises lähtekoodi failis on milline käsk assembleris. Selle võtme lisamine koodi reaalselt aeglasemaks ei tee aga aitab väga jamade leidmisel.

Näide:

tonu@hp:~/tyros/tonu$ ./watershed 
OpenCV Error: Assertion failed (arr != 0 && contour_header != 0 && block != 0) in cvPointSeqFromMat, file /home/tonu/Desktop/OpenCV-2.1.0/src/cv/cvutils.cpp, line 47
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/tonu/Desktop/OpenCV-2.1.0/src/cv/cvutils.cpp:47: error: (-215) arr != 0 && contour_header != 0 && block != 0 in function cvPointSeqFromMat

Aborted
tonu@hp:~/tyros/tonu$ 

Probleemi saab lahendada mitut moodi. Üks moodus on linuxis öelda tuumale, et kui mingi protsess kokku kukub, siis me tahame selle mälu seisu sellisena, nagu ta on säilitada:

tonu@hp:~/tyros/tonu$ ulimit -c unlimited
tonu@hp:~/tyros/tonu$ 

Eelnev käsk mõjub ainult sellele aknale, kus ta on antud. Nüüd kävitame programmi uuesti:

tonu@hp:~/tyros/tonu$ ./watershed 
OpenCV Error: Assertion failed (arr != 0 && contour_header != 0 && block != 0) in cvPointSeqFromMat, file /home/tonu/Desktop/OpenCV-2.1.0/src/cv/cvutils.cpp, line 47
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/tonu/Desktop/OpenCV-2.1.0/src/cv/cvutils.cpp:47: error: (-215) arr != 0 && contour_header != 0 && block != 0 in function cvPointSeqFromMat

Aborted (core dumped)
tonu@hp:~/tyros/tonu$ 

Võrreldes eelmise korraga on lisandunud teade Aborted (core dumped). See tähendab, et olukord kokku kukkumise hetkel salvestati faili nimega "core" ning me saame nüüd seda uurida:

tonu@hp:~/tyros/tonu$ gdb ./watershed core
GNU gdb (GDB) 7.1-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 "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tonu/tyros/tonu/watershed...done.
[New Thread 2556]

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /usr/local/lib/libcv.so.2.1...done.
Loaded symbols for /usr/local/lib/libcv.so.2.1
Reading symbols from /usr/local/lib/libcxcore.so.2.1...done.
Loaded symbols for /usr/local/lib/libcxcore.so.2.1
Reading symbols from /usr/local/lib/libcvaux.so.2.1...done.
Loaded symbols for /usr/local/lib/libcvaux.so.2.1
Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/tls/i686/cmov/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/tls/i686/cmov/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /usr/local/lib/libhighgui.so.2.1...done.
Loaded symbols for /usr/local/lib/libhighgui.so.2.1
Reading symbols from /lib/tls/i686/cmov/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libdl.so.2
Reading symbols from /lib/tls/i686/cmov/libpthread.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libpthread.so.0
Reading symbols from /lib/tls/i686/cmov/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/librt.so.1
Reading symbols from /usr/local/lib/libml.so.2.1...done.
Loaded symbols for /usr/local/lib/libml.so.2.1
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /usr/lib/libjpeg.so.62...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libjpeg.so.62
Reading symbols from /lib/libpng12.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libpng12.so.0
Reading symbols from /lib/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libz.so.1
Reading symbols from /usr/lib/libtiff.so.4...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libtiff.so.4
Reading symbols from /usr/lib/libjasper.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libjasper.so.1
Reading symbols from /usr/lib/libgtk-x11-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgtk-x11-2.0.so.0
Reading symbols from /usr/lib/libgdk-x11-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgdk-x11-2.0.so.0
Reading symbols from /usr/lib/libatk-1.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libatk-1.0.so.0
Reading symbols from /usr/lib/libgio-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgio-2.0.so.0
Reading symbols from /usr/lib/libpangoft2-1.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libpangoft2-1.0.so.0
Reading symbols from /usr/lib/libgdk_pixbuf-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgdk_pixbuf-2.0.so.0
Reading symbols from /usr/lib/libpangocairo-1.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libpangocairo-1.0.so.0
Reading symbols from /usr/lib/libcairo.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libcairo.so.2
Reading symbols from /usr/lib/libpango-1.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libpango-1.0.so.0
Reading symbols from /usr/lib/libfreetype.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libfreetype.so.6
Reading symbols from /usr/lib/libfontconfig.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libfontconfig.so.1
Reading symbols from /usr/lib/libgobject-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgobject-2.0.so.0
Reading symbols from /usr/lib/libgmodule-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgmodule-2.0.so.0
Reading symbols from /usr/lib/libgthread-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgthread-2.0.so.0
Reading symbols from /lib/libglib-2.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libglib-2.0.so.0
Reading symbols from /usr/lib/i686/cmov/libavcodec.so.52...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/i686/cmov/libavcodec.so.52
Reading symbols from /usr/lib/i686/cmov/libavformat.so.52...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/i686/cmov/libavformat.so.52
Reading symbols from /usr/lib/i686/cmov/libavutil.so.49...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/i686/cmov/libavutil.so.49
Reading symbols from /usr/lib/i686/cmov/libswscale.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/i686/cmov/libswscale.so.0
Reading symbols from /usr/lib/libdc1394.so.22...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libdc1394.so.22
Reading symbols from /lib/libbz2.so.1.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libbz2.so.1.0
Reading symbols from /usr/lib/libXext.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXext.so.6
Reading symbols from /usr/lib/libXrender.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXrender.so.1
Reading symbols from /usr/lib/libXinerama.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXinerama.so.1
Reading symbols from /usr/lib/libXi.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXi.so.6
Reading symbols from /usr/lib/libXrandr.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXrandr.so.2
Reading symbols from /usr/lib/libXcursor.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXcursor.so.1
Reading symbols from /usr/lib/libX11.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libX11.so.6
Reading symbols from /usr/lib/libXcomposite.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXcomposite.so.1
Reading symbols from /usr/lib/libXdamage.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXdamage.so.1
Reading symbols from /usr/lib/libXfixes.so.3...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXfixes.so.3
Reading symbols from /lib/libpcre.so.3...(no debugging symbols found)...done.
Loaded symbols for /lib/libpcre.so.3
Reading symbols from /lib/tls/i686/cmov/libresolv.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libresolv.so.2
Reading symbols from /lib/libselinux.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libselinux.so.1
Reading symbols from /usr/lib/libpixman-1.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libpixman-1.so.0
Reading symbols from /usr/lib/libdirectfb-1.2.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libdirectfb-1.2.so.0
Reading symbols from /usr/lib/libfusion-1.2.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libfusion-1.2.so.0
Reading symbols from /usr/lib/libdirect-1.2.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libdirect-1.2.so.0
Reading symbols from /usr/lib/libxcb-render-util.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libxcb-render-util.so.0
Reading symbols from /usr/lib/libxcb-render.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libxcb-render.so.0
Reading symbols from /usr/lib/libxcb.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libxcb.so.1
Reading symbols from /lib/libexpat.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libexpat.so.1
Reading symbols from /usr/lib/libgsm.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgsm.so.1
Reading symbols from /usr/lib/libschroedinger-1.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libschroedinger-1.0.so.0
Reading symbols from /usr/lib/sse2/libspeex.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/sse2/libspeex.so.1
Reading symbols from /usr/lib/libtheora.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libtheora.so.0
Reading symbols from /usr/lib/libvorbisenc.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libvorbisenc.so.2
Reading symbols from /usr/lib/libvorbis.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libvorbis.so.0
Reading symbols from /usr/lib/libraw1394.so.11...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libraw1394.so.11
Reading symbols from /lib/libusb-1.0.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libusb-1.0.so.0
Reading symbols from /usr/lib/libXau.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXau.so.6
Reading symbols from /usr/lib/libXdmcp.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXdmcp.so.6
Reading symbols from /usr/lib/liboil-0.3.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/liboil-0.3.so.0
Reading symbols from /usr/lib/libogg.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libogg.so.0
Reading symbols from /lib/tls/i686/cmov/libnss_compat.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libnss_compat.so.2
Reading symbols from /lib/tls/i686/cmov/libnsl.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libnsl.so.1
Reading symbols from /lib/tls/i686/cmov/libnss_nis.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libnss_nis.so.2
Reading symbols from /lib/tls/i686/cmov/libnss_files.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libnss_files.so.2
Reading symbols from /usr/lib/gtk-2.0/modules/libcanberra-gtk-module.so...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/gtk-2.0/modules/libcanberra-gtk-module.so
Reading symbols from /usr/lib/libcanberra-gtk.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libcanberra-gtk.so.0
Reading symbols from /usr/lib/libcanberra.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libcanberra.so.0
Reading symbols from /usr/lib/libvorbisfile.so.3...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libvorbisfile.so.3
Reading symbols from /usr/lib/libtdb.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libtdb.so.1
Reading symbols from /usr/lib/libltdl.so.7...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libltdl.so.7
Reading symbols from /usr/lib/gtk-2.0/2.10.0/engines/libmurrine.so...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/gtk-2.0/2.10.0/engines/libmurrine.so
Core was generated by `./watershed'.
Program terminated with signal 6, Aborted.
#0  0x00ef8422 in __kernel_vsyscall ()
(gdb) 

Järgmine käsk on "backtrace" ehk siis vaatame stäkki:

(gdb) bt
#0  0x00ef8422 in __kernel_vsyscall ()
#1  0x00a23651 in raise () from /lib/tls/i686/cmov/libc.so.6
#2  0x00a26a82 in abort () from /lib/tls/i686/cmov/libc.so.6
#3  0x009c252f in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/libstdc++.so.6
#4  0x009c0465 in ?? () from /usr/lib/libstdc++.so.6
#5  0x009c04a2 in std::terminate() () from /usr/lib/libstdc++.so.6
#6  0x009c05e1 in __cxa_throw () from /usr/lib/libstdc++.so.6
#7  0x002f8444 in cv::error(cv::Exception const&) () from /usr/local/lib/libcxcore.so.2.1
#8  0x007ca0af in cvPointSeqFromMat () from /usr/local/lib/libcv.so.2.1
#9  0x007cd976 in cvConvexHull2 () from /usr/local/lib/libcv.so.2.1
#10 0x08048f34 in main (argc=1, argv=0xbfdc2154) at watershed.cpp:104
(gdb) 

Siit saame juba esimese info kätte, et programm kukkus kokku meie koodis failis watershed.cpp reas 104. Nüüd on järgmine suur küsimus, et miks ikkagi reas 104 asi kokku kukkus? Üldjuhul on mingi muutuja kuskil ennem metsa läinud ja sisaldab nulli. Või siis püütakse näppida mingit mälu, mis ei kuulu meile. Käskudega "up" ja "down" saab liikuda mööda stäkki endale vajaliku kohani. Antud juhul palun minna 10 taset üles:

(gdb) up 10
#10 0x08048f34 in main (argc=1, argv=0xbfdc2154) at watershed.cpp:104
104		    seqhull = cvConvexHull2(contours, 0, CV_COUNTER_CLOCKWISE, 0);
(gdb) 

Nüüd olemegi debuggeriga selles kontekstis, kus on meie programm watersched.cpp reas 104 ning me saame küsida igasugu asju tema kohta, eelkõige muutujaid:

(gdb) p contours
$1 = (CvSeq *) 0x0
(gdb) 

Ilmselgelt on siin miskit valesti. Argument antud funktsioonile ei peaks tühi olema. Saab küsida ka kõiki lokaalseid muutujaid korraga:

(gdb) info locals
contours = 0x0
color_tab = 0x0
c = 0
filename = <value optimized out>
(gdb) 

Globaalseid muutujaid näeb käsuga "info variables":

(gdb) info variables
All defined variables:

File watershed.cpp:
IplImage *img;
IplImage *img0;
IplImage *img_gray;
IplImage *imgtmp;
IplImage *marker_mask;
IplImage *markers;
CvPoint prev_pt;
IplImage *wshed;

Non-debugging symbols:
0x08049098  _fp_hw
0x0804909c  _IO_stdin_used
0x08049268  __FRAME_END__
...

Struktuuridesse saab ka sisse vaadata kui lisada muutuja ette tärn:

(gdb) p img
$4 = (IplImage *) 0xa09f240
(gdb) p *img
$5 = {nSize = 112, ID = 0, nChannels = 3, alphaChannel = 0, depth = 8, colorModel = "RGB", channelSeq = "BGR", dataOrder = 0, origin = 0, align = 4, width = 640, height = 480, roi = 0x0, maskROI = 0x0, 
  imageId = 0x0, tileInfo = 0x0, imageSize = 921600, 
  imageData = 0xb734c010 "*St*Su+Tu+Tu+Tu*St)Rs*Rs,Rt,Rt,Rt+Qt+Qt+Qs+Rt*Pr+Qs,Rt+Qs*Pr)Oq)Oq)Oq)Oq)Oq*Pr*Pr)Oq(Np(No)Pp(Pm'Ol'Ol)Om)Om(Nl(Mk'Mk'Mk'Mk)Mk)Mk(Lj(Lj&Ll&Ll&Ll&Ll&Ll&Ll&Ll'Ml(Nk(Ok(Oi&Of&Of&Oe&Oe)Pf(Oe)Oe)Pf)Rh+Ti+T"..., widthStep = 1920, BorderMode = {0, 0, 0, 0}, BorderConst = {0, 0, 0, 0}, 
  imageDataOrigin = 0xb734c010 "*St*Su+Tu+Tu+Tu*St)Rs*Rs,Rt,Rt,Rt+Qt+Qt+Qs+Rt*Pr+Qs,Rt+Qs*Pr)Oq)Oq)Oq)Oq)Oq*Pr*Pr)Oq(Np(No)Pp(Pm'Ol'Ol)Om)Om(Nl(Mk'Mk'Mk'Mk)Mk)Mk(Lj(Lj&Ll&Ll&Ll&Ll&Ll&Ll&Ll'Ml(Nk(Ok(Oi&Of&Of&Oe&Oe)Pf(Oe)Oe)Pf)Rh+Ti+T"...}
(gdb) 


GDB eellaadimine

Debugida saab ka nii, et ulimit käsku mitte kasutada ja gdb kohe programmi alla laadida. Selle meetodi puudus on, et programmi töö muutub järsult aeglasemaks. Oluline on tähele panna, et meie programmile vajalikud argumendid ei tohi kaasa anda esmase gdb käivitamise käsuga, vaid hiljem argumendina "run" käsule:

tonu@hp:~/tyros/tonu$ gdb ./watershed 
GNU gdb (GDB) 7.1-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 "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tonu/tyros/tonu/watershed...done.
(gdb) run snow_flake_06664_8.jpg
Starting program: /home/tonu/tyros/tonu/watershed snow_flake_06664_8.jpg
[Thread debugging using libthread_db enabled]

Program exited with code 01.
(gdb) 

Antud meetodi eelis on see, et me saame debuggeril paluda mingeid asju teha ka enne kokku kukkumist.

Lõimed

Lõimedega gdb kasutamine ei ole tegelikult väga keeruline. Lihtsalt võtame lõimede nimekirja käsuga "info treads" ning siis valime sealt tööks sobiva:

(gdb) info threads
* 1 Thread 0xb7fd3730 (LWP 2867)  0x0012d422 in __kernel_vsyscall ()
(gdb) thread 1
[Switching to thread 1 (Thread 0xb7fd3730 (LWP 2867))]#0  0x0012d422 in __kernel_vsyscall ()
(gdb) 

Muu

Fail "core" on reaalselt kasulik ainult masinas, milles ta tekkis. Mujal arvutites on teekidest muud versioonid ning seal ei kajasta core enam tegelikkust. Seega üldjuhul ei ole abi tema kellelegi saatmisest.

Personaalsed tööriistad
Navigeerimine
Käsitöö