gpt4 book ai didi

linux - 内存访问错误 sys_rt_sigaction(信号处理程序)

转载 作者:IT王子 更新时间:2023-10-29 01:04:55 24 4
gpt4 key购买 nike

关注此Interfacing Linux Signals文章中,我一直在尝试在amd64中使用sys_rt_sigaction,但在发送信号时总是出现内存访问错误struct sigaction 在使用 C/C++ 函数 sigaction 时有效。

sys_rt_sigaction 调用有什么问题?

带有 ASM 代码的 C/C++:

#include<signal.h>
#include<stdio.h>
#include<time.h>

void handler(int){printf("handler\n");}
void restorer(){asm volatile("mov $15,%%rax\nsyscall":::"rax");}

struct sigaction act{handler};
timespec ts{10,0};

int main(){
act.sa_flags=0x04000000;
act.sa_restorer=&restorer;
//*
asm volatile("\
mov $13,%%rax\n\
mov %0,%%rdi\n\
mov %1,%%rsi\n\
mov %2,%%rdx\n\
mov $8,%%r10\n\
syscall\n\
mov %%rax,%%rdi\n\
mov $60,%%rax\n\
#syscall\n\
"::"i"(7),"p"(&act),"p"(0):"rax","rdi","rsi","rdx","r10");
/**/

/*
sigaction(7,&act,0);
/**/

nanosleep(&ts,0);
}

编译

g++ -o bin -std=c++11
g++ -o bin -std=c++11 -no-pie

发送信号

kill -7 `pidof bin`

最佳答案

在 x86-64 linux 中,必须提供 sa_restorer 而您还没有这样做。

relevant part of kernel source :

            /* x86-64 should always use SA_RESTORER. */
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode);
} else {
/* could use a vstub here */
err |= -EFAULT;
}

C library wrapper为你做这件事:

  kact.sa_flags = act->sa_flags | SA_RESTORER;

kact.sa_restorer = &restore_rt;

有了更新后的代码,你确实有了一个恢复器,但你有两个问题:它坏了,你传递错了。查看上面提到的 C 库源代码,您可以 find this comment :

/* The difference here is that the sigaction structure used in the
kernel is not the same as we use in the libc. Therefore we must
translate it here. */

此外,由于函数序言,您不能将 C++ 函数用作恢复器。此外,不支持从信号处理程序调用 printf(但在这里有效)。最后,正如 David Wohlferd 指出的那样,你的废话是错误的。总而言之,以下可能是重做的版本:

#include<stdio.h>
#include<unistd.h>
#include<time.h>

void handler(int){
const char msg[] = "handler\n";
write(0, msg, sizeof(msg));
}

extern "C" void restorer();
asm volatile("restorer:mov $15,%rax\nsyscall");

struct kernel_sigaction {
void (*k_sa_handler) (int);
unsigned long sa_flags;
void (*sa_restorer) (void);
unsigned long sa_mask;
};

struct kernel_sigaction act{handler};
timespec ts{10,0};

int main(){
act.sa_flags=0x04000000;
act.sa_restorer=&restorer;

asm volatile("\
mov $13,%%rax\n\
mov %0,%%rdi\n\
mov %1,%%rsi\n\
mov %2,%%rdx\n\
mov $8,%%r10\n\
syscall\n\
"::"i"(7),"p"(&act),"p"(0):"rax","rcx", "rdi","rsi","rdx","r8", "r9", "r10", "r11");

nanosleep(&ts,0);
}

它仍然很老套,显然你不应该真的这样做。

关于linux - 内存访问错误 sys_rt_sigaction(信号处理程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42356368/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com