Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to debug C++ code running in a docker container with gdbserver but can't seem to connect #774

Open
ReggieMarr opened this issue Feb 1, 2024 · 0 comments

Comments

@ReggieMarr
Copy link

ReggieMarr commented Feb 1, 2024

Hi all, I'm having an issue
I am experiencing an issue with remote debugging using cppdbg in dap-mode, where the debugger is not connecting to gdbserver running inside a Docker container. My setup involves a Docker container that runs gdbserver listening on port 5555. Although manual testing with gdb confirms that gdbserver is set up correctly and accessible, the VS Code debugger doesn't seem to make the connection.

Configuration:
launch.json

        {
            "name": "pipe to gdbserver",
            "type": "cppdbg",
            "request": "launch",
            "stopAtEntry": false,
            "program": "/app/tests/test_demux_via_umbilical/flight_segment_testbench/build/test_tx_mux",
            "args": [],
            "cwd": "${workspaceFolder}/tests/test_demux_via_umbilical/",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "sourceFileMap": {
                "/app/tests/test_demux_via_umbilical/": "${workspaceFolder}/tests/test_demux_via_umbilical/"
            },
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "pipeTransport": {
                "pipeProgram": "/bin/bash",
                "pipeCwd": "${workspaceFolder}/tests/test_demux_via_umbilical/",
                "pipeArgs": [
                    "${workspaceFolder}/tests/test_demux_via_umbilical/run.sh"
                ],
                "debuggerPath": "/usr/bin/gdb"
            }
        },

Dockerfile

# Use the official Docker Hub Ubuntu 20.04 base image
FROM ubuntu:20.04

ARG DEBIAN_FRONTEND=noninteractive
# Update the base image
RUN apt-get update && apt-get upgrade -y

# Install the necessary build tools
RUN apt-get install -y build-essential cmake gdb gdbserver libavformat-dev
# NOTE only needed for command line or popen calls, not for the api
RUN apt-get install -y ffmpeg

EXPOSE 5555

# create a new non-root user and group with name 'user'
ARG HOST_UID
ARG HOST_GID
RUN groupadd -g ${HOST_GID:-1000} user && useradd -u ${HOST_UID:-1000} -g ${HOST_GID:-1000} -m user
# Set the permission for /app directory
RUN mkdir -p /app && chown -R user:user /app

# Set the working directory to /app
WORKDIR /app

USER user

# Copy the current directory contents (where the Dockerfile is located, which should also contain your CMakeLists.txt file and source code)
# into the container at /app
ADD --chown=user:user . /app

VOLUME /app/tests/test_demux_via_umbilical/flight_segment_testbench
# Switch to test_demux_via_umbilical
WORKDIR /app/tests/test_demux_via_umbilical/flight_segment_testbench
# Build the project
RUN rm -rf build && mkdir -p build && cd build && cmake ../ && make

# Specify the command to run when the container starts
CMD [ "gdbserver :5555 ./build/test_tx_mux" ]

run.sh

#!/bin/bash
NAME="demux_via_umbilical"
if [ "$(docker ps -aq -f name=${NAME})" ]; then
    # cleanup
    echo "Container ${NAME} is not deleted. Removing now ..."
    docker rm --force ${NAME}
fi

docker run --rm --cap-add=sys_ptrace --security-opt seccomp=unconfined -p 5555:5555 \
    -v /home/reggiemarr/Projects/downlink-client/tests/test_demux_via_umbilical/flight_segment_testbench/build:/app/tests/test_demux_via_umbilical/flight_segment_testbench/build \
    -v /home/reggiemarr/Projects/downlink-client/tests/test_demux_via_umbilical/flight_segment_testbench:/app/tests/test_demux_via_umbilical/flight_segment_testbench \
    -w /app/tests/test_demux_via_umbilical/flight_segment_testbench/build -u 1000:1000 --name demux_via_umbilical downlink-client_demux_via_umbilical \
    gdbserver :5555 /app/tests/test_demux_via_umbilical/flight_segment_testbench/build/test_tx_mux

When running this configuration from dap-debug I'm able to get docker logs and I'm able to connect when invoking gbd from the command line but for some reason I can't get the connection through pipeTransport to work
What I've tested

