SUSE SLES15 Docker容器中gdbserver无法附加运行进程的问题求助
Let’s break down the two errors you’re facing and walk through the root causes and fixes to get your gdbserver attached to your C++ process successfully.
Error 1: Cannot attach to lwp 59: No such file or directory (2)
This error usually means gdbserver can’t locate the target process’s resources, even though ps -e shows it’s running. The most likely culprits are:
Cross-container PID namespace isolation
If you’re runninggdbserverin a separatedebuggercontainer (via--container debugger), Kubernetes/Docker assigns each container its own PID namespace by default. That means the process ID59exists in your C++ app’s container, but not in thedebuggercontainer’s namespace—so gdbserver can’t find it.Invalid executable path or deleted binary
Check if the C++ binary’s path is still accessible to gdbserver. Runls -l /proc/<pid>/exein the same container as the target process: if this returns a broken symlink, the binary was deleted or moved after the process started, which gdbserver needs to debug.Restricted procfs access
SLES15 might mount/procwithhidepidflags (e.g.,hidepid=2) that block non-root users from accessing other processes’/procentries. Even ifpsshows the process, gdbserver can’t read the required/proc/<pid>files.
Error 2: Cannot attach to process 220: Operation not permitted (1)
This is a permission issue that blocks the ptrace system call (used by gdbserver to attach to processes). Common causes:
Missing
SYS_PTRACEcapability
Docker/Kubernetes blocksptraceby default for security reasons. Without theSYS_PTRACEcapability, gdbserver can’t attach to any process.Kernel
ptrace_scoperestrictions
The kernel’syama/ptrace_scopesysctl setting (found at/proc/sys/kernel/yama/ptrace_scope) might be set to1or2, which limitsptraceto only parent-child processes or requires explicit capabilities.AppArmor/SELinux policies
SLES15’s AppArmor (or SELinux) policies might be configured to blockptraceoperations within containers, even if capabilities are granted.Mismatched user permissions
If gdbserver is running as a non-root user, and the target process is owned by root (or a different user), you’ll lack the permissions to attach.
Fixes & Troubleshooting Steps
Follow these steps to resolve the issues:
1. Fix Cross-Container PID Isolation (if using multiple containers)
If your C++ app and gdbserver are in separate containers in the same Pod:
- Enable shared PID namespace in your Kubernetes Pod spec:
This lets all containers in the Pod see each other’s processes, so the PID from your app container will be valid in thespec: shareProcessNamespace: truedebuggercontainer.
2. Grant SYS_PTRACE Capability
- For Docker: Start your container with the capability:
docker run --cap-add=SYS_PTRACE ... - For Kubernetes: Add the capability to your container’s security context:
spec: containers: - name: debugger securityContext: capabilities: add: ["SYS_PTRACE"] - name: your-cpp-app securityContext: capabilities: add: ["SYS_PTRACE"] # Also add if you need to debug within the app container
3. Adjust Kernel ptrace_scope (if needed)
- In the container, check the current setting:
cat /proc/sys/kernel/yama/ptrace_scope - If it’s
1or2, temporarily set it to0(allows any process withSYS_PTRACEto attach):echo 0 > /proc/sys/kernel/yama/ptrace_scope - To make this persistent across container restarts, add a sysctl configuration to your Kubernetes Pod:
Note: Some Kubernetes clusters restrict sysctl changes—check your cluster’s policies.spec: securityContext: sysctls: - name: kernel.yama.ptrace_scope value: "0"
4. Verify Executable Path & Procfs Access
- In the target process’s container, confirm the binary path is valid:
If the symlink is broken, ensure the binary isn’t deleted/moved after startup, and that gdbserver has access to the same path.ls -l /proc/<pid>/exe - Check procfs mount flags:
If you seemount | grep prochidepid=2, run gdbserver as root (or adjust the procfs mount to remove the flag, though this is less secure).
5. Check User Permissions & Security Policies
- Run gdbserver as root (use
sudoor start the container withUSER rootif needed)—root has unrestricted access to attach to processes. - For AppArmor issues (SLES15 default): Temporarily disable AppArmor for the container to test (not recommended for production):
For Kubernetes, you can set the security context to disable AppArmor:docker run --security-opt apparmor=unconfined ...securityContext: appArmorProfile: type: Unconfined
内容的提问来源于stack exchange,提问作者Franz

