c++ - 通过信号和返回地址改变程序执行流程

标签 c++ g++ signals callstack activation-record

我试图通过更改此代码中函数的返回地址来更改程序执行流程:

void s(int signum) {
    int b = 1;
    *(&b+3) = *(&b+3) + 4;
}

void f() {
    while(true);
    printf("f exit\n");
}

int main() {
    signal( SIGCONT, s );

    f();

    printf("end of prog");

    return 0;
}

为此,我调用了 f功能。所以它卡在了 while(true) .然后我发送一个SIGCONT使用 kill -SIGCONT <PID> 进行编程的信号命令。现在程序必须中断执行 while(true)f并执行 s功能。在 s我定义的函数 b查找 s 的返回地址运行时堆栈中的函数 *(&b+3) .我尝试使用 *(&b+3) = *(&b+3) + 4 更改此值这样当它回到 f 时, 跳过 while(true) 的执行并执行 printf("f exit\n") .但它一直卡在 while而且我不知道如何进行这项工作。

注意:我通过将 *(&b+3) 与之前 __builtin_return_address(0) 返回的值进行比较来验证它是否为返回地址。

函数体 mainf必须不变。

谢谢。

最佳答案

解决方案是以某种方式告诉 while 循环发生了某些变化。 例如

volatile int flag = 0 ;

void s(int signum) {
    int b = 1;
    __sync_fetch_and_add( &flag, 1 ) ;
}

void f() {
    while(__sync_fetch_and_add( &flag, 0 ) == 0);
    printf("f exit\n");
}

添加了原子内部函数(函数 __sync_fetch_and_add)以避免优化循环。我不确定一个简单的 volatile 是否足够。等待自己对此发表评论....

关于c++ - 通过信号和返回地址改变程序执行流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31324869/

相关文章:

java - G++编译的DLL有不同的函数名称

c - C 中的连接超时

c++ - 关于 C++ 中 union 使用的内存效率

C++、Visual Studio 2008、错误 C2556、C2371

c++ - 如何在运行时摆脱 LD_LIBRARY_PATH?

linux - 是否有系统调用或某种方式知道 Linux 中文件描述符的类型(例如常规文件 fd、套接字 fd、信号 fd、计时器 fd)?

c - 当 parent 将数据写入与 fork 的 child 共享的管道并且两者都在读取数据时,如何防止 parent 在 child 之前读取数据?

c++ - 值(value)的生命周期

c++ - 我是否需要做一些特别的事情来让我的 C++ 程序使用 gcc 进行编译?

linux - Hello World C++ 内核模块中的 undefined symbol