Какие числа sepfault rip/rsp и как их использовать
Когда мое приложение linux выходит из строя, оно создает строку в журналах, например:
segfault в 0000000 rip 00003f32a823 rsp 000123ade323 ошибка 4
Что это за адреса rip и rsp? как их использовать, чтобы определить проблему? соответствуют ли они чему-либо в выводах "objdump" или "readelf"? они полезны, если моя программа вычеркивает свои символы (в отдельный файл, который можно использовать с помощью gdb)
Ответы
Ответ 1
Ну, указатель rip сообщает вам инструкцию, вызвавшую сбой. Вам нужно найти его в файле карты.
В файле карты у вас будет список функций и их начальный адрес. Когда вы загружаете приложение, оно загружается на базовый адрес. Указатель копирования - базовый адрес дает адрес файла карты. Если вы затем просматриваете файл карты для функции, которая начинается с адреса, немного ниже, чем ваш рип-указатель, и в списке используется функция с более высоким адресом, вы обнаружили неисправную функцию.
Оттуда вам нужно попытаться определить, что пошло не так в коде. Это не очень весело, но это, по крайней мере, дает вам отправную точку.
Изменить: бит "segfault at" сообщает вам, я бы сказал, что вы разыменовали указатель NULL. Rsp - текущий указатель стека. Увы, возможно, не все это полезно. С дампом памяти вы "можете" более точно определить, где вы попали в функцию, но это может быть очень сложно решить, точно, где вы находитесь в оптимизированной сборке
Ответ 2
Я тоже получил ошибку. Когда я увидел:
probe.out[28503]: segfault at 0000000000000180 rip 00000000004450c0 rsp 00007fff4d508178 error 4
probe.out - это приложение, которое использует libavformat (ffmpeg). Я разобрал его.
objdump -d probe.out
В rip будет выполняться инструкция:
00000000004450c0 <ff_rtp_queued_packet_time>:
4450c0: 48 8b 97 80 01 00 00 mov 0x180(%rdi),%rdx
44d25d: e8 5e 7e ff ff callq 4450c0 <ff_rtp_queued_packet_time>
наконец, я обнаружил, что приложение разбилось на функцию ff_rtp_queued_packet_time
PS. иногда адрес точно не совпадает, но он почти там.