mirror of https://github.com/jetkvm/kvm.git
feat: add gdbserver support for native code debugging
This commit is contained in:
parent
db53e89df1
commit
ac9999171b
|
|
@ -18,6 +18,7 @@ sudo apt-get install -y --no-install-recommends \
|
||||||
build-essential \
|
build-essential \
|
||||||
device-tree-compiler \
|
device-tree-compiler \
|
||||||
gperf g++-multilib gcc-multilib \
|
gperf g++-multilib gcc-multilib \
|
||||||
|
gdb-multiarch \
|
||||||
libnl-3-dev libdbus-1-dev libelf-dev libmpc-dev dwarves \
|
libnl-3-dev libdbus-1-dev libelf-dev libmpc-dev dwarves \
|
||||||
bc openssl flex bison libssl-dev python3 python-is-python3 texinfo kmod cmake \
|
bc openssl flex bison libssl-dev python3 python-is-python3 texinfo kmod cmake \
|
||||||
wget zstd \
|
wget zstd \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "GDB Debug - Native (binary)",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "internal/native/cgo/build/jknative-bin",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": true,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"miDebuggerPath": "/usr/bin/gdb-multiarch",
|
||||||
|
"miDebuggerServerAddress": "${config:TARGET_IP}:${config:DEBUG_PORT}",
|
||||||
|
"targetArchitecture": "arm",
|
||||||
|
"preLaunchTask": "deploy",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"externalConsole": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -14,5 +14,12 @@
|
||||||
"cmake.ignoreCMakeListsMissing": true,
|
"cmake.ignoreCMakeListsMissing": true,
|
||||||
"C_Cpp.inlayHints.autoDeclarationTypes.enabled": true,
|
"C_Cpp.inlayHints.autoDeclarationTypes.enabled": true,
|
||||||
"C_Cpp.inlayHints.parameterNames.enabled": true,
|
"C_Cpp.inlayHints.parameterNames.enabled": true,
|
||||||
"C_Cpp.inlayHints.referenceOperator.enabled": true
|
"C_Cpp.inlayHints.referenceOperator.enabled": true,
|
||||||
|
"files.associations": {
|
||||||
|
"*.yml": "yaml",
|
||||||
|
"*.libsonet": "jsonnet",
|
||||||
|
"rk_comm_mb.h": "c"
|
||||||
|
},
|
||||||
|
"TARGET_IP": "192.168.0.199",
|
||||||
|
"DEBUG_PORT": "2345",
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "deploy",
|
||||||
|
"isBackground": true,
|
||||||
|
"type": "shell",
|
||||||
|
"command": "bash",
|
||||||
|
"args": [
|
||||||
|
"dev_deploy.sh",
|
||||||
|
"-r",
|
||||||
|
"${config:TARGET_IP}",
|
||||||
|
"--gdb-port",
|
||||||
|
"${config:DEBUG_PORT}",
|
||||||
|
"--native-binary",
|
||||||
|
"--disable-docker"
|
||||||
|
],
|
||||||
|
"problemMatcher": {
|
||||||
|
"base": "$gcc",
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "${config:BINARY}",
|
||||||
|
"endsPattern": "Listening on port [0-9]{4}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -208,6 +208,12 @@ rm /userdata/kvm_config.json
|
||||||
systemctl restart jetkvm
|
systemctl restart jetkvm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Debug native code with gdbserver
|
||||||
|
|
||||||
|
Change the `TARGET_IP` in `.vscode/settings.json` to your JetKVM device IP, then set breakpoints in your native code and start the `Debug Native` configuration in VSCode.
|
||||||
|
|
||||||
|
The code and GDB server will be deployed automatically.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Testing Your Changes
|
## Testing Your Changes
|
||||||
|
|
|
||||||
3
Makefile
3
Makefile
|
|
@ -14,6 +14,8 @@ SKIP_NATIVE_IF_EXISTS ?= 0
|
||||||
SKIP_UI_BUILD ?= 0
|
SKIP_UI_BUILD ?= 0
|
||||||
ENABLE_SYNC_TRACE ?= 0
|
ENABLE_SYNC_TRACE ?= 0
|
||||||
|
|
||||||
|
CMAKE_BUILD_TYPE ?= Release
|
||||||
|
|
||||||
GO_BUILD_ARGS := -tags netgo,timetzdata,nomsgpack
|
GO_BUILD_ARGS := -tags netgo,timetzdata,nomsgpack
|
||||||
ifeq ($(ENABLE_SYNC_TRACE), 1)
|
ifeq ($(ENABLE_SYNC_TRACE), 1)
|
||||||
GO_BUILD_ARGS := $(GO_BUILD_ARGS),synctrace
|
GO_BUILD_ARGS := $(GO_BUILD_ARGS),synctrace
|
||||||
|
|
@ -52,6 +54,7 @@ build_native:
|
||||||
echo "Building native..."; \
|
echo "Building native..."; \
|
||||||
CC="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-gcc" \
|
CC="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-gcc" \
|
||||||
LD="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-ld" \
|
LD="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-ld" \
|
||||||
|
CMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
|
||||||
./scripts/build_cgo.sh; \
|
./scripts/build_cgo.sh; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ set -e
|
||||||
SCRIPT_PATH=$(realpath "$(dirname $(realpath "${BASH_SOURCE[0]}"))")
|
SCRIPT_PATH=$(realpath "$(dirname $(realpath "${BASH_SOURCE[0]}"))")
|
||||||
source ${SCRIPT_PATH}/build_utils.sh
|
source ${SCRIPT_PATH}/build_utils.sh
|
||||||
|
|
||||||
|
CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Release}
|
||||||
|
|
||||||
CGO_PATH=$(realpath "${SCRIPT_PATH}/../internal/native/cgo")
|
CGO_PATH=$(realpath "${SCRIPT_PATH}/../internal/native/cgo")
|
||||||
BUILD_DIR=${CGO_PATH}/build
|
BUILD_DIR=${CGO_PATH}/build
|
||||||
|
|
||||||
|
|
@ -31,7 +33,7 @@ VERBOSE=1 cmake -B "${BUILD_DIR}" \
|
||||||
-DCONFIG_LV_BUILD_EXAMPLES=OFF \
|
-DCONFIG_LV_BUILD_EXAMPLES=OFF \
|
||||||
-DCONFIG_LV_BUILD_DEMOS=OFF \
|
-DCONFIG_LV_BUILD_DEMOS=OFF \
|
||||||
-DSKIP_GLIBC_NAMES=ON \
|
-DSKIP_GLIBC_NAMES=ON \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
|
||||||
-DCMAKE_INSTALL_PREFIX="${TMP_DIR}"
|
-DCMAKE_INSTALL_PREFIX="${TMP_DIR}"
|
||||||
|
|
||||||
msg_info "▶ Copying built library and header files"
|
msg_info "▶ Copying built library and header files"
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ show_help() {
|
||||||
echo
|
echo
|
||||||
echo "Optional:"
|
echo "Optional:"
|
||||||
echo " -u, --user <remote_user> Remote username (default: root)"
|
echo " -u, --user <remote_user> Remote username (default: root)"
|
||||||
|
echo " --gdb-port <port> GDB debug port (default: 2345)"
|
||||||
echo " --run-go-tests Run go tests"
|
echo " --run-go-tests Run go tests"
|
||||||
echo " --run-go-tests-only Run go tests and exit"
|
echo " --run-go-tests-only Run go tests and exit"
|
||||||
echo " --skip-ui-build Skip frontend/UI build"
|
echo " --skip-ui-build Skip frontend/UI build"
|
||||||
|
|
@ -59,6 +60,7 @@ REMOTE_PATH="/userdata/jetkvm/bin"
|
||||||
SKIP_UI_BUILD=false
|
SKIP_UI_BUILD=false
|
||||||
SKIP_UI_BUILD_RELEASE=0
|
SKIP_UI_BUILD_RELEASE=0
|
||||||
SKIP_NATIVE_BUILD=0
|
SKIP_NATIVE_BUILD=0
|
||||||
|
GDB_DEBUG_PORT=2345
|
||||||
BUILD_NATIVE_BINARY=false
|
BUILD_NATIVE_BINARY=false
|
||||||
ENABLE_SYNC_TRACE=0
|
ENABLE_SYNC_TRACE=0
|
||||||
RESET_USB_HID_DEVICE=false
|
RESET_USB_HID_DEVICE=false
|
||||||
|
|
@ -81,6 +83,10 @@ while [[ $# -gt 0 ]]; do
|
||||||
REMOTE_USER="$2"
|
REMOTE_USER="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--gdb-port)
|
||||||
|
GDB_DEBUG_PORT="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
--skip-ui-build)
|
--skip-ui-build)
|
||||||
SKIP_UI_BUILD=true
|
SKIP_UI_BUILD=true
|
||||||
shift
|
shift
|
||||||
|
|
@ -148,7 +154,8 @@ fi
|
||||||
check_ping "${REMOTE_HOST}"
|
check_ping "${REMOTE_HOST}"
|
||||||
check_ssh "${REMOTE_USER}" "${REMOTE_HOST}"
|
check_ssh "${REMOTE_USER}" "${REMOTE_HOST}"
|
||||||
function sshdev() {
|
function sshdev() {
|
||||||
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${REMOTE_USER}@${REMOTE_HOST}" $@
|
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${REMOTE_USER}@${REMOTE_HOST}" "$@"
|
||||||
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# check if the current CPU architecture is x86_64
|
# check if the current CPU architecture is x86_64
|
||||||
|
|
@ -163,10 +170,17 @@ fi
|
||||||
|
|
||||||
if [ "$BUILD_NATIVE_BINARY" = true ]; then
|
if [ "$BUILD_NATIVE_BINARY" = true ]; then
|
||||||
msg_info "▶ Building native binary"
|
msg_info "▶ Building native binary"
|
||||||
make build_native
|
CMAKE_BUILD_TYPE=Debug make build_native
|
||||||
sshdev "killall -9 jetkvm_app jetkvm_app_debug jetkvm_native_debug || true"
|
msg_info "▶ Checking if GDB is available on remote host"
|
||||||
|
if ! sshdev "command -v gdbserver > /dev/null 2>&1"; then
|
||||||
|
msg_warn "Error: gdbserver is not installed on the remote host"
|
||||||
|
tar -czf - -C /opt/jetkvm-native-buildkit/gdb/ . | sshdev "tar -xzf - -C /usr/bin"
|
||||||
|
msg_info "✓ gdbserver installed on remote host"
|
||||||
|
fi
|
||||||
|
msg_info "▶ Stopping any existing instances of jetkvm_native_debug on remote host"
|
||||||
|
sshdev "killall -9 jetkvm_app jetkvm_app_debug jetkvm_native_debug gdbserver || true >> /dev/null 2>&1"
|
||||||
sshdev "cat > ${REMOTE_PATH}/jetkvm_native_debug" < internal/native/cgo/build/jknative-bin
|
sshdev "cat > ${REMOTE_PATH}/jetkvm_native_debug" < internal/native/cgo/build/jknative-bin
|
||||||
sshdev ash << EOF
|
sshdev -t ash << EOF
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Set the library path to include the directory where librockit.so is located
|
# Set the library path to include the directory where librockit.so is located
|
||||||
|
|
@ -177,7 +191,7 @@ killall -9 jetkvm_app jetkvm_app_debug jetkvm_native_debug || true
|
||||||
sleep 5
|
sleep 5
|
||||||
echo 'V' > /dev/watchdog
|
echo 'V' > /dev/watchdog
|
||||||
chmod +x jetkvm_native_debug
|
chmod +x jetkvm_native_debug
|
||||||
./jetkvm_native_debug
|
gdbserver localhost:${GDB_DEBUG_PORT} ./jetkvm_native_debug
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue