У меня есть приложение C ++, скомпилированное для Linux, работающих на процессоре ARM Cortexa9, который сбивается с исключением SIGFPPE / арифметиком. Первоначально я думал, что это из-за некоторых оптимизаций, введенных Флаг -O3 -O3 Flag GCC, но затем я построил его в режиме отладки, и он все еще сбивает.
Я отладил приложение с GDB, который ловит исключение, но, к сожалению, исключение запуска эксплуатации, кажется, также мусор в стеке, поэтому я не могу получить какую-либо подробную информацию о месте в моем коде, который вызывает это, чтобы произойти. Единственная деталь, которую я мог бы, наконец, получила операцию, вызывающую исключение (из следующего куска трассировки стека):
3 raise() 0x402720ac
2 __aeabi_uldivmod() 0x400bb0b8
1 __divsi3() 0x400b9880
__ Aeabi_uldivmod () выполняет данный раздел без знаменитых долгосрочных и напоминание, поэтому я попробовал грубый Принудительный подход и обыскал мой код для мест, которые могут использовать эту операцию, но без особого успеха, поскольку оказалось, что она оказалась пугающей задачей. Также я пытался проверить потенциальные подразделения на ноль, но опять же, база кода довольно большая и проверяя каждую операцию подразделения, это громоздкий и несколько тупой подход. Так что должно быть умнее способ выяснить, что происходит.
Есть ли какие-либо методы для отслеживания причин таких исключений, когда отладчик не может сделать много, чтобы помочь?
Обновление: После хрустания на шестигранные номера, сброс памяти и выполнения криминала стека (спасибо Crashworks) Через этот драгоценный камень в документации компилятора ARM (даже если я не использую компилятор ARM Ltd.):
integer Devision-by-Zero-Zero Ошибки могут быть в ловушке и идентифицированы Повторное реализация соответствующих функций помощника библиотеки C. То поведение по умолчанию, когда происходит разделение на ноль, заключается в том, что при сигнале функция используется или __rt_raise () или __aeabi_idiv0 () повторно реализуются, __aeaabi_idiv0 () называется. В противном случае функция разделения возвращает ноль. __aeabi_idiv0 () поднимает sigfpe с дополнительным аргументом, divbyzero.
Итак, я положил точку останова на __aeabi_idiv0 (_aeabi_lldiv0) et voila!, У меня была полная трасса стека, прежде чем быть полностью разбитым. Спасибо всем за их очень информативные ответы!
Отказ от ответственности: «Победающий» ответ был выбран исключительно и субъективно с учетом веса его предложений в моих усилиях отладки, потому что более одного было информативным и действительно полезным .