본문으로 건너뛰기
0%
약 6분 (752 단어) ko

Remote Debugging Using GDB Server

Categories TechSavvy EmbeddedLinux
Tags #Blogging #Linux #AGL #EmbeddedLinux #OpenEmbedded #Yocto #CrossDevelopment #GCC #GDB #Toolchain

This post covers how to do remote debugging using the debugger tools gdbserver and gdb.

Remote debugging is a method where you run gdbserver on the target where the application is actually running, and debug using gdb and toolchain from a remote host.

Desktop View Ref. Linux Foundation Conference 2020

This method involves running an application on the target with optimizations and debugging symbols removed through gdbserver listening, while the remote host connects to gdbserver using gdb with an application that includes optimizations and debugging symbols through the toolchain for debugging.

When the target is an embedded board, disk memory capacity and system memory capacity are very limited, making remote debugging useful in such cases.

Breaking into Examples

  • Before the detailed explanation, I’ll assume you basically know how to use gdb from the command line to some extent.

0. Setting up Environment

Desktop View

The diagram above shows a situation where two VS Code instances each have Docker containers running.

  • Host IP: 172.25.125.2
  • Target IP: 172.25.125.3

1. Printing Hello World

The test scenario we want to test is as follows:

  1. Compile Helloworld.cpp for the target on the host and send it to the target
    • Not Stripped, with debug info, no optimization
  2. Connect GDBServer and GDB
  3. Real-time debugging of the application on the target from the host via network

The Helloworld.cpp test code is as follows:

#include <iostream>
#include <vector>

int main(){
    std::vector<int> intVector {1,2,3,4,5,6,7};
    
    for (auto i : intVector){
        std::cout << "Hello World : "<< i << std::endl;
    }
    return 0;
}

1. Compile Helloworld.cpp for the target on the host and send it to the target

Desktop View

2. Connect GDBServer and GDB

  • [TARGET] First, let’s start GDBServer on the target to put it in listening state

    Desktop View

  • [HOST] Run GDB and connect to GDBServer over the network

    Desktop View

  • [HOST, TARGET] Successfully connected screen

    Desktop View

4. Real-time debugging of the application on the target from the host via network

  • [HOST] Set a breakpoint at the main function and check

    Desktop View

  • [HOST] Execute

    Desktop View

    • The run command is not available in gdb connected remotely
    • When you proceed line by line with ‘n’ from the HOST, you can see messages from std::cout appearing on stdout on the TARGET

2. Attaching to Running Applications

Besides starting an application from scratch using GDBServer, you can also attach to applications that are already running just-in-time.

I’ll explain using an example that runs in an infinite loop like the one below:

//running_app.cpp
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>

int main(){
    using namespace std::chrono_literals;
    while (true){
        std::vector<int> intVector {1,2,3,4,5,6,7};
        for (auto i : intVector){
            std::cout << "Hello World : "<< i << std::endl;
            std::this_thread::sleep_for(1s);
        }
    }
    
    return 0;
}

The above example will repeatedly output “Hello World : 1 ~ 7” to stdout every second.

[TARGET] First, let’s move the built application above to the target and run it.

  • running_app is running with pid=25685 assigned.

    Desktop View

[TARGET] Let’s attach gdbserver to running_app

  • When listening starts normally, you’ll see logs like below

    Desktop View

[HOST] Connect to the TARGET with gdb as follows

Desktop View

  • The TARGET’s operation pauses as soon as you connect

    Desktop View

  • Looking at the logs, the connection point was when it was executing

    Desktop View

    std::this_thread::sleep_for(1s);
    • Symbol tracing is impossible because there’s no source code for the nanosleep.c side

[HOST] You can proceed with line-by-line debugging using n or s commands

  • n command (next)

    Desktop View

  • s command (step into)

    Desktop View

[HOST] You can make it resume normal operation through detach

  • It resumes normal operation from the last point where you were debugging

    Desktop View

Share this article

Found this helpful? Share it with your network

Join the Discussion

Share your thoughts and connect with other readers

댓글

GitHub 계정으로 로그인하여 댓글을 남겨보세요. 건설적인 의견과 질문을 환영합니다!

댓글을 불러오는 중...