Получить указатель инструкции на ошибку сегментации или сбой (для проекта компилятора JIT x86)? - PullRequest
4 голосов
/ 18 августа 2011

Я реализую бэкэнд для JIT-компилятора JavaScript, который создает код x86.Иногда, в результате ошибок, я получаю ошибки сегментации.Может быть довольно сложно отследить, что их вызвало.Поэтому мне было интересно, есть ли какой-нибудь «простой» способ перехвата ошибок сегментации и других подобных сбоев и получения адреса инструкции, которая вызвала ошибку.Таким образом, я мог бы сопоставить адрес обратно скомпилированной сборкой x86 или даже обратно с исходным кодом.

Это должно работать в Linux, но в идеале в любой POSIX-совместимой системе.В худшем случае, если я не смогу поймать ошибку seg и получить IP-адрес в моем работающем JIT, я бы хотел иметь возможность перехватить его снаружи (журнал ядра?) И, возможно, просто получить от компилятора дамп большого файлас сопоставлением адресов с инструкциями, которые я мог бы сопоставить со скриптом Python или чем-то еще.

Любые идеи / предложения приветствуются.Не стесняйтесь делиться своими собственными советами по отладке, если вы когда-либо работали над собственным проектом компилятора.

Ответы [ 2 ]

3 голосов
/ 18 августа 2011

Если вы используете sigaction, вы можете определить обработчик сигнала, который принимает 3 аргумента:

void (*sa_sigaction)(int signum, siginfo_t *info, void *ucontext)

Третий аргумент, передаваемый обработчику сигналов, - это указатель на структуру данных ОС и архитектуры. В Linux это ucontext_t, который определен в заголовочном файле <sys/ucontext.h>. В этом случае uc_mcontext - это mcontext_t (машинный контекст), который для x86 содержит все регистры на момент сигнала в gregs. Таким образом, вы можете получить доступ к

ucontext->uc_mcontext.gregs[REG_EIP]  (32 bit mode)
ucontext->uc_mcontext.gregs[REG_RIP]  (64 bit mode)

, чтобы получить указатель инструкции ошибочной инструкции.

0 голосов
/ 18 августа 2011

Используйте sigaction с флагом SA_SIGINFO и обработчиком сигнала с прототипом void (*handler)(int signum, siginfo_t *info, void *data). Когда обработчик сигнала будет вызван, info->si_addr будет содержать значение указателя инструкции о том, где произошла ошибка.

Имейте в виду, что состояние процесса не определено после того, как он получает SISEGV, который не был сгенерирован с помощью метода lift () или kill (). Если можете, используйте

...