Himanshu Poddar
Himanshu Poddar

Reputation: 7799

How to debug a cpp file that's part of a so file in the software?

So I have this software which has multiple .so files. For one of the so file and I made some changes to the code but I want to see the line by line execution of file present in the so file.

Just to give a reference while using visual studio we can attach the code to the process that is using the dll file and then once it gets attached we put breakpoints in the file we want to debug and step over to go to the next line.

How can I achieve the same on Linux machine? Is there any hack that would help me?

I have a software that uses so files and that so files has multiple cpp files as part of its build and I want to debug a file present in that so file.

Upvotes: 4

Views: 1451

Answers (1)

Pablo Yaggi
Pablo Yaggi

Reputation: 1221

If the .so has debugging information it is just trivial, you just run you app with the debugger and do the same you mention, put some breakpoints. You have many debugger and debugging options. For example you can run gdb from console, asking to execute the application:

>gdb yourAppPath

or to attach to a running process:

>gdb
(gdb) attach runningProcessId

Once you are inside gdb you can place breakpoints wherever you want (you should read the gdb documentation).

Another option is to use GUI front ends for gdb (ie: kgdb), here you can find a list of front ends. Also most of IDEs available on linux have good graphical integration with gdb.

Now, if you don't have debugging symbols on your library (.so) files, you should recompile them with the debugging info generation option of your compiler. If you are using gcc it will be '-g' .

If the libraries are provided by your distribution, most of them has separate packages for the debugging symbols, once you install those packages symbols will be available and gdb should load them automatically. For example in OpenSuse you have the glibc package and the glibc-debuginfo package containing the symbols for glibc.

Here is a minimal example of gdb usage on one of my projects:

Fist I call gdb with search path for all libraries because they are not located in the system path. If you libraries are 'installed', so they are accessible from system path you don't need to specify LD_LIBRARY_PATH.

>LD_LIBRARY_PATH=.:~/projects/asdstoolkit2/asdscore/:~/projects/asdstoolkit2/asdscrypto:~/projects/asdstoolkit2/asdsnet:~/projects/asdstoolkit2/codb/codb gdb ../clibrarian/clibrarian 

#output

Copyright (C) 2020 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-suse-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://bugs.opensuse.org/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../clibrarian/clibrarian...
(gdb) 

Then you could call start, to force gdb to load all libraries symbols and place a breakpoint at the start of the program. (you can load the symbols without doing this as well, I just don't recall how right now, check the docs).

(gdb)start
Temporary breakpoint 1 at 0x407aa9: file ../../librarian/clibrarian/main.cpp, line 16.
Starting program: /home/pablo/projects/build-librarian-Desktop-Debug/clibrarian/clibrarian 
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.32-1.1.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdbf8) at ../../librarian/clibrarian/main.cpp:16
16          qputenv("QT_FORCE_STDERR_LOGGING", QByteArray("1"));
Missing separate debuginfos, use: zypper install krb5-debuginfo-1.18.2-3.2.x86_64 libQt5Core5-debuginfo-5.15.1-2.1.x86_64 libQt5Gui5-debuginfo-5.15.1-2.1.x86_64 libQt5Network5-debuginfo-5.15.1-2.1.x86_64 libQt5Sql5-debuginfo-5.15.1-2.1.x86_64 libX11-6-debuginfo-1.6.12-1.1.x86_64 libXau6-debuginfo-1.0.9-1.7.x86_64 libbrotlicommon1-debuginfo-1.0.9-1.1.x86_64 libbrotlidec1-debuginfo-1.0.9-1.1.x86_64 libbz2-1-debuginfo-1.0.8-2.20.x86_64 libcom_err2-debuginfo-1.45.6-1.19.x86_64 libcurl4-debuginfo-7.72.0-1.2.x86_64 libdouble-conversion3-debuginfo-3.1.5-3.4.x86_64 libexiv2-27-debuginfo-0.27.3-2.1.x86_64 libexpat1-debuginfo-2.2.10-1.1.x86_64 libffi8-debuginfo-3.3.git30-1.13.x86_64 libfontconfig1-debuginfo-2.13.1-2.8.x86_64 libfreetype6-debuginfo-2.10.2-1.3.x86_64 libgcc_s1-debuginfo-10.2.1+git583-1.2.x86_64 libglib-2_0-0-debuginfo-2.64.6-1.1.x86_64 libglvnd-debuginfo-1.3.2-2.1.x86_64 libgmp10-debuginfo-6.2.0-3.3.x86_64 libgnutls30-debuginfo-3.6.15-1.1.x86_64 libgpg-error0-debuginfo-1.39-1.1.x86_64 libgraphite2-3-debuginfo-1.3.14-1.2.x86_64 libharfbuzz0-debuginfo-2.7.2-1.1.x86_64 libhogweed6-debuginfo-3.6-1.5.x86_64 libicu67-debuginfo-67.1-2.3.x86_64 libidn12-debuginfo-1.36-1.2.x86_64 libidn2-0-debuginfo-2.3.0-3.2.x86_64 libjpeg8-debuginfo-8.2.2-60.2.x86_64 libldap-2_4-2-debuginfo-2.4.53-57.2.x86_64 liblz4-1-debuginfo-1.9.2-2.1.x86_64 liblzma5-debuginfo-5.2.5-1.16.x86_64 libmodman1-debuginfo-2.0.1-18.10.x86_64 libnettle8-debuginfo-3.6-1.5.x86_64 libopenssl1_1-debuginfo-1.1.1g-2.13.x86_64 libp11-kit0-debuginfo-0.23.20-2.1.x86_64 libpcre2-16-0-debuginfo-10.35-1.4.x86_64 libpng16-16-debuginfo-1.6.37-1.7.x86_64 libpodofo0_9_6-debuginfo-0.9.6-4.8.x86_64 libproxy1-debuginfo-0.4.15-9.1.x86_64 libsasl2-3-debuginfo-2.1.27-3.5.x86_64 libssh4-debuginfo-0.9.5-1.1.x86_64 libstdc++6-debuginfo-10.2.1+git583-1.2.x86_64 libsystemd0-debuginfo-246.6-1.1.x86_64 libtag1-debuginfo-1.11.2~git20190725.79bc9ccf-2.3.x86_64 libtasn1-6-debuginfo-4.16.0-1.6.x86_64 libtiff5-debuginfo-4.1.0-2.4.x86_64 libunistring2-debuginfo-0.9.10-2.8.x86_64 libz1-debuginfo-1.2.11-16.1.x86_64 libzip5-debuginfo-1.7.3-1.2.x86_64 libzstd1-debuginfo-1.4.5-2.4.x86_64

