该方案是将文件读入无符号char缓冲区,将该缓冲区放入istringstream中,并对其进行迭代。
istringstream data((char*)buffer);
char line[1024]
while (data.good()) {
data.getline(line, 1024);
[...]
}
if (
data.rdstate() & (ios_base::badbit | ios_base::failbit)
) throw foobarException (
最初是被捕获的foobarException,它并没有说太多,因为这是一种不太可能的情况-文件是
/proc/stat
,缓冲区很好,并且实际上仅以此方式迭代了前几行,然后其余的的数据被丢弃(并且中断了循环)。实际上,该子句的从未被ijt_rstrong触发过。1我要强调的一点是,仅使用了前几行,以及在调试等方面。缓冲区在发生故障之前显然仍然有大量数据,因此没有任何问题可以影响到EOF。
我逐步通过调试器检查了缓冲区是否已从文件中正确填充,并且
getline()
的每次迭代都得到了应有的状态,直到失败的神秘点为止-尽管由于这是一个致命错误,所以没有多少错误届时将获得更多信息。然后,我更改了上面的代码以捕获并更详细地报告错误:istringstream data((char*)buffer);
data.exceptions(istringstream::failbit | istringstream::badbit);
char line[1024];
while (data.good()) {
try { data.getline(line, 1024); }
catch (istringstream::failure& ex) {
突然间事情发生了变化-该过程不是通过捕获和报告错误,而是通过
try
中的SIGABRT 来死。回溯看起来像这样:#0 0x00007ffff6b2fa28 in __GI_raise (sig=sig@entry=6)
at ../sysdeps/unix/sysv/linux/raise.c:55
#1 0x00007ffff6b3162a in __GI_abort () at abort.c:89
#2 0x00007ffff7464add in __gnu_cxx::__verbose_terminate_handler ()
at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#3 0x00007ffff7462936 in __cxxabiv1::__terminate (handler=<optimized out>)
at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:47
#4 0x00007ffff7462981 in std::terminate ()
at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:57
#5 0x00007ffff7462b99 in __cxxabiv1::__cxa_throw (obj=obj@entry=0x6801a0,
tinfo=0x7ffff7749740 <typeinfo for std::ios_base::failure>,
dest=0x7ffff7472890 <std::ios_base::failure::~failure()>)
at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:87
#6 0x00007ffff748b9a6 in std::__throw_ios_failure (
__s=__s@entry=0x7ffff7512427 "basic_ios::clear")
at ../../../../../libstdc++-v3/src/c++11/functexcept.cc:126
#7 0x00007ffff74c938a in std::basic_ios<char, std::char_traits<char> >::clear
(this=<optimized out>, __state=<optimized out>)
---Type <return> to continue, or q <return> to quit---
at /usr/src/debug/gcc-5.3.1-20160406/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/basic_ios.tcc:48
#8 0x00007ffff747a74f in std::basic_ios<char, std::char_traits<char> >::setstate (__state=<optimized out>, this=<optimized out>)
at /usr/src/debug/gcc-5.3.1-20160406/obj-x86_64-redhat-linux/x86_64-redhat-linux/libstdc++-v3/include/bits/basic_ios.h:158
#9 std::istream::getline (this=0x7fffffffcd80, __s=0x7fffffffcd7f "",
__n=1024, __delim=<optimized out>)
at ../../../../../libstdc++-v3/src/c++98/istream.cc:106
#10 0x000000000041225a in SSMlinuxMetrics::cpuModule::getLevels (this=0x67e040)
at cpuModule.cpp:179
cpuModule.cpp:179
是try { data.getline(line, 1024) }
。根据以下几个问题:
听起来这里确实只有两种可能性:
由于2似乎不太可能,并且我找不到#1的情况-例如,以
valgrind
运行,因此中止之前没有错误:==8886== Memcheck, a memory error detector
==8886== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8886== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==8886== Command: ./monitor_demo
==8886==
terminate called after throwing an instance of 'std::ios_base::failure'
what(): basic_ios::clear
==8886==
==8886== Process terminating with default action of signal 6 (SIGABRT)
==8886== at 0x5D89A28: raise (raise.c:55)
==8886== by 0x5D8B629: abort (abort.c:89)
而且(当然)“到目前为止,它一直工作良好”,我很沮丧。
除了斜视代码并尝试隔离路径,直到发现问题或让SSCCE演示错误为止,我是否不知道有什么可能提供快速解决方案?
1.这个项目是一个不完整的项目,几个月后我又回来了,在此期间,我知道glibc已在系统上升级。
最佳答案
我相信奇怪的猜想是因为libc升级引入的ABI兼容性是正确的。系统已经运行了8天,并且在此期间进行了更新。
重新启动后,并且没有更改代码的,它可以编译并运行而没有错误。我也在另一个系统上进行了测试,结果相同。
可能的道理是,如果您发现glibc已更新,请重新启动系统...