试图通过陷阱标记和陷阱信号处理程序单步执行程序,在vsyscall上崩溃

试图通过陷阱标记和陷阱信号处理程序单步执行程序,在vsyscall上崩溃,第1张

概述试图通过陷阱标记和陷阱信号处理程序单步执行程序,在vsyscall上崩溃

我想创build一个完整的程序执行指令跟踪,收集一些统计信息等。我首先尝试使用linux的ptracefunction来逐步通过一个程序(使用这里的教程)。 这创build了两个进程,跟踪的和deBUGging器,并通过信号进行通信。 我只有每秒16K的指令(在1.6GHz Atom上),所以对于任何不重要的东西来说这太慢了。

我以为通过信号的进程间通信太慢了,所以我试着在执行过程中设置deBUGging:设置陷阱标志,并创build一个信号处理程序。 当一个软件中断被用来做一个系统调用时,陷阱标志应该被保存,内核将使用它自己的标志 – 所以我想。 但我的程序不知何故被信号SIGTRAP杀死。

这是我设置的:

#include <stdio.h> #include <unistd.h> #include <signal.h> int cycle = 0; voID trapHandler(int signum) { if (cycle % 262144 == 0) { write(STDOUT_fileNO," trapn",6); } cycle += 1; } voID startTrace() { // set up signal handler signal(SIGTRAP,trapHandler); // set trap flag asm volatile("pushfln" "orl $0x100,(%esp)n" "popfln" ); } voID printRock() { char* s = "Rockn"; asm( "movl $5,%%edxn" // message length "movl %0,%%ecxn" // message to write "movl $1,%%ebxn" // file descriptor (stdout) "movl $4,%%eaxn" // system call number (sys_write) "int $0x80n" // sycall : // no output regs : "r"(s) // input text : "edx","ecx","ebx","eax" ); } int main() { startTrace(); // some computation int x = 0; int i; for (i = 0; i < 100000; i++) { x += i*2; } printRock(); write(STDOUT_fileNO,"Papern",6); write(STDOUT_fileNO,"Scissorsn",9); }

运行时,这给出:

收到TERM信号后Java Swing应用程序不会退出

linux:窥探一个信号,而不是为随后的核心转储废弃寄存器?

如何按C到达的顺序处理多个信号

XOPEN_SOURCE和信号处理

在库(2)调用中禁用SIGPIPE信号

trap trap trap Rock Paper trap Trace/breakpoint trap (core dumped)

所以现在我们每秒得到大约25万条指令,仍然很慢但是不重要的执行是可能的。 但是在这两个写入调用之间似乎会发生核心转储。 在GDB,我们看到它发生的地方:

Dump of assembler code for function __kernel_vsyscall: 0xb76f3414 <+0>: push %ecx 0xb76f3415 <+1>: push %edx 0xb76f3416 <+2>: push %ebp 0xb76f3417 <+3>: mov %esp,%ebp 0xb76f3419 <+5>: sysenter 0xb76f341b <+7>: nop 0xb76f341c <+8>: nop 0xb76f341d <+9>: nop 0xb76f341e <+10>: nop 0xb76f341f <+11>: nop 0xb76f3420 <+12>: nop 0xb76f3421 <+13>: nop 0xb76f3422 <+14>: int $0x80 => 0xb76f3424 <+16>: pop %ebp 0xb76f3425 <+17>: pop %edx 0xb76f3426 <+18>: pop %ecx 0xb76f3427 <+19>: ret

回溯:

Program terminated with signal SIGTRAP,Trace/breakpoint trap. #0 0xb77c5424 in __kernel_vsyscall () #1 0xb76d0553 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:81 #2 0x0804847d in trapHandler (signum=5) at count.c:8 #3 <signal handler called> #4 0xb77c5424 in __kernel_vsyscall () #5 0xb76d0553 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:81 #6 0x08048537 in main () at count.c:49

看来通过int 80发生的系统调用是好的,但写调用使用内核的VIDSO / vsyscall中断(我不知道这个function, 这里更详细的描述)。 这可能与使用sysenter而不是int 80 ,也许在进入内核时陷阱标记仍然存在。 我不太清楚recursion__kernel_vsyscall调用的情况。 我也不明白为什么__kernel_vsyscall函数中有一个int 80调用。

有没有人有什么build议,以及如何解决这个问题? 也许可以禁用VDSO / vsysicall? 或者是有可能重写__kernel_vsyscall函数与一个使用int 80而不是sysenter ?

尝试在windows上的Hotspot JVM中处理SIGBREAK时发生IllegalArgumentException

如何确定unix信号队列(linux)中未决信号的数量

在处理程序中阻止新的信号

C#windows服务事件

为什么控制台上的信号处理没有输出?

回答自己的问题。 我没有弄清楚发生了什么事情或详细解释,但我发现一个解决方法:禁用VDSO。 这可以通过

sudo sysctl vm.vdso_enabled=0

有了这个,这整个单一的步骤通过一个程序工作,包括跨系统调用。 免责声明:如果事情变坏,不要责怪我。

编辑:更新我的linux(32位x86)更晚之后,此错误不再发生。 也许这是一个固定的错误。

总结

以上是内存溢出为你收集整理的试图通过陷阱标记和陷阱信号处理程序单步执行程序,在vsyscall上崩溃全部内容,希望文章能够帮你解决试图通过陷阱标记和陷阱信号处理程序单步执行程序,在vsyscall上崩溃所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1288094.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存