Then you can list a method source code: (you can tap tab key to autocomplete)

(gdb) list AIcon::AIcon
file: "aicon.cpp", line number: 12, symbol: "AIcon::AIcon()"
7       #include <QTextStream>
8       extern QStringList AIcon_google_catnames;
9       extern QList<QList<GoogleIcon>* > AIcon_google_Cats;
10      static QStringList AIcon_texts=QStringList()<<QString();
11      static QStringList AIcon_files=QStringList()<<QString();
12      AIcon::AIcon()
13      {
14          m_itype=Icon_Null;
15          m_icon=0;
16      }
file: "aicon.cpp", line number: 17, symbol: "AIcon::AIcon(GoogleIcon)"
12      AIcon::AIcon()
13      {
14          m_itype=Icon_Null;
15          m_icon=0;
16      }
17      AIcon::AIcon(GoogleIcon i)
18      {
19          m_itype=Icon_Google;
20          m_icon=i;
21      }
file: "aicon.cpp", line number: 22, symbol: "AIcon::AIcon(QString const&, bool)"
17      AIcon::AIcon(GoogleIcon i)
18      {
19          m_itype=Icon_Google;
20          m_icon=i;
21      }
22      AIcon::AIcon(const QString &text,bool ti)
23      {
24          if (ti)
25              setTextIcon(text);
26          else
file: "aicon.cpp", line number: 29, symbol: "AIcon::AIcon(AI18n::CountryCode)"
24          if (ti)
25              setTextIcon(text);
26          else
27              setFileIcon(text);
28      }
29      AIcon::AIcon(AI18n::CountryCode cc)
30      {
31          setFlagIcon(cc);
32      }
33      AIcon::AIcon(AI18n::LanguageCode cc)
file: "aicon.cpp", line number: 33, symbol: "AIcon::AIcon(AI18n::LanguageCode)"
28      }
29      AIcon::AIcon(AI18n::CountryCode cc)
30      {
31          setFlagIcon(cc);
32      }
33      AIcon::AIcon(AI18n::LanguageCode cc)
34      {
35          setLanguageIcon(cc);
36      }
37

Finally you can place a breakpoint and eventually continue the execution

(gdb) break 35
Breakpoint 2 at 0x7ffff7f04651: file aicon.cpp, line 35.
(gdb) continue

Upvotes: 1

Related Questions