Вызов исключения C++ с помощью LibUnwind на загруженном PowerPC устанавливает случайные ловушки исключений с плавающей запятой
В настоящее время я отлаживаю некоторые ошибки в PyTorch, библиотеке Python с расширением C++, поэтому есть код C++, вызываемый кодом Python.
Ошибка происходит из-за того, что некоторые ловушки исключений с плавающей запятой устанавливаются до, казалось бы, невинного
std::exp
вызов, вызывающий дамп ядра. Как ни странно, уменьшив это до минимума, просто установив FPE через
feenableexcept
а затем позвонив
std::exp
с такими же значениями не производит этот аварийный / основной дамп. Так что я застрял в отладке исходного приложения.
Выполнив некоторую отладку printf (конечно, код не ломается [т.е. ловушки не устанавливаются] при компиляции в режиме отладки) я сузил его до
throw c10::Error(...)
заявление. Этот класс является производным от
std::exception
так что здесь ничего необычного. Чтобы преобразовать это исключение C++ в исключение Python,
catch(...){ /*set a bool*/; throw;}catch(c10::Error&){...}
введен. Пока ничего не выглядит странным, и, конечно же, это не воспроизводится при минимальной настройке, выполняющей то же самое.
Использование gdb с
catch throw
и
catch catch
Я добрался до места, где возникает и перехватывается это исключение, и сделал несколько пошаговых действий (step
) с последующим
p fegetexcept()
и действительно:
90 in ../../../../libstdc++-v3/libsupc++/eh_throw.cc
(gdb) p fegetexcept()
$20 = 0
(gdb) s
Catchpoint 4 (exception caught), __cxxabiv1::__cxa_begin_catch (exc_obj_in=0x11c6da60) at ../../../../libstdc++-v3/libsupc++/eh_catch.cc:42
42 ../../../../libstdc++-v3/libsupc++/eh_catch.cc: Datei oder Verzeichnis nicht gefunden.
(gdb) p fegetexcept()
$21 = 536870912
Так что прямо внутри броска FPE все еще не установлен, а прямо внутри улова он находится. Линия в
eh_throw
является
_Unwind_RaiseException (&header->exc.unwindHeader);
в которую я не могу войти.
Также значение
fegetexcept()
сильно отличается в зависимости от вызова программы. Кроме того, проблема исчезнет, если я НЕ буду строить с помощью GLOG, который я впоследствии проследил с помощью libunwind.
Однако я не могу продвинуться дальше того момента, когда libunwind вызывает
setcontext
из которых получаю только сборку. На линии
lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
значение
fegetexcept()
изменения.
Так что это похоже на проблему с libunwind. Однако проблема не возникает, когда я использую clang 9.0.1 вместо GCC 8.3.0. Так что я здесь в растерянности.
Есть ли у кого-нибудь идеи, в чем может быть проблема, что еще я могу сделать или есть ли известная ошибка? В этом случае используются glibc 2.17 и libunwind 1.4.0.