You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ptrace获取子进程系统调用参数与返回值的问题排查

问题分析与解决

你看到的18446744073709551578是**-6的64位无符号整数表示**(对应十六进制0xfffffffffffffffa),这说明系统调用返回了错误码EBADF(无效文件描述符),但你的代码错误地把带符号的返回值当作无符号数打印了。

核心问题

Linux系统调用的返回规则是:

  • 调用成功时,rax寄存器存储正数或0;
  • 调用失败时,rax存储负数形式的错误码(比如-EBADF即-6)。

你用%llu(无符号长整型格式符)打印regs.rax,会把负数强制转换为超大无符号数,就出现了看到的异常值。

代码修正

修改返回值的打印逻辑,先判断返回值是否为负,再做对应处理:

// 替换原有的printf行
long long ret = regs.rax;
if (ret < 0) {
    // 错误情况:取反得到错误码,并用strerror输出对应描述
    printf(" -> -%d (%s)\n", (int)-ret, strerror((int)-ret));
} else {
    // 成功情况:正常打印返回值
    printf(" -> %lld\n", ret);
}

额外排查方向

  1. 验证系统调用参数合法性:比如输出里多次出现close(3),可能是子进程重复关闭已释放的文件描述符,导致EBADF错误,可在系统调用进入时打印参数确认。
  2. 确认寄存器结构正确性:确保你使用的user_regs_struct是对应架构(比如x86_64)的正确定义,rax和orig_rax的偏移没有错误。
  3. 检查waitpid逻辑:当前两次waitpid的循环没有处理子进程退出的边界情况,可能导致无限循环,建议在WIFEXITED(status)或WIFSIGNALED(status)时跳出循环。

内容的提问来源于stack exchange,提问作者user2374991

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:23:20