Уроборос: запись вызовов работающей программы Уроборос: что он записывает и когда это нужно
0%

Уроборос: что он записывает и когда это нужно

Уроборос: что он записывает и когда это нужно

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

Что он делает

Инструмент дописывает в ваш исходник строки, которые ничего не вычисляют, а только записывают случившееся. Программа после этого запускается как обычно, и каждый вызов обмазанной функции оставляет две записи: одну при входе, вторую при выходе.

Записи копятся в файле debug.info — по одному объекту JSON в строке. Набор таких записей дальше называется трассой.

Три слова, которые встречаются в каждой главе:

  • обмазать — дописать в исходник строки, которые ведут запись. Сам код при этом не переписывается: тело функции остаётся ровно таким, каким было.
  • трасса — файл debug.info с записями одного прогона.
  • доводы — то, с чем функцию позвали.

Как выглядит запись

Вот две настоящие строки из прогона, который разбирается в следующей главе:

{"p":"in","t":"2026-09-10T19:59:29.262","id":"36c9ba0c-e827-4e03-9020-3f9745d1a37c","ci":-1,"th":"7.129140652823040","fn":"discount_rate","a":"9999, False","k":""}
{"p":"out","id":"36c9ba0c-e827-4e03-9020-3f9745d1a37c","fn":"discount_rate","r":"0.0","d":2e-06}

Ключи короткие нарочно: записей бывает много, и лишние байты в каждой строке стоят места.

ключ на какой строке что означает
p на обеих in — в вызов вошли, out — из вызова вышли
t in время входа
id на обеих номер вызова; по нему пара строк и связывается
fn на обеих имя функции
a in позиционные доводы
k in именованные доводы
r out что вернули
x out что бросили. Стоит вместо r, а не вместе с ним
d out сколько вызов занял, в секундах
ci in номер ядра процессора; -1 — узнать не удалось
th in какой поток вызывал

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

Записей две, а не одна. Записать только результат было бы вдвое дешевле, но тогда вызов, который завис или упал так, что не вернулся, не оставил бы следа вообще. А так он оставляет строку in без парной строки out — и это самый дешёвый ответ на вопрос «где оно висит».

Доводы снимаются до тела функции. Функция, которая портит то, что ей передали, всё равно запишет то, с чем её позвали, а не то, во что она это превратила.

Имя функции стоит на обеих строках. Если трасса оборвалась на середине и строка in потерялась, строка out всё равно говорит, что именно вернулось.

Три задачи, на которых это окупается

Разобраться в чужом коде. Прочитать сорок тысяч строк дорого, прогнать — дёшево. Через десять минут известно, какие функции живые, с чем их зовут и в каком порядке. Регулярно выясняется, что живых путей три, а остальное не исполнялось ни разу.

Найти причину падения, когда стека не хватает. Стек говорит, откуда позвали. Трасса говорит, с чем позвали, — и обычно ответ там. В разборе из следующей главы стек показывает TypeError в сравнении, а трасса показывает довод 'free' вместо числа: строку, которой в стеке нет.

Дать ИИ-агенту факты вместо догадок. Модель, читающая исходник, рассуждает о том, что может случиться. Трасса говорит, что случилось. Про это — глава про работу с агентом.

Чем это не является

Не профилировщик. Профилировщик меряет цену кода. Здесь записи сами стоят работы, и прогон с ними идёт медленнее. Поле d — честная длительность вызова в обмазанном прогоне, и читать её как цену того же кода без обмазки нельзя.

Не отладчик с точками останова. Программа не останавливается и ничего не ждёт от человека. Прогон идёт как обычно, записи копятся сами.

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

Не доказательство правильности. Трасса записывает, как код себя вёл, а не как он должен себя вести. Это главное ограничение, и ему посвящена последняя глава.

Две стороны инструмента

Одна и та же начинка выставлена наружу двумя способами.

Командная строка — семнадцать команд. Для начала нужны четыре: обмазать файл, обмазать выбранные функции, прочитать трассу, свести её в сводку.

Сервер MCP — те же семнадцать операций, отданные ИИ-агенту. Это тот же способ подключения внешних инструментов, которым к агенту подключаются остальные серверы.

Курс идёт по командной строке: то же самое видно глазами, и повторить можно сразу. Работа через агента разобрана в четвёртой главе.

Что дальше

  1. Первый прогон — поставить, обмазать свой файл, запустить, прочитать записи.
  2. Отказы — когда инструмент не делает того, о чём его попросили, и почему это правильно.
  3. Что записывать и как найти нужное — весь файл или выбранные функции, и как отобрать вызовы из тысячи записей.
  4. Работа с ИИ-агентом — сервер MCP, песочница из чернового и чистового каталогов, формулировка задания.
  5. Восемь языков — одна схема записи и разные способы обмазки.
  6. Границы — чего инструмент не делает. Эту главу сокращать нельзя.

Короткое описание без курса — на странице Уробороса в разделе инструментов.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов
Дальше