1. 环境:
ubuntu 系统 + strace + vim
2.编写挂死程序:(参考博客)
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <string.h> int main(int argc, char** argv) { getpid(); if(argc < 2) { printf("pick one (user|system)\n"); return 1; } if(!strcmp(argv[1], "user")) while(1); else if(!strcmp(argv[1], "system")) sleep(500); return 0; }
3.利用strace查看日志:
root@:~/watson# strace ./a.out user -o user_trace.log execve("./a.out", ["./a.out", "user", "-o", "user_trace.log"], [/* 20 vars */]) = 0 brk(0) = 0x9b49000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7773000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=91359, ...}) = 0 mmap2(NULL, 91359, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb775c000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000\226\1\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1730024, ...}) = 0 mmap2(NULL, 1743580, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75b2000 mprotect(0xb7755000, 4096, PROT_NONE) = 0 mmap2(0xb7756000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a3) = 0xb7756000 mmap2(0xb7759000, 10972, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7759000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75b1000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb75b1900, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb7756000, 8192, PROT_READ) = 0 mprotect(0x8049000, 4096, PROT_READ) = 0 mprotect(0xb7796000, 4096, PROT_READ) = 0 munmap(0xb775c000, 91359) = 0 getpid() = 28915
root@:~/watson# strace ./a.out system -o kernel_trace.log execve("./a.out", ["./a.out", "system", "-o", "kernel_trace.log"], [/* 20 vars */]) = 0 brk(0) = 0x8ee6000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7769000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=91359, ...}) = 0 mmap2(NULL, 91359, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7752000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000\226\1\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1730024, ...}) = 0 mmap2(NULL, 1743580, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75a8000 mprotect(0xb774b000, 4096, PROT_NONE) = 0 mmap2(0xb774c000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a3) = 0xb774c000 mmap2(0xb774f000, 10972, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb774f000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75a7000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb75a7900, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb774c000, 8192, PROT_READ) = 0 mprotect(0x8049000, 4096, PROT_READ) = 0 mprotect(0xb778c000, 4096, PROT_READ) = 0 munmap(0xb7752000, 91359) = 0 getpid() = 28917 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({500, 0},
tip:
1. 对于user层面测试,出现
getpid() = 28934 ^C--- SIGINT (Interrupt) @ 0 (0) ---
SIGINT的捕捉,中断出现。
对于 getpid() = 28915,则是getid()函数执行的过程,后续无log输出。
陷入while(1)操作。
2. 对于system层面测试,出现
nanosleep({500, 0}, ^C <unfinished ...>
unfinished出现。
nanosleep 是未完整,当修改程序sleep(1)
nanosleep({1, 0}, 0xbfac2df8) = 0 exit_group(0) = ?
最终退出exit_group
是因为在调用sleep时卡死,没法正常运行,是挂死在系统调用。(具体看接口手册)
4. 结论(前提没有exit_group)
1. strace log显示最终的log完整,则卡死在程序逻辑上。
2. strace log显示最终的log不完整,则卡死在系统调用上。
(结论或许有反驳,当调用一个get_id的接口是,该接口自己实现的。)
int get_id() { return 1; }
输出的log不完整,也就挂死在get_id,该也是调用,并非系统调用。
Life is mess, don't let mess mess us.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了