Итак, я отлаживаю программу, которая таинственно вылетает через SIGSEGV. Программа однопоточная.Интерпретация причины segfault с помощью GDB nexti
Я отлаживал много segfaults раньше - большинство из них приходят вниз, чтобы стека или куча коррупции. Обычно легко отлаживать проблемы с кучей коррупции с помощью valgrind. Повреждение стека более сложное, но обычно вы можете сказать, что повреждение стека является проблемой, когда GDB показывает, что ваш стек искажен.
Но здесь я столкнулся с очень странной проблемой, которую я никогда раньше не видел. Используя GDB, чтобы перейти к инструкции по инструкции, я вижу, что segfault происходит сразу после инструкции callq
. Кроме этого callq
адреса динамически не загружаются из регистра или из памяти - это просто статического адрес функции:
(gdb) ni
0x00007ffff659c423 223 setPolicyDocumentLoader(docLoader);
1: x/i $pc
=> 0x7ffff659c423 <WebCore::FrameLoader::init()+351>: mov %rdx,%rsi
(gdb)
0x00007ffff659c426 223 setPolicyDocumentLoader(docLoader);
1: x/i $pc
=> 0x7ffff659c426 <WebCore::FrameLoader::init()+354>: mov %rax,%rdi
(gdb)
0x00007ffff659c429 223 setPolicyDocumentLoader(docLoader);
1: x/i $pc
=> 0x7ffff659c429 <WebCore::FrameLoader::init()+357>:
callq 0x7ffff53a2d50 <_ZN7WebC[email protected]plt>
(gdb) ni
Program received signal SIGSEGV, Segmentation fault.
0x0000000000683670 in ??()
1: x/i $pc
=> 0x683670: add %al,(%rax)
(gdb)
Таким образом, как только он выполняет callq
по адресу 0x7ffff53a2d50
, он вдруг ошибка сегментации.
Я понимаю, что, как правило, Stackoverflow не может быть слишком полезен для большинства проблем или проблем, подобных этому, потому что причины, как правило, чрезвычайно специфичны для некоторых конкретных обстоятельств и обычно просто сводятся к повреждению памяти через программиста ошибка.
Но я все же думал, что стоит задать этот вопрос, потому что это принципиально даже не имеет для меня никакого смысла. Как это возможно возможно для ОС для доставки SIGSEGV, когда программа выполняет команду callq
для законного статически определяется адрес функции?
'ni' шагает по' call'. Ошибка в другом месте, глубже. Вместо этого вы должны использовать 'si' для входа в вызываемую функцию. – Jester