使用 fstream 读取 MSR

3

我无法使用fstream读取MSRs(模型特定寄存器)。为什么会这样?

使用fopen/fseek/fread进行读取却能正常工作。

有人知道原因吗?下面是MSRs的权限。

# ll /dev/cpu/0/msr
crw------- 1 root root 202, 0 Jan 26 22:29 /dev/cpu/0/msr

msr 伪文件是一个特殊的文件,不支持文件上的许多常规操作(例如,许多 fstat 值)。此外,无论权限如何,读取或写入可能会在文件中的任何位置失败,这取决于特定 MSR 的语义。显然,更高级别的 fstream 功能依赖于一些不可用的功能,或者尝试缓冲一些不可读的文件。你得到的实际错误消息是什么? - BeeOnRope
你的意思是在使用带有libstdc++的Linux吗?你尝试过使用clang的libc++吗? 我认为你应该标记你的问题与相关的平台问题,以便那些了解这些事情的人能够回答你的问题。 - TheCppZoo
我见到的错误是fstream的坏位被设置了,除此之外我没有得到任何更多的信息。而且我使用CLANG编译器。 - chimp45
1个回答

3

C++ 缓冲区 I/O 读取和写入。例如,在简单的GCC应用程序中,该缓冲区设置为8192字节。当然,您有可能改变该大小。

正如setbuf上的Wiki页面所说:

  • GCC 4.6 libstdc++

    使用用户提供的缓冲区,从文件读取每次读取n-1个字节。

  • Clang++3.0 libc++

    使用用户提供的缓冲区,从文件读取适合于缓冲区的最大4096的倍数。

这就是为什么来自GCC编译的程序对MSR文件进行简单的openseekread翻译的原因:

openat(AT_FDCWD, "/dev/cpu/0/msr", O_RDONLY) = 3
lseek(3, 408, SEEK_SET)                 = 408
read(3, 0x113a0a0, 8191)                = -1 EINVAL (Invalid argument)

请注意值8191。 MSR(4)后面的答案由EINVAL提供:

通过打开文件并将MSR号作为偏移量定位到文件中,然后以8字节的块读取或写入来完成寄存器访问。

最简单的解决方法是更改缓冲区的大小。在GCC中,您可以这样做:

char buf[8 + 1];
std::ifstream file;
file.rdbuf()->pubsetbuf(buf, sizeof(buf));
file.open("/dev/cpu/0/msr", std::ifstream::binary);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接