2015-12-07 1 views
1

В моем python debugger У меня есть способ переназначить строку на имя файла, чтобы при переходе через функцию exec'd внутри отладчика вы можете перечислить строки, или просматривать их внутри редактора, такого как Emacs, через realgud.Получение строки аргумента exec p python или доступа к стеку оценки

Так что я хочу, чтобы иметь возможность извлекать строку в инструкции exec, когда CPython остановлен в оценке этого.

У меня уже есть механизм, который может оглянуться назад в кадре вызова, чтобы посмотреть, есть ли caller was an EXEC_STMT, и я могу посмотреть одну инструкцию, чтобы узнать, была ли предыдущая инструкция DUP_TOP. Поэтому я был бы свободным домой, если бы мог просто вычислить способ чтения записи стека во время вызова, и это дает оценку строки. Вероятно, есть способ попасть в C, чтобы получить это, но мои знания о внутренних функциях CPython отсутствуют и предпочли бы этого не делать. Если есть пакет, возможно, я мог бы включить это опционально.

CPython уже предоставляет доступ к аргументам функции и локальным переменным, но, разумеется, поскольку это встроенная функция, это не записывается как параметр функции.

Если есть другие мысли о том, как сделать то же самое, это тоже будет хорошо. Я считаю, что менее хорошим решением было бы как-то попытаться перегрузить или заменить exec, поскольку отладчики могут быть привезены в конце игры.

Я понимаю, что CPython2 и CPython3 могут быть немного разными, но начать это было бы.

ответ

0

Я думаю, что я нашел способ.

Внутри отладчика я поднимаю стек вызовов на один уровень, чтобы перейти к оператору exec. Затем я могу использовать uncompyle6, чтобы получить абстрактное синтаксическое дерево исходного кода. (Для облегчения этого может потребоваться изменение в uncompyle6.)

Дерево в точке вызова будет иметь что-то вроде exec_stmt -> expr .... Это выражение будет иметь текст выражения, которое не обязательно является значением выражения. Выражение может быть постоянным строковым значением, но оно может быть чем-то сложным, как "foo" + var1.

Итак, отладчик может оценить эту строку в контексте отладчика, который знает, как оценивать выражения в стеке вызовов.

У этого еще есть проблема переоценки выражения, которое может иметь побочные эффекты. Но это плохая практика программирования, не так ли? ;-)

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

Совершенно иной подход состоял бы в том, чтобы остановить ранний переход к суб-интерпретатору, например byterun (или некоторому модифицированному модулю Python C), который имел бы доступ к стеку.

0

С открытым исходным кодом Thonny IDE имеет [sub] выражение оценка степпинг. См. Раздел author's answer на вопрос SO . Прослеживание оценки экспрессии Python шаг за шагом.

+0

Я вижу, вы не отказались от этой проблемы. Благодаря! Я посмотрел на Тонни и понравился. Однако преодоление изменений, которые, как я подозреваю, будет сложнее, чем использование одного из других подходов. Обратите внимание, что Thonny использует 3.4. или больше, пока мои отладчики поддерживают 2.6; 'exec' как зарезервированное слово появляется только в Python 2.x. [продолжение ...] – rocky

+0

Но это в стороне, как это будет работать? Ну, мне бы пришлось отказаться от кода, а затем с помощью Thonny он использовал бы исходный текст для создания Python AST, который он мог бы интерпретировать. Опять же, опираясь на то, что источник Python и AST изменят бит между версиями Python, мне все равно придется вычитать значения переменных в этом фрейме. Итак, проще, я просто отменил бы выражение, которое попадает в 'eval' или' exec', а затем передает это в отдельный интерпретатор, который имеет доступ для чтения к записи стека. – rocky

Смежные вопросы