Stackful сопрограммы + gdb = "предыдущий кадр внутри этого кадра (поврежденный стек)?" - PullRequest
0 голосов
/ 26 сентября 2018

Я пишу некоторый код для отладки стековых сопрограмм, использующих Boost.Context 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: "Доверяй мне, я знаю, что я"я делаю "?

1 Ответ

0 голосов
/ 26 сентября 2018

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

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

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

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

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

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

...