Kernel Driver Series - 10 - GDB Part 2 - Remote Debugging
Hi Everyone, Hope you all are doing great.
It's nice to be back with a new article after a long time, I was not doing well due to my chronic health condition and was not able to contribute to my articles for a long time. Few things will always disturb our life and our family and friends will help us in this tough time to get back on. I am very happy to have my parents and such friends in my life, to whom I cannot thank enough to support me during my tough times.
Let's switch to the main content of this article. In this article we will discuss about the remote debugging capabilities of the GDB and we will understand the concepts with a hands-on example.
💡GDB - Remote Debugging:
Let's say you have a situation where you want to debug the programs running inside the Routers or Embedded Systems which doesn't have any monitor or terminals or keyboard attached. Please note that these devices have networking capabilities. In this situation, you need a remote server that is capable of running the debugging infrastructure to debug the programs.
GDB offers such a remote stub that is capable of communicating over the network and perform the debugging. In this article, we will see the way to run this infrastructure to debug the programs remotely on the target hardware.
💡Architecture
As you can see in the above diagram, we are debugging a program called "demo" which is an aarch64 ISA ELF file. This program is cross-compiled in x86_64 system (Ubuntu system) and then copied to the BananaPI R3 router using scp. Please note that the binary has been compiled using "-g" in the Makefile to generate debug symbols.
We are going to launch the "demo" program with a binary called "gdbserver" and with a port number 8999 (Please change this port number to your convenience). Once this is done, we will connect to this server from our laptop using "gdb-multiarch". "gdb-multiarch" has the capabilities to work with multiple architectures such as x86, x86_64, arm, aarch64, MIPS, etc., Once we have launched the gdb-multiarch in our host machine, we will use the cross-compiled program to read the debug symbols and then use the "target remote" command to connect to the remote server and start the debugging session.
This is a generalised architecture in which you can replace the host and target machines with ARM, ARM64, x86_64 as needed.
💡Prerequisites for Host Machine
Following are the packages you need to install onto the host machine. The instructions are given as per Ubuntu Platform. Kindly adjust the installation parameters to suite your distro.
At the time of writing this article, I have 12.1 installed in my system as shown in the screenshot below
💡Prerequisites for Target Platform
Following are the prerequisites for the target platform. I am using Banana PI R3 as the target platform running OpenWRT. Kindly adjust the parameters of your target platform as mentioned in the documentation of your platforms.
In the following screenshots, you can see the various options that needed to be enabled in the OpenWRT to support remote gdb (gdb-server).
Save and compile the gdb package.
💡Option 1: Build full image and flash
You can completely build the entire image and flash onto the target platform by running the following commands
make V=s
Once the compilation of entire OpenWRT is completed, image will be generated for BananaPI R3 in the following location
bin/targets/mediatek/filogic/openwrt-mediatek-filogic-bananapi_bpi-r3-sdcard.img.gz
Follow the BananaPI R3 documentation to transfer the image
Recommended by LinkedIn
💡Option 2: Transfer the gdbserver via scp
You can copy the gdb binaries directly to the target platform as shown in the commands below
scp build_dir/target-aarch64_cortex-a53_musl/gdb-13.2/ipkg-install/usr/bin/* root@192.168.1.1:/usr/bin/
# where 192.168.1.1 is the BananaPI R3 running OpenWRT image
# we are copying gdb and gdbserver both to the BananaPI R3
💡Program to debug using gdbserver
Following is the program that is generated as the OpenWRT package and is transferred to the BananaPI R3 using SCP command.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
struct sample_t{
int a;
int b;
int c;
};
int perform_calculations(struct sample_t *obj){
int result = 0;
result = obj->a + obj->b + obj->c;
return result;
}
int main(int argc, char **argv){
int a = 0, b = 0, c = 0;
int result = 0;
struct sample_t obj = {
.a = 10,
.b = 20,
.c = 30
};
printf("This is the sample program for demostrating the gdb server\n");
result = perform_calculations(&obj);
a = result * 10;
b = result * 20;
c = result * 30;
printf("Results: %d, %d, %d, %d\n", result, a, b, c);
return 0;
}
Makefile for the program:
all:
$(CC) demo.c -o demo -g
💡Perform Remote GDB using gdbserver
Following are the set of commands that can be used to put the program in remote debugging mode.
On the Target Platform:
On the Host Machine:
If you see the similar screenshots on your host machine and target platform, then the GDB is connected via remote debugger and is able to perform remote debugging on the target binary.
💡Video Showcasing the remote debugging
Following YouTube video showcases the remote debugging of the "demo" program.
💡Conclusion
Hope you have enjoyed this article and if so kindly subscribe to my LinkedIn and YouTube Channel - "SammyTechPlayground - Learn with Naveen".
Thank you all for your wonderful support and will be back with another exciting article soon. Till then, stay safe, stay happy and wish you a wonderful programming experience...
💡References
Embedded Networking Engineer | RTOS | Linux | System Programming| Edge ML/AL| Networking | IOT I Openwrt | COMINT
8moVery useful information .keep it up
Senior Engineer at Bosch
8moInsightful
Member of Technical Team - I
8moNice explanation 👌