#!/bin/bash # # Copyright (c) 2024 Red Hat, Inc. # # SPDX-License-Identifier: Apache-2.0 # # This script allows debugging the GO kata shim using Delve. # It will start the delve debugger in a way where it runs the program and waits # for connections from your client interface (dlv commandline, vscode, etc). # # You need to configure crio or containerd to use this script in place of the # regular kata shim binary. # For cri-o, that would be in the runtime configuration, under # /etc/crio/crio.conf.d/ # # Use this for quick-testing the shim binary without a debugger #NO_DEBUG=1 # Edit this to point to the actual shim binary that needs to be debugged # Make sure you build it with the following flags: # -gcflags=all=-N -l SHIM_BINARY=/go/src/github.com/kata-containers/kata-containers/src/runtime/__debug_bin DLV_PORT=12345 # Edit the following to make sure dlv is in the PATH export PATH=/usr/local/go/bin/:$PATH # The shim can be called multiple times for the same container. # If it is already running, subsequent calls just return the socket address that # crio/containerd need to connect to. # This is useful for recovery, if crio/contaienrd is restarted and loses context. # # We usually don't want to debug those additional calls while we're already # debugging the actual server process. # To avoid running additional debuggers and blocking on them, we use a lock file. LOCK_FILE=/tmp/shim_debug.lock if [ -e $LOCK_FILE ]; then NO_DEBUG=1 fi # crio can try to call the shim with the "features" or "--version" parameters # to get capabilities from the runtime (assuming it's an OCI compatible runtime). # No need to debug that, so just run the regular shim. case "$1" in "features" | "--version") NO_DEBUG=1 ;; esac if [ "$NO_DEBUG" == "1" ]; then $SHIM_BINARY "$@" exit $? fi # dlv commandline # # --headless: dlv run as a server, waiting for a connection # # --listen: port to listen to # # --accept-multiclient: allow multiple dlv client connections # Allows having both a commandline and a GUI # # -r: have the output of the shim redirected to a separate file. # This script will retrieve the output and return it to the # caller, while letting dlv run in the background for debugging. # # -- $@ => give the shim all the parameters this script was given # SHIMOUTPUT=$(mktemp /tmp/shim_output_XXXXXX) cat > $LOCK_FILE << EOF #!/bin/bash dlv exec ${SHIM_BINARY} --headless --listen=:$DLV_PORT --accept-multiclient -r stdout:$SHIMOUTPUT -r stderr:$SHIMOUTPUT -- "\$@" rm $LOCK_FILE EOF chmod +x $LOCK_FILE # We're starting dlv as a background task, so that it continues to run while # this script returns, letting the caller resume its execution. # # We're redirecting the outputs of dlv itself to a separate file so that the # only output the caller will have is the one from this script, giving it the # address of the socket to connect to. # ${LOCK_FILE} "$@" > /tmp/dlv_output 2>&1 & # wait for the output file of the shim process to be filled with the address. while [ ! -s $SHIMOUTPUT ]; do sleep 1 done # write the adress to stdout cat $SHIMOUTPUT exit 0