note I've tested the following:
after starting the debug session I ran this

❯ docker logs demux_via_umbilical       
Process /app/tests/test_demux_via_umbilical/flight_segment_testbench/build/test_tx_mux created; pid = 10
Listening on port 5555

which indicates that the docker container is up and running but not connected

I then used gdb to connect manually:

❯ gdb 
(gdb) file test_tx_mux
Reading symbols from test_tx_mux...
(gdb) target extended-remote localhost:5555
Remote debugging using localhost:5555

(gdb) b downlink.h:113
No line 113 in file "downlink.h".
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b downlink.cpp:113
Breakpoint 1 at 0x55555555b79d: file /app/tests/test_demux_via_umbilical/flight_segment_testbench/downlink.cpp, line 114.
(gdb) c
Continuing.
[Detaching after vfork from child process 11]

(gdb) set substitute-path /app/tests/test_demux_via_umbilical /home/reggiemarr/Projects/downlink-client/tests/test_demux_via_umbilical/
(gdb) c
Continuing.

Breakpoint 1, TX_ActiveMux::genDownlinkDatagrams (this=0x7fffffffea40, out=...) at /app/tests/test_demux_via_umbilical/flight_segment_testbench/downlink.cpp:114
114             cout << stateName[state] << "\n";
(gdb) 

And I see that the docker logs now indicate that a connection has been made.

❯ docker logs demux_via_umbilical 
Process /app/tests/test_demux_via_umbilical/flight_segment_testbench/build/test_tx_mux created; pid = 10
Listening on port 5555
Remote debugging from host 172.17.0.1, port 50754
Detaching from process 11

EDIT:
After some spunlinking I found a blog post that describes doing something close to what I want to do, however I think the error is on the dap-mode side. I've updated my launch.json config to look like this:

        {
            "name": "test pipe to gdbserver",
            "type": "cppdbg",
            "request": "launch",
            "stopAtEntry": false,
            "program": "/app/tests/test_demux_via_umbilical/flight_segment_testbench/build/test_tx_mux",
            "args": [],
            "cwd": "/app/tests/test_demux_via_umbilical/",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "sourceFileMap": {
                "/app/tests/test_demux_via_umbilical/": "${workspaceFolder}/tests/test_demux_via_umbilical/"
            },
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "pipeTransport": {
                "debuggerPath": "/usr/bin/gdb",
                "pipeProgram": "docker",
                "pipeArgs": [
                    "run", "-i", "--rm", "--cap-add=sys_ptrace", "--security-opt", "seccomp=unconfined",
                    "-p", "5555:5555",
                    "-v", "${workspaceFolder}/tests/test_demux_via_umbilical/flight_segment_testbench/build:/app/tests/test_demux_via_umbilical/flight_segment_testbench/build",
                    "-v", "${workspaceFolder}/tests/test_demux_via_umbilical/flight_segment_testbench:/app/tests/test_demux_via_umbilical/flight_segment_testbench",
                    "-w", "/app/tests/test_demux_via_umbilical/flight_segment_testbench/build",
                    "-u", "1000:1000",
                    "--name", "demux_via_umbilical",
                    "downlink-client_demux_via_umbilical",
                    "bash", "-c"
                ],
                "pipeCwd": "${workspaceFolder}/tests/test_demux_via_umbilical/"
            }
        },

However emacs doesn't let me run that configuration and provides the following error message:

Setting current directory: No such file or directory, /app/tests/test_demux_via_umbilical/

However if I change cwd back to "cwd": "${workspaceFolder}/tests/test_demux_via_umbilical/", I get the following error:

⛔ Warning (emacs): Initialize request failed: Unable to start debugging. Unexpected GDB output from command "-environment-cd /home/reggiemarr/Projects/downlink-client/tests/test_demux_via_umbilical/". /home/reggiemarr/Projects/downlink-client/tests/test_demux_via_umbilical/: No such file or directory.

So it seems that there needs to be some custom handling so that when we are using cppdbg and we've populated the pipeTransport parameters cwd shouldn't neccesarily be interpretted as being a path on the host machine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant