Стекающие сопрограммы + gdb = & quot; предыдущий кадр внутри этого кадра (поврежденный стек)? & Quot;

Я пишу некоторый код для отладки стека сопрограмм, которые используют Boost.Context’s make_fcontext а также jump_fcontextи столкнулись с небольшой проблемой.

Обычно это невозможно backtrace мимо записи стековой сопрограммы, поскольку она выполняется в своем собственном стеке. Это означает, что я не могу определить из отладчика, откуда была введена сопрограмма. Это, однако, не та проблема, о которой я спрашиваю. Я уже решил эту проблему, добавив некоторую встроенную сборку и байт-код DWARF в функцию, которую я передаю make_fcontext:

__asm__ volatile (
"mov %[caller_fcontext_t] %[somewhere]\n\t"".cfi_escape /* DWARF bytecode to load caller_fcontext_t from ""             * somewhere and use it to load all the registers saved ""             * there by jump_fcontest */""call %[another_function]": /* stuff */ : /* stuff */ : /* stuff */)

Это действительно работает, и теперь я могу backtrace до точки в вызывающей стороне, где он начинает или возобновляет внутреннюю сопрограмму — но только иногда.

Оказывается, у GDB есть «проверка работоспособности»: если указатель стека перемещается в «неправильном» направлении между кадрами вызова, GDB предполагает, что стек поврежден и останавливает трассировку с сообщением »Backtrace stopped: previous frame inner to this frame (corrupt stack?)».

Это срабатывает, когда мои стеки распределены определенным образом, но не другими способами. У меня даже есть тест со статически распределенными стеками, который вызывает этот сбой при использовании в прямом порядке, но не при использовании в обратном порядке.

Я даже нашел часть исходного кода GDB, которая выполняет эту проверку здесь: https://github.com/bminor/binutils-gdb/blob/master/gdb/frame.c#L737-L816

Теперь вот мой актуальный вопрос: Как я могу это исправить?

Могу ли я написать какое-нибудь заклинание сборки, которое говорит GDB «поверь мне, я знаю, что делаю»?

2

Решение

Теперь вот мой актуальный вопрос: как я могу это исправить?

Могу ли я написать какое-нибудь заклинание сборки, которое говорит GDB «доверие
я знаю, что я делаю «?

Там в настоящее время нет способа сделать это. Это было бы хорошей идеей, но, вероятно, потребовало бы некоторого расширения DWARF. Таким образом, это может быть сложно реализовать.

Вы можете увидеть доказательства этого в источниках GDB: у GCC была похожая проблема, связанная с -fsplit-stack, и это было обойдено путем простого кодирования имени вызывающей функции в gdb:

  if (!morestack_name || strcmp (morestack_name, "__morestack") != 0)

Быстрый обходной путь для личного использования — просто закомментировать раннее возвращение сюда.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]