metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2014-11-25 11:33 pm

Инструментация кода логгерами.

Бредовые идеи про отладку программ на ходу.

1. макрос/плагин компилятора, вызываемый при компиляции вызова любой функции или метода,а так же при компиляции тела этой функции.
2. макрос строит дерево вызовов функций и делает из него статическую структуру в памяти программы, с флагом isDebug на каждую функцию. Структура доступа через какой-нибудь дико профайлинговый рантайм API
3. в каждую функцию макрос добавляет проверку ее флага и если он включен - вывод уникального идентификатора стек-трейса вызова функции, параметров при вызове и вывод результата при выходе, в логи.
4. чтобы стек-трейс не генерить в рантайме - в каждый вызов при компиляции добавляется статическая информация, "откуда меня вызвали", в виде ссылки на граф вариантов вызова этой функции.

Ежели функции ленивые - то вместо стек-трейса будет что-нибудь вроде "где thunk создали, а где зафорсили", но это надо подумать, как такое представить наглядным образом.

[identity profile] swizard.livejournal.com 2014-11-25 09:46 pm (UTC)(link)
> "откуда меня вызвали", в виде ссылки на граф вариантов вызова этой функции

а как быть с рекурсивными и взаимно-рекурсивными функциями?

ЗЫ: есть подозрение, что тебе нужен common lisp

[identity profile] metaclass.livejournal.com 2014-11-25 10:03 pm (UTC)(link)
По идее взаимно-рекурсивные будут петлями в таком графе, хотя уникально идентифицировать путь вызова в таком случае, без количества проходов по петле не получится.
Еще более плохой вариант - это если функции вызывать через reflection :)

[identity profile] kiryl.livejournal.com 2014-11-25 10:16 pm (UTC)(link)
ещё веселее если по дороге где-нить jit или ещё какая runtime-кодогенерация ;)

[identity profile] swizard.livejournal.com 2014-11-26 03:52 am (UTC)(link)
Да не, какая кодогенерация, там уже банальный вызов функции по указателю (например, виртуальный метод) окажется серьёзной проблемой.

[identity profile] swizard.livejournal.com 2014-11-26 03:58 am (UTC)(link)
Ну если количество переходов не нужно, то уже проще. В кл, например, я примерно уже представляю, как это всё сделать :)

Но надо решать, что делать с вызовами функций по указателю (и ваще динамической диспетчеризацией), замыканиями (и ваще анонимными функциями), вызовами функций из eval, и тд.