Contents
Debugging programs using the QEMU GDB server
The GDB server of QEMU has the following distinguishing characteristics:
- Does not recognize processes and threads managed by KasperskyOS.
All processes managed by KasperskyOS are viewed as one process by the GDB server of QEMU. This process includes one or more threads depending on how many threads can be executed at the same time on the hardware platform emulated by QEMU. Therefore, the processes and threads handled by the GDB server of QEMU are not considered to be processes and threads managed by KasperskyOS.
- Does not guarantee debug capabilities for QEMU emulation of hardware platforms employing symmetric multiprocessing (SMP).
The GDB server of QEMU can be used during QEMU emulation of hardware platforms employing SMP. However, GDB commands for step-by-step execution of a program may fail (for example,
next
andstep
).
Preparations for debugging
To prepare the conditions for debugging with the GDB server of QEMU, you must complete the following steps:
- Disable ASLR support and define the memory addresses for loading the
.text
sections of executable files.To do so, you need to use the following
CMake
command:set_target_properties(<program name> PROPERTIES LINK_FLAGS "-no-pie -Ttext <address>")The GDB debugger needs the memory address used to load the ELF image to map the debug symbols to the ELF image. When ASLR is supported by default, this address is defined by a random value that is unknown to the GDB debugger, which complicates debugging. To disable ASLR support, indicate the
-no-pie
flag.The GDB server of QEMU views all running processes managed by KasperskyOS as one process. If ASLR is not supported, by default the linker causes the executable files to be loaded at the same memory address of processes. As a result, the loaded segments of executable files overlap in memory from the perspective of the GDB debugger, and debugging is carried out incorrectly (for example, incorrect values of variables are displayed, or breakpoints set for another program are triggered). To prevent overlapping of loaded segments corresponding to different programs, use the
-Ttext
<address
> parameter that defines the load address of the.text
section. The offset between the load addresses of the.text
section in different processes can be a value that is 1 MB larger than the largest executable file in the solution image. For example, the value0x06000000
can be specified as the loading address of the.text
section for theClient
program in the ping example, and the value0x06200000
can be specified for theServer
program in this example.The offset between addresses of
.text
sections cannot guarantee that there will be no overlaps of loaded segments if pre-built executable files used in the solution (for example, from KasperskyOS Community Edition) were linked for ASLR support. (You can disable ASLR and define the addresses for loading.text
sections only for the executable files that are built during creation of the solution. This cannot be done for pre-built executable files.) The.text
sections of these executable files are loaded to random addresses, which could cause overlaps with loaded segments corresponding to the program that you need to debug. - [Optional] Define the settings for running QEMU.
To change the initial settings and/or add new settings for running QEMU, you need to use the
QEMU_FLAGS
parameter of theCMake
commandbuild_kos_qemu_image()
.Example:
set(QEMU_FLAGS "-m 2048 -machine vexpress-a15,secure=on \ -cpu cortex-a72 -nographic -monitor none -smp 4") build_kos_qemu_image(kos-qemu-image ... QEMU_FLAGS "${QEMU_FLAGS}")
Initial steps of debugging
To begin debugging using the GDB server of QEMU, you must complete the following steps:
- Build debug versions of executable files and libraries, create a solution image for QEMU, and run QEMU on standby for a connection from the GDB debugger.
To do so, call the
cmake
shell commands, and specify the-D CMAKE_BUILD_TYPE:STRING=Debug
and--target gdbsim
parameters.Example:
"Unix Makefiles" \ -D CMAKE_BUILD_TYPE:STRING=Debug \ -D CMAKE_TOOLCHAIN_FILE=$SDK_PREFIX/toolchain/share/toolchain-$TARGET.cmake \ -B build \ && cmake --build build --target gdbsim... cmake -GInstead of the
gdbsim
target, you can specify thegdbsim/fast
target to avoid rebuilding.QEMU starts but does not execute the solution code while it waits for a call of the GDB command
continue
. - Run the GDB debugger and connect to the GDB server of QEMU.
To do so, you must call the shell command
make gdb
in thebuild
directory. - [Optional] Define additional paths to search for dynamic libraries containing debug symbols.
During step 1, the
build/einit/.gdbinit
file automatically records the path where the GDB debugger will search for dynamic libraries containing debug symbols from KasperskyOS Community Edition (as a parameter of the GDB commandset sysroot
). To define additional paths to search for dynamic libraries, call the following GDB command:set solib-search-path <path to directory>... - [Optional] Load debug symbols of executable files.
If
.text
section loading addresses are defined for executable files with static linking (using theCMake
commandset_target_properties()
), the GDB command for loading debug symbols for each of these files is automatically added to thebuild/einit/.gdbinit
file at step 1.If a
.text
section loading address is defined for one executable file with dynamic linking, the GDB command for loading debug symbols for this file is automatically added to thebuild/einit/.gdbinit
file at step 1. If.text
section loading addresses are defined for multiple executable files with dynamic linking, the GDB command for loading debug symbols is not automatically added to thebuild/einit/.gdbinit
file for any of these executable files at step 1.To manually load debug symbols, use the following GDB commands:
add-symbol-file
<path to file
> – for executable files with static or dynamic linking.file
<path to file
> – for executable files with dynamic linking.
The GDB command
file
must be used so that the GDB debugger can load debug symbols of an executable file and the dynamic libraries required by this executable file. Use the GDB commandadd-symbol-file
for the GDB debugger to load the debug symbols only for an executable file with dynamic linking.The GDB command
file
can be used only for one executable file. In other words, the GDB debugger cannot load debug symbols of dynamic libraries for multiple executable files at the same time.After the GDB command
file
is called, the following message can be displayed:warning: Unable to find dynamic linker breakpoint function.GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code.This message should be ignored.
If debug symbols are saved in separate files instead of in the executable files, links to the files containing the debug symbols are added to the executable files. When the GDB command
add-symbol-file
orfile
is called, you can specify the executable file or the file containing debug symbols.
When performing a repeat build (step 1), you do not have to terminate the debug session (i.e. exit the debugger). (This means that you can avoid repeating operations such as loading debug symbols and defining additional paths to search for dynamic libraries.) To avoid terminating the debug session, you must run the GDB command detach
before running the repeat build, then you must run the GDB command target remote localhost:1234
after starting QEMU.
GDB commands (for example, to load debug symbols or define additional paths to search for dynamic libraries) can be written to a file and then called by using the GDB command source
<path to file
>.
Special considerations for debugging emulated hardware platforms with SMP
Processors (computing kernels) are presented as threads.
To display information about processors, call the following GDB command:
To switch to another processor, call the following GDB command: