Страницы

Поиск по вопросам

пятница, 29 марта 2019 г.

Как получить название функции, которая совершила вызов данной функции?

Пишу лабораторную работу, нужно логирование, и для того чтобы не запутываться, хотелось бы иметь в логах что-то вроде: Error: init_link - not enough memory Сейчас ничего, кроме передачи в логгер строки-названия функции, в голову не приходит. Есть ли более изящный метод? Update: Вот что я имею в виду: int foo(int bar) { int foobar = -1; check_something(foobar/bar); return foobar/bar; } Теперь в check_something должен вызваться логгер, в котором сказано о том, что check_something был вызван из foo


Ответ

Вопрос очень интересный, попробую предложить решение, хотя не уверен, то ли это, что видится автору вопроса. На мой взгляд, хороший логгер должен выводить весь путь вызовов к точке вывода сообщения, наподобие вывода команды where в интерактивном отладчике gdb . В принципе, такую информацию можно извлечь, совместно рассматривая стек выполнения (там адреса возврата) и таблицу символов загрузочного модуля (там есть адреса точек входа в функции и их имена (конечно, если модуль не стрипнут). Для лабораторки это, конечно, крутовато. Можно, наверное, предложить 'ручной' вариант. При входе в функцию, имя которой должно появиться в списке логгера, вызовем My_set_fname(fname), а для печати My_logger(message); fname ДОЛЖНА быть локальной переменной (располагаться в стеке программы). My_set_fname(fname) будет вести свой стек (например, связанный список в куче или достаточно большой статический массив (собственно большой - это если My_set_fname() будут вызываться из рекурсии)). В этот стек надо помещать адрес параметра (fname). Здесь надо иметь в виду, что стек исполнения программы растет от больших адресов к меньшим, поэтому при очередном вызове My_set_fname() будем корректировать (путем удаления) верхнюю часть своего стека, так чтобы в нем содержались только адреса больше, чем адрес нашего аргумента. Эти соображения определяют требование к размещению аргумента. Константы и куча не подходят. Ну, логика My_logger(), по-моему, уже очевидна (или скажем так: формат вывода - дело вкуса).

Комментариев нет:

Отправить комментарий