Сценарий - это файл, который считывается в неподписанный буфер символов, буфер помещается в поток istringstream, а строки в нем повторяются.SIGABRT, вызванный через istringstream.getline()
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
, буфер хорошо, и только первые несколько строк на самом деле повторяется таким образом, а остальные данные отбрасываются (и цикл прерывается). Фактически, этот пункт имеет никогда уволен ранее.
Я хочу подчеркнуть точку о том, о только первые несколько строк используется, и что при отладке и т.д. буфер, очевидно, все еще есть много данных, оставшихся в ней до отказа, так что ничего не бьет 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) {
И вдруг все изменилось - а не ловить и сообщения об ошибке, процесс умирает через SIGABRT внутри try
. Цепочка вызовов выглядит следующим образом:
#0 0x00007ffff6b2fa28 in __GI_raise ([email protected]=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 ([email protected]=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 (
[email protected]=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) }
.
Согласно этим несколько вопросов:
Похоже, на самом деле есть только две возможности здесь:
Я где-то ушел и повредил экземпляр istringstream.
В библиотеке есть ошибка.
С 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 был обновлен в системе.
я держал пари, что это изменение ABI НКУ 5 проблем – strangeqargo
может быть, некоторые линии длиннее, чем 1024? (тогда getline устанавливает failbit). Это может произойти в некоторых файлах/proc. Второй сбой внутри попытки может быть вызван ловлей через ссылку, а не константу ссылки. – Hcorg
@strangeqargo Я думаю, что вы правы, см. Мой ответ (система работала на 8 дней и не перезагружалась после обновления libc). – delicateLatticeworkFever