Guidelines and HOWTOs/Debugging/Debugging symbols: Difference between revisions
Replace "debugfull" with "debug", following last change ─which was made by Daniel Vrátil (Dvratil) |
→Example app: Update main.cpp with the KF5 code from https://develop.kde.org/docs/getting-started/hello_world/ |
||
Line 15: | Line 15: | ||
'''main.cpp''' | '''main.cpp''' | ||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
#include < | #include <QApplication> | ||
#include <QCommandLineParser> | |||
#include <KAboutData> | #include <KAboutData> | ||
#include < | #include <KLocalizedString> | ||
#include <KMessageBox> | #include <KMessageBox> | ||
#include <iostream> | #include <iostream> | ||
int main (int argc, char *argv[]) | int main (int argc, char *argv[]) | ||
{ | { | ||
QApplication app(argc, argv); | |||
KLocalizedString::setApplicationDomain("tutorial1"); | |||
KAboutData aboutData( | |||
// The program name used internally. (componentName) | |||
QStringLiteral("tutorial1"), | |||
// A displayable program name string. (displayName) | |||
i18n("Tutorial 1"), | |||
// The program version string. (version) | |||
QStringLiteral("1.0"), | |||
// Short description of what the app does. (shortDescription) | |||
i18n("Displays a KMessageBox popup"), | |||
// The license this code is released under | |||
KAboutLicense::GPL, | |||
// Copyright Statement (copyrightStatement = QString()) | |||
i18n("(c) 2015"), | |||
// Optional text shown in the About box. | |||
// Can contain any information desired. (otherText) | |||
i18n("Some text..."), | |||
// The program homepage string. (homePageAddress = QString()) | |||
QStringLiteral("http://example.com/"), | |||
// The bug report email address | |||
// (bugsEmailAddress = QLatin1String("[email protected]") | |||
QStringLiteral("[email protected]")); | |||
aboutData.addAuthor(i18n("Name"), i18n("Task"), QStringLiteral("[email protected]"), | |||
QStringLiteral("http://your.website.com"), QStringLiteral("OSC Username")); | |||
KAboutData::setApplicationData(aboutData); | |||
QCommandLineParser parser; | |||
aboutData.setupCommandLine(&parser); | |||
parser.process(app); | |||
aboutData.processCommandLine(&parser); | |||
KGuiItem yesButton(i18n("Hello"), QString(), | |||
i18n("This is a tooltip"), | |||
i18n("This is a WhatsThis help text.")); | |||
int* i; | int* i; | ||
cout << "i is at " << i << " value " << *i << endl; | std::cout << "i is at " << i << " value " << *i << std::endl; | ||
i=(int*)0x0; | i=(int*)0x0; | ||
cout << "i is at " << i << " value " << *i << endl; | std::cout << "i is at " << i << " value " << *i << std::endl; | ||
return 0; | return KMessageBox::questionYesNo(0, i18n("Hello World"), i18n("Hello"), yesButton) | ||
== KMessageBox::Yes? EXIT_SUCCESS: EXIT_FAILURE; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 08:32, 18 April 2021
Overview
Debugging symbols allow you to debug your application better. They are added to your binary by the compiler. For KDE, you have to decide during the cmake step if you want debugging symbols or not. To compile your application with debugging symbols, use
cmake . -DCMAKE_BUILD_TYPE=debug
to compile it without debugging symbols, use
cmake . -DCMAKE_BUILD_TYPE=release
Depending on your decision, output generated with the command kDebug will also be (debug) or not be (release) added to your application.
Example app
As an example, let's write an application that crashes:
main.cpp
#include <QApplication>
#include <QCommandLineParser>
#include <KAboutData>
#include <KLocalizedString>
#include <KMessageBox>
#include <iostream>
int main (int argc, char *argv[])
{
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("tutorial1");
KAboutData aboutData(
// The program name used internally. (componentName)
QStringLiteral("tutorial1"),
// A displayable program name string. (displayName)
i18n("Tutorial 1"),
// The program version string. (version)
QStringLiteral("1.0"),
// Short description of what the app does. (shortDescription)
i18n("Displays a KMessageBox popup"),
// The license this code is released under
KAboutLicense::GPL,
// Copyright Statement (copyrightStatement = QString())
i18n("(c) 2015"),
// Optional text shown in the About box.
// Can contain any information desired. (otherText)
i18n("Some text..."),
// The program homepage string. (homePageAddress = QString())
QStringLiteral("http://example.com/"),
// The bug report email address
// (bugsEmailAddress = QLatin1String("[email protected]")
QStringLiteral("[email protected]"));
aboutData.addAuthor(i18n("Name"), i18n("Task"), QStringLiteral("[email protected]"),
QStringLiteral("http://your.website.com"), QStringLiteral("OSC Username"));
KAboutData::setApplicationData(aboutData);
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.process(app);
aboutData.processCommandLine(&parser);
KGuiItem yesButton(i18n("Hello"), QString(),
i18n("This is a tooltip"),
i18n("This is a WhatsThis help text."));
int* i;
std::cout << "i is at " << i << " value " << *i << std::endl;
i=(int*)0x0;
std::cout << "i is at " << i << " value " << *i << std::endl;
return KMessageBox::questionYesNo(0, i18n("Hello World"), i18n("Hello"), yesButton)
== KMessageBox::Yes? EXIT_SUCCESS: EXIT_FAILURE;
}
CMakeLists.txt
project (tutorial1) find_package(KDE4 REQUIRED) include (KDE4Defaults) include_directories(${KDE4_INCLUDES}) set(tutorial1_SRCS main.cpp) kde4_add_executable(tutorial1 ${tutorial1_SRCS}) target_link_libraries(tutorial1 ${KDE4_KDEUI_LIBS}) install(TARGETS tutorial1 ${INSTALL_TARGETS_DEFAULT_ARGS})
Now let's compile this without debugging symbols:
cmake . -DCMAKE_BUILD_TYPE=release && make
We see that the resulting file is small:
# ls -lh tutorial1 -rwxr-xr-x 1 user user 15K Jul 11 18:07 tutorial1
With debugging symbols, the file is bigger:
cmake . -DCMAKE_BUILD_TYPE=debug && make # ls -lh tutorial1 -rwxr-xr-x 1 root root 250K Jul 11 18:09 tutorial1
Backtraces
Now let's start the application and look at the backtrace:
cmake . -DCMAKE_BUILD_TYPE=release && make
Gives you the backtrace
Application: Tutorial 1 (tutorial1), signal SIGSEGV �[?1034h[Thread debugging using libthread_db enabled] 0x00007f58abba4cb0 in nanosleep () from /lib64/libc.so.6 [Current thread is 1 (Thread 0x7f58b0cfd750 (LWP 21264))] Thread 1 (Thread 0x7f58b0cfd750 (LWP 21264)): [KCrash Handler] '''#5 0x00000000004016aa in main ()'''
The debugging build
cmake . -DCMAKE_BUILD_TYPE=debug && make
Gives you the backtrace
Application: Tutorial 1 (tutorial1), signal SIGSEGV �[?1034h[Thread debugging using libthread_db enabled] 0x00007fd0b8161cb0 in nanosleep () from /lib64/libc.so.6 [Current thread is 1 (Thread 0x7fd0bd2ba750 (LWP 21327))] Thread 1 (Thread 0x7fd0bd2ba750 (LWP 21327)): [KCrash Handler] '''#5 0x0000000000401625 in main (argc=1, argv=0x7fffc52f5138) at /root/kdehello/main.cpp:25'''
So you see: with debugging symbols, you see the line number where the crash occurred. Without, you do not see this.
Where are they?
Where are the debugging symbols stored? Use objdump -g to find out:
# objdump -g tutorial1-release | wc -l 511 # objdump -g tutorial1-debug | wc -l 40943
It is important to know that the code lines (in assembler) to be executed actually do not differ a lot. We see this when disassembling the code:
# objdump -d tutorial1-debug | wc -l 658 # objdump -d tutorial1-release | wc -l 697
This gives us hope that there will be no major speed difference between a debug- and a release-version of a binary.
Speed implications
We remove the lines that cause the crash and the messagebox. Then we execute the program 100 times:
cmake . -DCMAKE_BUILD_TYPE=debug && make -j4 time for i in $(seq 1 1 100); do ./tutorial1; done real 0m6.201s user 0m4.368s sys 0m1.320s
Lasts 6 seconds. Now with the release version:
cmake . -DCMAKE_BUILD_TYPE=release && make -j4 time for i in $(seq 1 1 100); do ./tutorial1; done real 0m6.259s user 0m4.368s sys 0m1.328s
Also lasts 6 seconds. So the main difference is in the binaries size.
And make?
How does cmake propagate to make if a debug version is wanted? Do a
cmake . -DCMAKE_BUILD_TYPE=debug && make VERBOSE=1
You will find a difference during the link step. The parameters
-DNDEBUG -DQT_NO_DEBUG
are unique for the release-version. There are further differences like the O2 optimization.