Linux 为什么是segfault而不是特权指令错误?
我试图在用户模式下执行特权指令Linux 为什么是segfault而不是特权指令错误?,linux,performance,assembly,x86,Linux,Performance,Assembly,X86,我试图在用户模式下执行特权指令rdmsr,我希望得到某种特权错误,但我得到了一个segfault。我已经检查了asm,并且正在将0x186加载到ecx,根据第1171页的 segfault的原因是什么,我如何修改下面的代码来修复它? 我想在破解内核模块之前解决这个问题,因为我不想让这个segfault炸毁我的内核 更新:我运行的是英特尔(R)至强(R)CPU X3470 #define _GNU_SOURCE #include <stdio.h> #include <stdl
rdmsr
,我希望得到某种特权错误,但我得到了一个segfault。我已经检查了asm
,并且正在将0x186
加载到ecx
,根据第1171页的
segfault的原因是什么,我如何修改下面的代码来修复它?
我想在破解内核模块之前解决这个问题,因为我不想让这个segfault炸毁我的内核
更新:我运行的是英特尔(R)至强(R)CPU X3470
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sched.h>
#include <assert.h>
uint64_t
read_msr(int ecx)
{
unsigned int a, d;
__asm __volatile("rdmsr" : "=a"(a), "=d"(d) : "c"(ecx));
return ((uint64_t)a) | (((uint64_t)d) << 32);
}
int main(int ac, char **av)
{
uint64_t start, end;
cpu_set_t cpuset;
unsigned int c = 0x186;
int i = 0;
CPU_ZERO(&cpuset);
CPU_SET(i, &cpuset);
assert(sched_setaffinity(0, sizeof(cpuset), &cpuset) == 0);
printf("%lu\n", read_msr(c));
return 0;
}
定义GNU源
#包括
#包括
#包括
#包括
#包括
uint64\u t
读取msr(内部ecx)
{
无符号整数a,d;
__挥发性物质(“rdmsr”):“=a”(a),“=d”(d):“c”(ecx));
return((uint64_t)a)|((uint64_t)d)我将尝试回答的问题:为什么上面的代码会导致SIGSEGV
而不是SIGILL
,尽管代码没有内存错误,但却是一条非法指令(从非特权用户速度调用的特权指令)
我希望得到一个带有si_code
ILL_PRVOPC
的SIGILL
,而不是segfault。你的问题已经问了3年了,今天,我发现了同样的行为。我也很失望:-(
故障的原因是什么
原因似乎是Linux内核代码决定发送SIGSEGV
看看函数的最后一行
在中,您得到了其他汇编指令的列表,这些指令作为SIGSEGV
传播到用户空间,尽管它们实际上是一般保护故障。我发现了您的问题,因为我使用cli
触发了该行为
我如何修改下面的代码来修复它
从Linux内核4.9开始,我不知道有什么可靠的方法来区分内存错误(我认为是SIGSEGV
)和来自用户空间的特权指令错误
识别这些情况的方法可能非常粗糙且不可移植。当特权指令导致SIGSEGV
时,siginfo\u t
SIU code
设置为一个值,该值未直接列在man 2 sigaction
的SIGSEGV
部分中。记录的值为SEGV MAPERR
,SEGV_ACCERR
,SEGV_PKUERR
,但是我在我的系统上得到了SI_内核(0x80)。根据手册页,SI_内核
是一个代码“可以为任何信号放入SI_代码中”。在图中,您可以看到SIGSEGV{SI_signo signo signo SIGSEGV,SI_code=SI_内核,SI_addr=0}
。负责的内核代码是
也可以为字符串grepdmesg
请永远不要使用这两种方法来区分生产系统上的GPF和内存错误
代码的具体解决方案:不要从用户空间运行rdmsr
。但是如果您正在寻找一种通用方法来找出程序为什么收到SIGSEGV
请参阅dmesg
输出,我想您会看到陷阱,这表明您正在尝试执行privil来自usermode的ege指令。@rakib,dmesg的输出:通用保护ip:4005d0 sp:7fff6dea4070错误:0
。我想这就是我需要知道的。我会接受这个答案,并单独问后续问题。真的需要在单独的问题中问这个吗?你得到了你想要的。我对此很好奇,因为我正在深入研究要了解更多的asmasm
,我想更全面地了解什么样的事情会导致伪segfaults
。