[Pthread] Linux上程序调试的基石(一)--ptrace

本文介绍了Linux系统调用ptrace,它是进程跟踪的基础,用于父进程监控和控制子进程。通过ptrace,可以实现类似strace和gdb的功能。以strace为例,展示了如何使用ptrace跟踪和记录进程的系统调用及信号处理,揭示了strace跟踪系统调用的基本原理。
引子:
1.在Linux系统中,进程状态除了我们所熟知的TASK_RUNNING,TASK_INTERRUPTIBLE,TASK_STOPPED等,还有一个TASK_TRACED。这表明这个进程处于什么状态?
2.strace可以方便的帮助我们记录进程所执行的系统调用,它是如何跟踪到进程执行的?
3.gdb是我们调试程序的利器,可以设置断点,单步跟踪程序。它的实现原理又是什么?

所有这一切的背后都隐藏着Linux所提供的一个强大的系统调用ptrace().

1.ptrace系统调用
ptrace系统调从名字上看是用于进程跟踪的,它提供了父进程可以观察和控制其子进程执行的能力,并允许父进程检查和替换子进程的内核镜像(包括寄存器)的值。其基本原理是: 当使用了ptrace跟踪后,所有发送给被跟踪的子进程的信号(除了SIGKILL),都会被转发给父进程,而子进程则会被阻塞,这时子进程的状态就会被系统标注为TASK_TRACED。而父进程收到信号后,就可以对停止下来的子进程进行检查和修改,然后让子进程继续运行。    
    其原型为:    
    #include <sys/ptrace.h>
    long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
    ptrace有四个参数:
    1). enum __ptrace_request request:指示了ptrace要执行的命令。
    2). pid_t pid: 指示ptrace要跟踪的进程。
    3). void *addr: 指示要监控的内存地址。
    4). void *data: 存放读取出的或者要写入的数据。
