我使用C和我制作apache模块,我使用strace作为调试时间的主要工具。这是我扔在一起的代码。如果变量名称不符合标准,我表示歉意。
#include <stdio.h>
int main(){
long ct2,ct; //counters
int a=0; //dummy value
FILE *f0=fopen("/","r"); //measuring point
ct2=10;
while (--ct2>0){
ct=5000000;
while (--ct>0){
if (!!a){
printf("%d",a);
}
}
}
FILE *f=fopen("/","r"); //measuring point
ct2=10;
while (--ct2>0){
ct=5000000;
while (--ct>0){
if (a){
printf("%d",a);
}
}
}
FILE *f2=fopen("/","r"); //measuring point
return 0;
}
此代码可以编译。然后我通过strace运行它(通过键入终端:strace -r -ttt ./a.out
),我看到了:
0.000000 execve("./a.out", ["./a.out"], [/* 47 vars */]) = 0
0.000315 brk(0) = 0x804a000
0.000124 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
0.000144 open("/etc/ld.so.cache", O_RDONLY) = 3
0.000116 fstat64(3, {st_mode=S_IFREG|0644, st_size=139721, ...}) = 0
0.000138 mmap2(NULL, 139721, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7ece000
0.000114 close(3) = 0
0.000109 open("/lib/libc.so.6", O_RDONLY) = 3
0.000113 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360d\1"..., 512) = 512
0.000130 fstat64(3, {st_mode=S_IFREG|0755, st_size=1575187, ...}) = 0
0.000131 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ecd000
0.000122 mmap2(NULL, 1357360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7d81000
0.000119 mmap2(0xb7ec7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x146) = 0xb7ec7000
0.000146 mmap2(0xb7eca000, 9776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7eca000
0.000139 close(3) = 0
0.000112 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d80000
0.000119 set_thread_area({entry_number:-1 -> 6, base_addr:0xb7d806c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
0.000217 mprotect(0xb7ec7000, 4096, PROT_READ) = 0
0.000108 munmap(0xb7ece000, 139721) = 0
0.000174 brk(0) = 0x804a000
0.000099 brk(0x806b000) = 0x806b000
0.000110 open("/", O_RDONLY) = 3
0.203487 open("/", O_RDONLY) = 4
0.202225 open("/", O_RDONLY) = 5
0.000133 exit_group(0) = ?
我最后可以告诉你:
0.000110 open("/", O_RDONLY) = 3
0.203487 open("/", O_RDONLY) = 4
0.202225 open("/", O_RDONLY) = 5
返回我设置的三个测量点。
我希望能够在我的代码中调整测量点线,这样当我运行strace时,我可以像现在一样找到我的测量点,但系统的操作次数较少。除了文件调用之外,我没有看到与我的程序相关的任何其他内容。
我想也许在C中有一个内置的MeasureMe函数可以用来代替代码中的测量点线,然后strace可以输出:
0.000110 MeasureMe called in code
0.203487 MeasureMe called in code
0.202225 MeasureMe called in code
有什么方法可以用Strace来解决这个问题吗?
我之所以要问strace而不是gdb是因为我用它来调试请求到我的apache服务器,就像这个视频中的人那样,我将能够看到apache模块在运行:< / p>
https://www.youtube.com/watch?v=eF-p--AH37E
知道如何解决这个问题吗?或者我是否必须继续尝试打开不存在的文件?
答案 0 :(得分:2)
我收集您当前使用的是open("/",O_RDONLY)
[或open("/i_do_not_exist",O_RDONLY)
]的“跟踪点”。不幸的是,因为你正在使用strace
,所以你被限制使用系统调用。但是,是一种实现所需效果的方法。
您在源代码中的各个点手动插入的跟踪点需要/想要的是:
access
] 实际上,dup
关于一个糟糕的fildes很好地填补了这个账单:
dup(-10000);
它将返回EBADF
。它很容易被区分为跟踪点,因为大多数真正的dup
调用“不好”将是dup(-1)
您可以根据需要添加尽可能多的这些内容。实际参数成为“跟踪点编号”:
dup(-10001); // tracepoint 1
...
dup(-10002); // tracepoint 2
...
dup(-10003); // tracepoint 3
输出如下:
0.000044 dup(-10001) = -1 EBADF (Bad file descriptor)
0.000022 dup(-10002) = -1 EBADF (Bad file descriptor)
0.000019 dup(-10003) = -1 EBADF (Bad file descriptor)
我通常将其封装在一个宏中:
#ifdef DEBUG
#define TRACEPOINT(_tno) tracepoint(_tno)
#else
#define TRACEPOINT(_tno) /**/
#endif
void
tracepoint(int tno)
{
dup(-10000 - tno);
}
然后,我添加了类似的内容:
TRACEPOINT(1); // initialization phase
...
TRACEPOINT(2); // execution phase
...
TRACEPOINT(3); // cleanup/shutdown
现在,我将编写一个perl
或python
脚本来读取源文件,提取给定跟踪点的注释,并将它们附加到{{1}中的匹配行输出文件:
strace
更复杂的后处理脚本版本可以执行各种操作:
0.000044 TRACEPOINT(1) initialization phase
0.000022 TRACEPOINT(2) execution phase
0.000019 TRACEPOINT(3) cleanup/shutdown
和断点]