указатель "this" поврежден в трассировке стека - PullRequest
11 голосов
/ 30 августа 2011

Я видел эту ветку.Мой случай немного отличается, и я пытаюсь выяснить, как указатель "this" искажается.

Я использую фреймворк Qt 4.6.2, используя их QTreeView с моей собственной моделью.Я получаю обратную трассировку (86 кадров в длину, с большим количеством рекурсии, поэтому я не вставил все это целиком, она в этом pastebin включает только их код.

Наконец-тоsegfaults на каком-то ассемблере в QBasicAtomicInt :: deref, но очевидно, что он замер, что подтверждается следующими тремя кадрами:

#15 0x01420fd3 in QFrame::event (this=0x942bba0, e=0xbf8eb624) at widgets/qframe.cpp:557
#16 0x014bb382 in QAbstractScrollArea::viewportEvent (this=0x4, e=0x93f9240) at widgets/qabstractscrollarea.cpp:1036
#17 0x0156fbd7 in QAbstractItemView::viewportEvent (this=0x942bba0, event=0xbf8eb624) at itemviews/qabstractitemview.cpp:1610

В кадре 17 this равно 0x942bb0. В кадре 16, this должно быть таким же, как в кадре 17, он вызывает реализацию своего метода тем же методом для своего предка. Однако this становится 0x4.

Достаточно интересно, что в кадре 15 (опять же, кадр 16 вызвал своего предкареализации той же функции), указатель 'this' восстанавливается до 0x942bba0.

Если вы посмотрите на вставку полной обратной трассировки, вы можете увидеть какое-то «оптимизированное значение». У меня было приложениескомпилирован с оптимизацией, теперь у меня gcc установлен на -g3 -O0, поэтому, когда это произойдет в следующий раз, у меня может быть что-то большее. Но, конечно, теперь я не могу заставить его рухнуть - это довольновозникла сложная ошибка (но, тем не менее, очень важно ее исправить), поэтому я не думаю, что это слишком подозрительно.

Учитывая оптимизацию, это this pointer=0x4 необычно или определенно неправильно?Странно то, что в этих фреймах viewportEvent нет реального кода - они просто переключают тип события, проваливают оператор switch и возвращают реализацию своего предка.

Valgrind не делаетПохоже, что это вызывает какие-то проблемы, хотя я еще не делал это в Valgrind.

Кто-нибудь видел такое раньше?Что может быть причиной этого?

1 Ответ

8 голосов
/ 30 августа 2011

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

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

То же самое может случиться с параметрами.Если оптимизатор решит передать параметр в регистр, отладчик все равно будет смотреть на стековый фрейм.Более конкретно, в месте, где параметр будет соответствовать правилам соглашения о вызовах.

Тот факт, что следующий кадр стека имеет значение, правильно восстановленное, указывает, что сгенерированные инструкции имеют дело спараметр правильно, но отладчик просто не знает, где его искать.

...