ptrace是如此的
make[2]: Entering directory ‘/home/bba/work/BBA1_5/MBB_Platform/apps/public/openssl-1.1.1f’ /usr/bin/perl apps/progs.pl apps/openssl > apps/progs.h mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/asn1pars.d.tmp -MT apps/asn1pars.o -c -o apps/asn1pars.o apps/asn1pars.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/ca.d.tmp -MT apps/ca.o -c -o apps/ca.o apps/ca.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/ciphers.d.tmp -MT apps/ciphers.o -c -o apps/ciphers.o apps/ciphers.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/cms.d.tmp -MT apps/cms.o -c -o apps/cms.o apps/cms.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/crl.d.tmp -MT apps/crl.o -c -o apps/crl.o apps/crl.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/crl2p7.d.tmp -MT apps/crl2p7.o -c -o apps/crl2p7.o apps/crl2p7.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/dgst.d.tmp -MT apps/dgst.o -c -o apps/dgst.o apps/dgst.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/dhparam.d.tmp -MT apps/dhparam.o -c -o apps/dhparam.o apps/dhparam.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/dsa.d.tmp -MT apps/dsa.o -c -o apps/dsa.o apps/dsa.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/dsaparam.d.tmp -MT apps/dsaparam.o -c -o apps/dsaparam.o apps/dsaparam.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/ec.d.tmp -MT apps/ec.o -c -o apps/ec.o apps/ec.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/ecparam.d.tmp -MT apps/ecparam.o -c -o apps/ecparam.o apps/ecparam.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/enc.d.tmp -MT apps/enc.o -c -o apps/enc.o apps/enc.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/engine.d.tmp -MT apps/engine.o -c -o apps/engine.o apps/engine.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/errstr.d.tmp -MT apps/errstr.o -c -o apps/errstr.o apps/errstr.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/gendsa.d.tmp -MT apps/gendsa.o -c -o apps/gendsa.o apps/gendsa.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/genpkey.d.tmp -MT apps/genpkey.o -c -o apps/genpkey.o apps/genpkey.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/genrsa.d.tmp -MT apps/genrsa.o -c -o apps/genrsa.o apps/genrsa.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/nseq.d.tmp -MT apps/nseq.o -c -o apps/nseq.o apps/nseq.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/ocsp.d.tmp -MT apps/ocsp.o -c -o apps/ocsp.o apps/ocsp.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/openssl.d.tmp -MT apps/openssl.o -c -o apps/openssl.o apps/openssl.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/passwd.d.tmp -MT apps/passwd.o -c -o apps/passwd.o apps/passwd.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/pkcs12.d.tmp -MT apps/pkcs12.o -c -o apps/pkcs12.o apps/pkcs12.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/pkcs7.d.tmp -MT apps/pkcs7.o -c -o apps/pkcs7.o apps/pkcs7.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/pkcs8.d.tmp -MT apps/pkcs8.o -c -o apps/pkcs8.o apps/pkcs8.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/pkey.d.tmp -MT apps/pkey.o -c -o apps/pkey.o apps/pkey.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/pkeyparam.d.tmp -MT apps/pkeyparam.o -c -o apps/pkeyparam.o apps/pkeyparam.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/pkeyutl.d.tmp -MT apps/pkeyutl.o -c -o apps/pkeyutl.o apps/pkeyutl.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/prime.d.tmp -MT apps/prime.o -c -o apps/prime.o apps/prime.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/rand.d.tmp -MT apps/rand.o -c -o apps/rand.o apps/rand.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/rehash.d.tmp -MT apps/rehash.o -c -o apps/rehash.o apps/rehash.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/req.d.tmp -MT apps/req.o -c -o apps/req.o apps/req.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/rsa.d.tmp -MT apps/rsa.o -c -o apps/rsa.o apps/rsa.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/rsautl.d.tmp -MT apps/rsautl.o -c -o apps/rsautl.o apps/rsautl.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/s_client.d.tmp -MT apps/s_client.o -c -o apps/s_client.o apps/s_client.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/s_server.d.tmp -MT apps/s_server.o -c -o apps/s_server.o apps/s_server.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/s_time.d.tmp -MT apps/s_time.o -c -o apps/s_time.o apps/s_time.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/sess_id.d.tmp -MT apps/sess_id.o -c -o apps/sess_id.o apps/sess_id.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/smime.d.tmp -MT apps/smime.o -c -o apps/smime.o apps/smime.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/speed.d.tmp -MT apps/speed.o -c -o apps/speed.o apps/speed.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/spkac.d.tmp -MT apps/spkac.o -c -o apps/spkac.o apps/spkac.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/srp.d.tmp -MT apps/srp.o -c -o apps/srp.o apps/srp.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/storeutl.d.tmp -MT apps/storeutl.o -c -o apps/storeutl.o apps/storeutl.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/ts.d.tmp -MT apps/ts.o -c -o apps/ts.o apps/ts.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/verify.d.tmp -MT apps/verify.o -c -o apps/verify.o apps/verify.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/version.d.tmp -MT apps/version.o -c -o apps/version.o apps/version.c mipsel-linux-gcc -I. -Iinclude -Iapps -pthread -Wall -Os -DGNU -DNDEBUG -MMD -MF apps/x509.d.tmp -MT apps/x509.o -c -o apps/x509.o apps/x509.c rm -f apps/openssl ${LDCMD:-mipsel-linux-gcc} -pthread -Wall -Os -DGNU -L. -o apps/openssl apps/asn1pars.o apps/ca.o apps/ciphers.o apps/cms.o apps/crl.o apps/crl2p7.o apps/dgst.o apps/dhparam.o apps/dsa.o apps/dsaparam.o apps/ec.o apps/ecparam.o apps/enc.o apps/engine.o apps/errstr.o apps/gendsa.o apps/genpkey.o apps/genrsa.o apps/nseq.o apps/ocsp.o apps/openssl.o apps/passwd.o apps/pkcs12.o apps/pkcs7.o apps/pkcs8.o apps/pkey.o apps/pkeyparam.o apps/pkeyutl.o apps/prime.o apps/rand.o apps/rehash.o apps/req.o apps/rsa.o apps/rsautl.o apps/s_client.o apps/s_server.o apps/s_time.o apps/sess_id.o apps/smime.o apps/speed.o apps/spkac.o apps/srp.o apps/storeutl.o apps/ts.o apps/verify.o apps/version.o apps/x509.o apps/libapps.a -lssl -lcrypto -ldl -pthread ./libcrypto.so: warning: gethostbyname is obsolescent, use getnameinfo() instead. ./libcrypto.so: undefined reference to getcontext' ./libcrypto.so: undefined reference to setcontext’ ./libcrypto.so: undefined reference to `makecontext’ collect2: ld returned 1 exit status Makefile:6187: recipe for target ‘apps/openssl’ failed make[2]: *** [apps/openssl] Error 1 make[2]: Leaving directory ‘/home/bba/work/BBA1_5/MBB_Platform/apps/public/openssl-1.1.1f’ Makefile:183: recipe for target ‘build_programs’ failed make[1]: *** [build_programs] Error 2 make[1]: Leaving directory ‘/home/bba/work/BBA1_5/MBB_Platform/apps/public/openssl-1.1.1f’ make/apps/pubapps/openssl.mk:3: recipe for target ‘openssl’ failed make: *** [openssl] Error 2
最新发布
09-23
你贴出的构建日志和之前的完全致,说明 **尽管我们已经建议添加 `no-async`,但你还没有重新配置(re-configure)OpenSSL**。 --- ## 🔴 核心问题重申 ```bash undefined reference to `getcontext' undefined reference to `setcontext' undefined reference to `makecontext' ``` 这是因为在 **MIPS + 嵌入式 libc(如 uclibc/musl)环境中,`ucontext` 系列函数不可用**,而 OpenSSL 默认启用了依赖这些函数的 **异步上下文支持(`ASYNC`)**。 > ✅ 解决方法只有条:**在执行 `./Configure` 时明确禁用 `async` 支持** --- ## ✅ 正确修复步骤(必须完整执行) ### 🛠️ 第步:彻底清理旧构建状态 ```bash cd /home/bba/work/BBA1_5/MBB_Platform/apps/public/openssl-1.1.1f # 彻底清除之前生成的 Makefile、依赖、对象文件 make distclean ``` > ⚠️ 注意:如果 `make distclean` 失败或不存在,可以直接删除整个目录后解压干净源码。 --- ### 🛠️ 第二步:使用正确的 `./Configure` 命令(含 `no-async`) ```bash CC=mipsel-linux-gcc \ AR=mipsel-linux-ar \ RANLIB=mipsel-linux-ranlib \ ./Configure \ --prefix=/home/bba/work/BBA1_5/MBB_Platform/apps/public/openssl-1.1.1f/install \ --cross-compile-prefix=mipsel-linux- \ shared \ linux-generic32 \ no-zlib \ no-asm \ no-hw \ no-engine \ no-ssl3 \ no-comp \ no-err \ no-async \ # 👈 关键!必须加上这行 no-srp \ no-dtls \ no-tls1 \ no-weak-ssl-ciphers \ -Os -DGNU -DNDEBUG -DCONFIG_TP_IMAGE ``` 📌 特别注意: - `no-async` 是解决 `getcontext` 错误的根本手段 - 必须在 `./Configure` 阶段加入,不能后期补 - 如果不重新运行 `./Configure`,`Makefile` 中仍会链接 `async.o` 模块 → 继续报错 --- ### 🛠️ 第三步:编译并安装 ```bash make depend # 更新依赖关系(可选) make -j$(nproc) make install ``` ✅ 成功后你会看到: - `install/lib/libcrypto.so` - `install/bin/openssl`(可选工具- 不再出现 `getcontext` 链接错误 --- ## ❓ 为什么 `no-async` 能解决问题? | 组件 | 说明 | |------|------| | `async.o` / `async_wait.o` | OpenSSL 的异步任务调度模块 | | 它内部调用 | `getcontext`, `setcontext`, `makecontext` | | 这些函数在 glibc 中存在 | 但在 **musl、uclibc、bare-metal libc 中通常缺失** | | 所以链接失败 | 即使代码没用到 async 功能,只要模块被编译进去就会引用 | 👉 加上 `no-async` 后: - OpenSSL 宏定义中禁用 `OPENSSL_USE_ASYNC_JOB` - 相关代码不会被编译 - 不再调用 `ucontext` 函数 - 链接成功! --- ## ✅ 可选进步裁剪(适合嵌入式设备) 继续减小体积和依赖: ```bash no-stdio # 禁用 stdin/stdout 相关功能(如 apps 模块) no-ui # 禁用用户交互接口 no-dso # 禁用动态加载引擎(避免 dlopen 等依赖) no-tests # 不编译测试程序 no-deprecated # 禁用废弃 API ``` 例如: ```bash no-async no-stdio no-ui no-dso no-tests no-deprecated ``` 如果你不需要 `apps/openssl` 工具本身,甚至可以跳过编译它。 --- ## ✅ 如何验证是否真的修复了? 成功构建后运行: ```bash file install/lib/libcrypto.so ``` 输出应类似: ``` ELF 32-bit LSB shared object, MIPS, MIPS32 version 1, dynamically linked, stripped ``` 确认是 MIPS 架构,并且能正常部署到目标设备。 --- ## 🧩 补充:关于 `gethostbyname` 警告 ```bash warning: gethostbyname is obsolescent, use getnameinfo() instead. ``` 这个只是 **警告(warning)**,不是错误。不影响编译。 它是 OpenSSL 自带代码使用的旧 API,在嵌入式环境下常见,可暂时忽略。 若想消除警告,需打补丁替换为 `getaddrinfo()`,但非必要。 --- ## ✅ 总结 | 问题 | 解法 | |------|------| | `undefined reference to getcontext` | ➕ `no-async` 到 `./Configure` | | 必须重新 configure | ❌ 仅 `make clean` 不够 | | 是否影响功能? | ✅ 普通 TLS 通信无任何影响 | | 推荐做法 | 在所有嵌入式平台都加 `no-async` | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值