Предыстория: я выделяю контексты и стеки своих машин с помощью getcontext(3)
/ makecontext(3)
/ setcontext(3)
( ucontext.h
; SUSv2, POSIX.1-2001) семейство функций
Когда я использую gdb (версия 6.1.1) для проверки стека пока поток находится в одном из этих контекстов, которые я выделил, похоже, что gdb не знает, где конец (логическое дно) стека.Например, вот стек из x86 FreeBSD:
#0 0x2872d79f in poll () from /lib/libc.so.7
#1 0x28646e23 in poll () from /lib/libthr.so.3
#2 0x2869b267 in fdtask (task=0x28a3dc40, v=0x0) at fd.c:58
#3 0x2869c8dc in taskstart (y=681827392, x=0) at task.c:58
#4 0x00000000 in ?? ()
#5 0x28a3dc40 in ?? ()
#6 0x00000000 in ?? ()
#7 0x00000000 in ?? ()
…
#65 0x00000000 in ?? ()
…
(да, это построен на основе библиотеки libtask Расса Кокса.)
Выполнение этого контекста начинается с функции taskstart
, но похоже, что GDB не может понять, что ему следует прекратить попытки чтения стека, даже если в этом кадре он достигает адреса возврата NULL. .
У меня такой вопрос: могу ли я что-нибудь сделать (каким-то образом отформатировав стек или установив регистр, что угодно), чтобы помочь GDB понять, где находится вершина стека? Спасибо.
Редактировать: Заключение: похоже, что gdb 6.1.1 определяет конец стека, проверяя, что сохраненный указатель фрейма равен NULL; Я исправил проблему для своего варианта использования, изменив функцию x86 и amd64 makecontext(2)
для сброса ebp или rbp в ноль при инициализации нового контекста. (В данном случае меня не интересуют другие архитектуры.) Эта проблема исчезает с gdb 7.1; предположительно gdb 7.1 способен обнаруживать конец стека с помощью некоторых других средств, таких как отладочная информация.