 |
Меню |
|
|
|
|
 |
Главная |
|
| Посл.ответ |
Сообщение |
|
Дата: 19 Дек, 18:28
Доброго времени суток.
Действие:
функция А() вызвала функцию B()...
Задача:
из функции B() нужно узнать адрес вызвавшей ее функции, в данном случае функции A().
Подскажите как это делается или где читать...
Заранее спасибо.
|
|
Дата: 19 Дек, 19:59
никак. стандартных средств нет.
вопрос: а зачем? может есть проще решения...
|
|
Дата: 20 Дек, 07:04
Да может и есть, только пока в голове единственный вариант...
А суть в том, что через функцию B() идет управление неким ресурсом. Так вот в этой функции, в режиме отладки, хотелелось бы встроить трассировку/лог. Где будет записываться с какого адреса был вызов и с какими параметрами ресурс был изменен.
Очень не хочется каждый раз передавать адрес функции в качестве аргумента.
|
|
Дата: 20 Дек, 09:06
Очень трудно мне это ..представляется. Если трасировка не в дебагере - то что даст адрес метода? Я даже упускаю возможность всяких там DLL - где адрес насколько я понимаю у вас будет варьироватся от ДЛЛ к ДЛЛ .. и от приложения к приложению.. Даже если и адресса будут гарантировано постоянные - много гемора, имхо, по определению с какому именно адресу пренадлежит тот или иной вызов...
Если трасировка в дебагере - то поидее у него должна быть тулза.. которая показывает вызовы (обычно  .. - адрес вызывающего метода помещается в стеке.. вопрос остался.. найти тулзу или развернуть стек самому). Но это работает как правило в месте "падения" (или по брекпоинту). |
|
Дата: 20 Дек, 16:57
To lastcross:
Немного я вас запутал, не уточнив некоторые моменты...
- рижим отладки - емеется ввиду не отладка в дебагере,
а режим работы самой программы в режиме отладки,
- OS QNX 4.25 - так что ни каких .dll, + компилятор саздает файл с картой адресов
- сам метод трассировки хочу использывать в классе который у меня используется в любом фотоновском приложении
- вся задумка ради того чтоб отследить "левые/лишние" обращения к ресурсам.
|
|
Дата: 21 Дек, 09:14 · Поправил: vshemm
При входе в функцию В первый дворд на стеке будет указывать в функцию А. По идее  Если вызов будет прямым, а не через "переходники".
Если вызовы должны происходить только из Ваших функций - делаете таблицу адресов (на этапе компиляции или в рантайме в случае перемещаемого кода) и сравниваете полученный адрес вызова с диапазонами из этой таблицы. |
|
Дата: 21 Дек, 13:06
Можно поступить следующим способом:
- создать структуру элемента массива истории, содержащего нужную Вам информацию о вызове (в простейшем варианте идентификатор функции)
- завести кольцевой массив истории;
- написать функцию трассировки - которая будет переписывать нужную Вам информацию в текущую позицию массива истории, и переходить к следующему, по достижении конца массива, переходить на первый элемент;
- написать функцию запроса n-го предыдущего вызова функции, которая относительно текущего указателя в кольцевом буфере будет возвращать запись, отстоящую на n
позиций назад;
в таком случае, если обе функции и A и B будут вызывать функцию трассировки, то функция B при помощи кольцевого буфера истории, может узнать, что её вызвала A.
Можно построить стек (программно), т.е. при входе в функцию вызывать, например, trace() (помещающую информацию в стек трассировки), а при выходе untrace()(удаляющую эту информацию). Стек трассировки строится аналогично таблице трассировки.
|
|
Дата: 21 Дек, 16:39
Спасибо.
Буду корпеть.  |
|
Дата: 21 Дек, 18:53
Не.. ну если конешна.. код функций A и B доступен для изменения.. - то пожалуста.. Пишим свой класс-менеджер для хранения точек входа как синглтон CTraceManager.. Дальше делаем класс.. собствено организующий запись(удаления) в менеджер данных и тд. Назовем его CTracer .. Объект класса CTracer создаем статически в начале каждого метод. В конструкторе - указываем имя и параметры метода в котором он был создан (вплоть до адресса..вощем все необходимые параметры.. которые тебе нужны при разборе.. Главное чтобы один изних был уникальным .. для индетификации метода внутри менеджера - в простом варианте имя функции). При создании объекта - менеджеру передается параметры - и он создает нужную запись о входе в метод.
При выходе из метода - вызывается деструктор (объект статический.. потому он гарантировано вызовится ).. который обеспечивает уведомление менеджеру об выходе из метода.. Далее.. по завершению (а можно хоть и вовремя работы) - анализировать кто вызвал метод.. сколько раз.. зачем.. и в какой последовательности - все зависит от того как вы построите мендежер трасировок.. и от конкретной задачи..
Впринципе тоже самое что и писал darkelf - но на классы переведенное. А воще - это распространненый подход к логам. Но если не внутрьпрограммно (без доступа в сорцы) - то я тут немогу ниче подсказать ))
|
|
Дата: 22 Дек, 16:18
Если весь код доступен для компиляции, то можно использовать ключь wcc -ep (prologue hook) и свой prologue. Так, например, работает (работал  ) deja-view. |
|
Дата: 23 Дек, 12:04 · Поправил: Hedrin_
да, код весь доступен, но проект достаточно большой
и искать в нем все обращения к ресурсу достаточно тяжело. вот по этому и созрела идея вставить трассировку в функцию handler() этого ресурса.
Но, по всему видимо, придется искать... ))
|
|
Дата: 23 Дек, 12:44
Опять же не понятно - в чем рудность? Вставит в код каждой функции первой строчкой
#ifndef _DEBUG
KTracer tracerObj(/*Имя функции и параметры функци,передающиеся менеджеру трасировки*/);
#endif // _DEBUG
..?? Как помне.. какой бы громадный проект бы небыл.. вставить одну строчку в каждую функцию.. нетак уж и времени займет. Я думаю чуть труднее(по затраченому времени) будет создать этот самый менеджер .. своими руками - но походу мона найти реализации и в инете |
|
Дата: 24 Дек, 08:03
Да нету ни каких трудностей. )
Но, согласитесь, зачем измываться над всем кодом и над своим временем когда можно было бы акуратненько поправить только одно место. И из этого места наблюдать за всей работой.)
Была идея, была попытка, но...будем работать ручками  )) |
|
Дата: 24 Дек, 09:21
Всегда хочится - если править .. то только ОДНО место. )).
С таким подходом - только смотреть опции компилера как писал e_boris ито ..если этот компилер жутко "умный" и выдаст все что вам хотелось узнать. Ну и действительно - если время поджимает.
А так, как по мне, иметь в кармане клас типа KTracer .. вполне не помешало бы )). Сегодня потратите.. надцать единиц времени - завтра.. десяток минут на подобную задачу.
|
You must login to post.
| | |