Задача Трассировки (построение графа функций)

 

Допустим имеем некий код (функции, классы и т.д.)

Есть задача - создать стек вызовов. Но не просто линейный, а в виде дерева.

Где узлом дерева будет вход в функцию, а ветками - вызовы следующих функций из текущей функции узла.

Например есть такая структура функций:

void Main() { A(); B(); }

void A() { /*вошли в А*/ a(); b(); c(); }
void B() { /*Вошли в B*/ a(); b(); c(); }

void a() { /*Вошли в а */ }
void b() { /*Вошли в b */ }
void c() { /*Вошли в c */ }

в результате это будет выглядеть примерно так


Обязательное условие:

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

Это условие необходимо для того, что не делать большую модификацию кода, а ограничится лишь вставкой одной и той же функции трейсинга (например назовем её _TRACE_IN_) - во все имеющиеся функции кода. Чтоб получить все проходы исходного кода и построить дерево вызовов.


Буду рад услышать любые идеи или варианты.
Как ни кручу - натыкаюсь на замкнутый круг, что надо вызывать не одну, а две функции для формирования такого дерева. А надо по-любому только одна. :)

 

Т.е. вы хотите сделать прогу для для выявления алгоритма иходника.

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

зачем ввиде дерева?

или мож чего я непонял. 

 
FLET:

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


про "ломать" я как то не думал. Но поняли правильно. Это для построения логической структуры кода.

То есть моя задача - включив работающий код (свой, или чужой или например из стандартной поставки МТ5) - в отдельном окне получаю весь стек вызываемых функций в виде дерева. В течении одного цикла (тика).То есть в корне - функция start() и дальше пошло поехало выше и шире....

Работу дерева я давно реализовал. В нем есть анализ времени проведенных в функциях (для анализа качества кода), число обращений к функциям, отслеживание значения переменных и т.д. Также реализовал три варианта отображения данного дерева - в виде того что на скрине, в виде круговой и линейной диаграммы. Но это все по мелочи.

Самая главная задача с которой столкнулся - это заполнение самой структуры дерева.

Мне нужна идея, как с помощью одной функции (или возможно несколькими присвоениями, но главное стоят подряд), дописываемой в функции исходного кода, строить такую структуру как на скрине.

 
sergeev:

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

Доказательство невозможности за идею проканает?
 
MetaDriver:
Доказательство невозможности за идею проканает?

проканает.... но только через 3 страницы обсуждения вариантов :))

сложные реализации, дополнительные переменные, использование глобальных, или что угодно. принимаю все :)

 
sergeev:

проканает.... но только через 3 страницы обсуждения вариантов :))
Лан. Жду четвёртую страницу ;-)
 
sergeev:

проканает.... но только через 3 страницы обсуждения вариантов :))


значит задача свелась к тому, чтобы заполнить топик 3-мя страницами текста? :), ОК, приступим ;)

1. работа со строками: вход в ф-цию, прибавляем имя ф-ции, выход из ф-ции удаляем, в лог/трассировку постоянно выводим полную строку в виде линейного списка:

start(enter)-func1(enter)-func2(enter)

start(enter)-func1(enter)-func2(exit)

...

такой подход имхо - безобразие

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

примерно так, но опять же имхо - а стоит овчинка выделки? уж больно большой объем работы предстоит

 

IgorM:

значит задача свелась к тому, чтобы заполнить топик 3-мя страницами текста? :), ОК, приступим ;)

Эгегей. не так горячо!!! у нас тут каждая страница на счету :)

1. работа со строками: вход в ф-цию, прибавляем имя ф-ции, выход из ф-ции удаляем,

это не подходит по условию. Нужен только один вызов - при входе. При выходе это нереально. В функции может быть несколько точек выходов. А вход только один. Поэтому "добавка" должна быть только при входе.
 
sergeev:

Эгегей. не так горячо!!! у нас тут каждая страница на счету :)

поздно, Ваше желание было Вами же озвучено ;)

по сабжу - имхо всё равно нужно работать с матрицами/многомерными массивами - тогда появится математическая модель Вашей трассировки, а как ВЫ будете потому обрабатывать события вход/выход из ф-ции это другой вопрос

 
IgorM:

поздно, Ваше желание было Вами же озвучено ;)

похоронить ветку всегда можно. сама утонет когда прийдет время. И это не желание.

по сабжу - имхо всё равно нужно работать с матрицами/многомерными массивами - тогда появится математическая модель Вашей трассировки, а как ВЫ будете потому обрабатывать события вход/выход из ф-ции это другой вопрос

немного не понимаю. Можете на пальцах объяснить как сюда матрицы подходят?

Идея в том, чтоб функции попадали в граф (дерево по-народному). Но в четко хронологическом порядке вызовов и идентификации что где вызывалось. Ведь одна и та же функция может вызываться как из start, так и из init. Вот это и надо фиксировать.

(делаю на/для MQL5, поэтому использую классы для графа)

 
sergeev:

граф (дерево по-народному).

Дерево - частный случай графа.