gpt4 book ai didi

rhel - 将输入流重定向到字符串时的c++程序核心转储

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:49:06 25 4
gpt4 key购买 nike

我最近发现我的 C++ 程序在尝试从输入流重定向到字符串时在 Red Hat Linux 上发生核心转储。该程序提供了一个 PID,并尝试从/proc 中获取进程名称。代码如下:

std::string processName;
std::stringstream filename;

filename << "/proc/" << pid << "/status";
std::ifstream f(filename.str().c_str());

if (f.good()) {
std::string label;
f >> label; // This causes the core dump

if (label == "Name:") {
f >> processName;
}
}
f.close();

我进行了一些搜索并发现了以下 c++ 错误,它看起来与我的问题非常相似(请注意最后一条评论,它专门针对我正在执行的操作)。 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53984

我已经能够使用一个在紧密循环中执行相同操作的小型测试程序来重现该问题,但仍然不太了解实际问题背后的原因。

有没有人知道使用上面显示的方法(从/proc 中)尝试读取进程名称的任何问题?我正在考虑重写我的代码以使用系统调用而不是从文件系统读取,但希望在进行更改之前获得一些建议。

最佳答案

这是可以重现您的问题的代码:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>

int main(int argc, char **argv)
{
pid_t pid = fork();
if (!pid) {
// Child process immediately dies and becomes a zombie
exit(0);
}

std::string processName;
std::stringstream filename;

// Open status of child process dying
filename << "/proc/" << pid << "/status";
std::ifstream f(filename.str().c_str());

// Wait for child process attaining death
wait(NULL);

// Read status of child process already gone
if (f.good()) {
std::string label;
// This causes the core dump
// read() returns ESRCH (No such process)
f >> label;

if (label == "Name:") {
f >> processName;
}
std::cout << processName << std::endl;
}
f.close();

return 0;
}

strace -f ./a.out 显示:

clone(Process 624 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f20758daa10) = 624
[pid 623] brk(0) = 0x8b8000
[pid 623] brk(0x8d9000) = 0x8d9000
[pid 623] open("/proc/624/status", O_RDONLY <unfinished ...>
[pid 624] exit_group(0) = ?
[pid 623] <... open resumed> ) = 3
[pid 623] wait4(-1, <unfinished ...>
[pid 624] +++ exited with 0 +++
<... wait4 resumed> NULL, 0, NULL) = 624
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=624, si_status=0, si_utime=0, si_stime=0} ---
read(3, 0x8b84b0, 8191) = -1 ESRCH (No such process)
write(2, "terminate called after throwing "..., 48terminate called after throwing an instance of ') = 48
write(2, "std::ios_base::failure", 22std::ios_base::failure) = 22
write(2, "'\n", 2'
) = 2
write(2, " what(): ", 11 what(): ) = 11
write(2, "basic_filebuf::underflow error r"..., 47basic_filebuf::underflow error reading the file) = 47
write(2, "\n", 1
) = 1
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
gettid() = 623
tgkill(623, 623, SIGABRT) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=623, si_uid=1000} ---
+++ killed by SIGABRT (core dumped) +++
Aborted (core dumped)

根本原因是内核在 read() 上返回了 ESRCH(没有这样的进程),这是 libstdc++ 无法预料的。我不确定这里应该归咎于内核还是用户态库。

关于rhel - 将输入流重定向到字符串时的c++程序核心转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32452535/

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