Archive

Posts Tagged ‘gdb’

Setting up Pretty Printers in GDB

July 2nd, 2014 No comments

There’s an official page on gcc website: https://sourceware.org/gdb/wiki/STLSupport. And here is how to set up it under Ubuntu.

Under Ubuntu 12.04(Precise), simply install the libstdc++6 debug package. It includes the python script for pretty printers:

# sudo apt-get install libstdc++6-4.6-dbg

Create a .gdbinit file in your home directory, with the content:

python
import sys
sys.path.insert(0, '/usr/share/gcc-4.6/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

My test program looks like:

#include <string>
#include <vector>
using namespace std;

int main()
{
    string s = "test";
    vector<int> vi;
    vi.push_back(1);
    vi.push_back(2);
    vi.push_back(3);
    return 0;
}

Build it with debugging enabled(-g):

# g++ -g test.cpp -o test

Debug it with GDB:

# gdb -q test 
Reading symbols from /home/gonwan/test...done.
(gdb) b 12
Breakpoint 1 at 0x8048842: file test.cpp, line 12.
(gdb) r
Starting program: /home/gonwan/test 

Breakpoint 1, main () at test.cpp:12
12	    return 0;
(gdb) p s
$1 = "test"
(gdb) p vi
$2 = std::vector of length 3, capacity 4 = {1, 2, 3}
(gdb) 

Without pretty printers, the output is tedious and hard to understand:

$ gdb -q test 
Reading symbols from /home/gonwan/test...done.
(gdb) set print pretty
(gdb) b 12
Breakpoint 1 at 0x8048842: file test.cpp, line 12.
(gdb) r
Starting program: /home/gonwan/test 

Breakpoint 1, main () at test.cpp:12
12	    return 0;
(gdb) p s
$1 = {
  static npos = <optimized out>, 
  _M_dataplus = {
    <std::allocator<char>> = {
      <__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    members of std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider: 
    _M_p = 0x804c014 "test"
  }
}
(gdb) p vi
$2 = {
  <std::_Vector_base<int, std::allocator<int> >> = {
    _M_impl = {
      <std::allocator<int>> = {
        <__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, 
      members of std::_Vector_base<int, std::allocator<int> >::_Vector_impl: 
      _M_start = 0x804c040, 
      _M_finish = 0x804c04c, 
      _M_end_of_storage = 0x804c050
    }
  }, <No data fields>}
(gdb) 

Under Ubuntu 14.04(Trusty), the 4.8 version of debug package should be installed:

# sudo apt-get install libstdc++6-4.8-dbg

There’s an additional step. Since GDB in Trusty is built with python3, not python2, and the python scripts for pretty printers are in python2 syntax. A simple conversion is required:

# sudo 2to3 -w /usr/share/gcc-4.8/python/libstdcxx/v6/printers.py

Backup it before conversion if neccessary.

Categories: C/C++ Tags: ,

Debug Qt Libraries with Ubuntu Debug Packages

March 28th, 2011 No comments

In previous articles, I was not able to use Qt’s debug package provided by Ubuntu. Now, I will explain how to use them.

Our simple application:

// main.cpp
#include <QtCore/QString>
int main() {
    QString s = "1234567";
    int i = s.indexOf('3');
    return i != 2;
}

Our *.pro file, you should enable the debug build:

# DebugQt.pro
TARGET = DebugQt
TEMPLATE = app
SOURCES += main.cpp
QT -= gui
CONFIG += console debug_and_release

1. Build your debug version of application:

# qmake-qt4
# make debug

2. Install Qt’s debug package:

# sudo apt-get install libqt4-debug

3. Install the Qt source:

# sudo apt-get source libqt4-debug

Now you can start debugging your application. Since Qt’s debug symbols are installed in /usr/lib, It does not follow the GDB’s global debug directory described here. We should tell GDB to load these symbols manually:

# gdb ./DebugQt
GNU gdb 6.8-debian
...
(gdb) b main
Breakpoint 1 at 0x8048696: file main.cpp, line 3.
(gdb) r
Starting program: /home/binson/DebugQt/DebugQt 
[Thread debugging using libthread_db enabled]
[New Thread 0xb71d36c0 (LWP 11138)]
[Switching to Thread 0xb71d36c0 (LWP 11138)]

Breakpoint 1, main () at main.cpp:3
3     QString s = "1234567";
(gdb) info sharedlibrary
From        To          Syms Read   Shared Object Library
0xb77a47f0  0xb77b96df  Yes         /lib/ld-linux.so.2
0xb7652510  0xb7740904  Yes         /usr/lib/libQtCore.so.4
0xb7605210  0xb7610a04  Yes         /lib/tls/i686/cmov/libpthread.so.0
0xb754fa60  0xb75ccb14  Yes         /usr/lib/libstdc++.so.6
0xb74eb440  0xb7505414  Yes         /lib/tls/i686/cmov/libm.so.6
0xb74de970  0xb74e5e04  Yes         /lib/libgcc_s.so.1
0xb73a4230  0xb74a4ea4  Yes         /lib/tls/i686/cmov/libc.so.6
0xb7368470  0xb7380684  Yes         /usr/lib/libfontconfig.so.1
0xb7350910  0xb735e3e4  Yes         /usr/lib/libz.so.1
0xb734a180  0xb734b804  Yes         /usr/lib/libgthread-2.0.so.0
0xb7341990  0xb7345ee4  Yes         /lib/tls/i686/cmov/librt.so.1
0xb72a0620  0xb72fe114  Yes         /usr/lib/libglib-2.0.so.0
0xb728ba70  0xb728ca74  Yes         /lib/tls/i686/cmov/libdl.so.2
0xb72249f0  0xb7276264  Yes         /usr/lib/libfreetype.so.6
0xb71fe190  0xb7214384  Yes         /usr/lib/libexpat.so.1
0xb71d5ef0  0xb71f1da4  Yes         /usr/lib/libpcre.so.3

We set a breakpoint at the beginning of main function to load all shared libraries. Next, we will load symbols for libQtCore.so.4. The symbol will be loaded in the start address of it (0xb7652510):

(gdb) add-symbol-file /usr/lib/libQtCore.so.4.3.4.debug 0xb7652510
add symbol table from file "/usr/lib/libQtCore.so.4.3.4.debug" at
 .text_addr = 0xb7652510
(y or n) y
Reading symbols from /usr/lib/libQtCore.so.4.3.4.debug...done.

Now, you are able to step into the Qt library, but no source is attached:

(gdb) b 4
Breakpoint 2 at 0x80486a9: file main.cpp, line 4.
(gdb) c
Continuing.

Breakpoint 2, main () at main.cpp:4
4     int i = s.indexOf('3');
(gdb) s
QChar (this=0xbfb1ec0e, ch=51 '3') at tools/qchar.cpp:432
432 tools/qchar.cpp: No such file or directory.
 in tools/qchar.cpp

Source files are attached by:

(gdb) dir ~/qt4-x11-4.3.4/src/corelib
Source directories searched: /home/binson/qt4-x11-4.3.4/src/corelib:$cdir:$cwd
(gdb) l
427 
428 /*!
429     Constructs a QChar corresponding to ASCII/Latin-1 character \a
430     ch.
431 */
432 QChar::QChar(char ch)
433 {
434 #ifndef QT_NO_CODEC_FOR_C_STRINGS
435     if (QTextCodec::codecForCStrings())
436         // #####
(gdb) bt
#0  QChar (this=0xbfb1ec0e, ch=51 '3') at tools/qchar.cpp:432
#1  0x080486bc in main () at main.cpp:4

See the source and backtrace? 🙂

Categories: C/C++ Tags: , , ,

Using Ubuntu Debug Packages in GDB (2)

July 7th, 2010 No comments

From last blog, I’ve demostrated the usage of Ubuntu *-dbg packages. However, not all *-dbg packages seem to work as libssl0.9.8-dbg. For instance, libcurl3-dbg and libqt4-dbg packages do not work. I’m afraid some debug info are missing in these two packages. I’m not sure.

I googled a lot, but was not able to find a solution. So I decided to build the debug version of the two library myself. Here are steps for libcurl:

# sudo apt-get source libcurl3-dbg
# cd curl-7.19.7/
# ./configure --prefix=/usr/local --enable-debug --enable-static=0
# make

After all, the compiled binary is located in /home/gonwan/testgdb/curl-7.19.7/lib/.libs/. Note, this is a hidden folder.

Here comes our test code:

#include <curl/curl.h>
int main() {
    curl_easy_init();
    return 0;
}

Build commands:

# gcc -g testcurl.c -o testcurl /usr/lib/libcurl.so.4

I use /usr/lib/libcurl.so.4 instead of lcurl, since lcurl will link the binary to /usr/lib/libcurl-gnutls.so.4. But I currently cannot afford it :(. Last, start our GDB:

# LD_LIBRARY_PATH=/home/gonwan/testgdb/curl-7.19.7/lib/.libs/ gdb ./testcurl
GNU gdb (GDB) 7.1-ubuntu
...
Reading symbols from /home/gonwan/testgdb/testcurl...done.
(gdb) b 3
Breakpoint 1 at 0x8048572: file testcurl.c, line 3.
(gdb) r
Starting program: /home/gonwan/testgdb/testcurl
[Thread debugging using libthread_db enabled]
Breakpoint 1, main () at testcurl.c:3
3           curl_easy_init();
(gdb) s
curl_easy_init () at easy.c:372
372         if(!initialized) {
(gdb) bt
#0  curl_easy_init () at easy.c:372
#1  0x08048577 in main () at testcurl.c:3
(gdb)

It prints the backtrace now, though I’m not so accustomed to console debugging. I add the LD_LIBRARY_PATH environment to let our test program find our homemade version of libcurl.so.4. In fact, we can run ldd like following lines. You see the re-direction?

# ldd ./testcurl | grep libcurl
    libcurl.so.4 => /usr/lib/libcurl.so.4 (0x00943000)
# LD_LIBRARY_PATH=/home/gonwan/testgdb/curl-7.19.7/lib/.libs/ ldd ./testcurl | grep libcurl
    libcurl.so.4 => /home/gonwan/testgdb/curl-7.19.7/lib/.libs/libcurl.so.4 (0x00318000)

Later, I successfully made it possible to debug Qt source code in IDE. I chose QtCreator, since it has both windows and linux version, and it’s easy to install and configure. I also built my homemade version of Qt:

# sudo apt-get source libqt4-dbg
# cd qt4-x11-4.6.2/
# ./configure -prefix /usr/local -debug-and-release -no-qt3support -no-webkit -no-script -no-scripttools -no-xmlpatterns -no-phonon -no-multimedia -no-declarative -make libs -nomake tools -nomake examples -nomake demos -nomake docs -nomake translations -fast
# make

I only built the most common modules, excluding webkit, script, xmlpatterns, phonon, multimedia and declarative modules. It took only 25 minutes to finish (An entire build under windows may take 3 – 4 hours.). After all, start your QtCreator, create a Qt console project with the source below:

#include <QtCore/QString>
int main() {
    QString s = "1234567";
    int i = s.indexOf('3');
    return i != 2;
}

Build the project in debug mode. And now, here’s the magic: Go to Project tab –> Run Settings –> Run Environment, append our homemade Qt library path to LD_LIBRARY_PATH. In my example, it’s /home/gonwan/testgdb/qt4-x11-4.6.2/lib. Ok, you’re almost done! Go back to the Edit tab, set a breakpoint at line 4 (or line 3 as you like), press F5 to start debugging the project. Then continue pressing F11, you will find GDB has stepped into Qt source code! Let me take a screenshot:

qtcreator_qt4debug

In order to load our homemade *.so, we can also run “make install”.

Categories: Linux Tags: , , ,

Using Ubuntu Debug Packages in GDB

July 7th, 2010 No comments

I will use openssl library as example. Here’s a simplest source:

#include <openssl/ssl.h>
int main() {
    SSL_library_init();
    return 0;
}

Now build and start your GDB, note the ‘-g’ option is necessary:

# gcc -g testopenssl.c -o testopenssl -lssl
# gdb ./testopenssl
GNU gdb 6.8-debian
...
(gdb) b 3
Breakpoint 1 at 0x8048495: file testopenssl.c, line 3.
(gdb) r
Starting program: /home/binson/testgdb/testopenssl
Breakpoint 1, main () at testopenssl.c:3
3       SSL_library_init();
(gdb) s
4       return 0;
(gdb)

GDB cannot step into openssl source code, since there’s no debug symbol found. In Ubuntu, we can install it using apt-get. I’m using Hardy(8.04):

# sudo apt-get install libssl0.9.8-dbg

Launch our GDB again:

# gdb ./testopenssl
GNU gdb 6.8-debian
...
(gdb) b 3
Breakpoint 1 at 0x8048495: file testopenssl.c, line 3.
(gdb) r
Starting program: /home/binson/testgdb/testopenssl
Breakpoint 1, main () at testopenssl.c:3
3       SSL_library_init();
(gdb) s
SSL_library_init () at ssl_algs.c:68
68  ssl_algs.c: No such file or directory.
    in ssl_algs.c
(gdb)

Symbols are found, GDB prompt for missing source files! We can install by typing:

# sudo apt-get source libssl0.9.8

The source files will be downloaded and extracted in openssl-0.9.8g folder. Now we wanna attach the source files when debugging.

# gdb ./testopenssl
GNU gdb 6.8-debian
...
(gdb) dir openssl-0.9.8g/ssl/
Source directories searched: /home/binson/testgdb/openssl-0.9.8g/ssl:$cdir:$cwd
(gdb) b 3
Breakpoint 1 at 0x8048495: file testopenssl.c, line 3.
(gdb) r
Starting program: /home/binson/testgdb/testopenssl
Breakpoint 1, main () at testopenssl.c:3
3       SSL_library_init();
(gdb) s
SSL_library_init () at ssl_algs.c:68
68      EVP_add_cipher(EVP_des_cbc());
(gdb) bt
#0  SSL_library_init () at ssl_algs.c:68
#1  0x0804849a in main () at testopenssl.c:3
(gdb)

Oh! Everything works!

Categories: Linux Tags: , ,