QNX RTP Logo QNX Realtime Platform: Русский Портал QNX
Thursday, 20 Nov 2008 19:44
Меню

Проект OpenNET - все о Unix
Главная

 · Начало · Статистика · Поиск ·

  QNX.ORG.RU —› Языки и алгоритмы —› адрес функции

Посл.ответ Сообщение


Дата: 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.

©   2000-2003 Команда проекта QNX.ORG.RU // QNX.ORG.RU Team
Авторы проекта: Дмитрий Алексеев [dmi] и Дмитрий Васильев. Техническое сопровождение проекта: Игорь Сорокин [isorokin]. Информационное сопровождение: Дмитрий Алексеев [dmi]
QNX - зарегистрированная торговая марка QNX Software Systems, Ltd., Canada. Остальные упоминаемые на сайте торговые марки и логотипы являются исключительно собственностью их уважаемых владельцев. Ничьи права не затронуты. Материалы сайта не могут быть скопированы и где-либо использованы в той или иной форме без письменного разрешения разработчиков сайта.
Powered by Mambo Open Source