C语言读取/proc/interrupts缺失IPI行的原因与修复方法
问题原因
/proc属于Linux虚拟文件系统,其下的文件内容并非预先存储在磁盘上,而是内核在读取时动态生成,和普通磁盘文件的读取逻辑存在差异:- 单次
read调用不一定会返回全部内容,内核通常限制单次read最多返回1页(多数架构默认是4KB)大小的内容,你测试中单次read仅返回了3626字节,刚好接近4KB上限,所以只拿到了前面的硬件中断部分,末尾的IPI内容需要再次调用read才能获取。 - 当前代码仅执行了一次
read就关闭了文件,自然丢失了后半部分的IPI相关行。
- 单次
- 原有代码还存在缓冲区溢出风险:当
read返回8192字节时,buffer[n] = 0会写入数组越界位置,可能触发未定义行为。
修复方案
修改代码逻辑,循环调用read直到返回值为0(代表内容读取完毕),同时预留缓冲区空间存放字符串结束符,参考修复后的代码:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> // 16KB大小足够覆盖绝大多数场景下的/proc/interrupts内容,CPU核心数极多可再调大 #define BUF_SIZE 16384 int main(int argc, char **argv) { int source, n; unsigned char *buffer = malloc(BUF_SIZE); int total_read = 0; if (!buffer) { perror("malloc failed"); return 1; } source = open("/proc/interrupts", O_RDONLY); if (source < 0) { perror("open failed"); free(buffer); return 1; } // 循环读取直到内容全部返回 while ((n = read(source, buffer + total_read, BUF_SIZE - total_read - 1)) > 0) { total_read += n; } close(source); buffer[total_read] = 0; // 补字符串结束符 printf("%d chars in /proc/interrupts:\n", total_read); printf("%s", buffer); free(buffer); return 0; }
内容的提问来源于stack exchange,提问作者IRatherStayPrivate
相关产品推荐
相关产品推荐

