Как проверить макросы, определенные в .so? Я бы использовал nm для проверки функции, есть ли способ сделать то же самое для макросов?

У меня есть такой код в mylib.h, и я использую его для создания mylib.so. Есть ли способ проверить, как MY_MACROS определен в .so?

#ifdef SWITCH_CONDITION
    #define MY_MACROS       0
#else
    #define MY_MACROS       1
#endif

Если бы это была функция, я бы просто сделал

nm mylib.so | grep myfunction

Есть ли способ сделать то же самое для макросов?

P.S. Должно быть из-за

> grep MY_MACROS mylib.so 
> Binary file mylib.so matches

person tkrishtop    schedule 02.09.2019    source источник
comment
Макросы не определены в динамических библиотеках, они создаются только во время компиляции (а не во время предварительной обработки). Чего вы пытаетесь достичь?   -  person walnut    schedule 02.09.2019
comment
Макросы заменяются препроцессором, поэтому они не существуют как символы в скомпилированном коде. Другими словами, в общем случае это невозможно   -  person Ingo Leonhardt    schedule 02.09.2019
comment
@uneven_mark спасибо! Я не уверен, что SWITCH_CONDITION работает должным образом, и пытаюсь выяснить, как это проверить.   -  person tkrishtop    schedule 02.09.2019
comment
Некоторые из вас превращают это в ответ.   -  person Marco Bonelli    schedule 02.09.2019
comment
определения макросов - это потеря информации во время компиляции, вы не можете, вообще говоря, увидеть, какие макросы компиляции были определены и с какими значениями.   -  person Luis Colorado    schedule 04.09.2019


Ответы (2)


В общем, для макросов нет возможности сделать что-то подобное. (Но подробнее см. ниже.)

Макросы препроцессора теоретически являются концепцией времени компиляции. Фактически, в ранних реализациях C препроцессор был буквально отдельной программой, работающей в отдельном процессе и преобразовывающей код C с #include, #define и #ifdef в код C без них. Фактический компилятор C видел только «предварительно обработанный» код.

Теоретически компилятор может каким-то образом сохранить некоторые записи определений макросов, возможно, для облегчения отладки. Я не знал ни о ком, кто делал это, хотя очевидно, что те, кто использует формат DWARF, действительно делают ! См. комментарии ниже и этот ответ.

Вы всегда можете написать свой собственный явный код для отслеживания определения определенных макросов. Например, я часто писал код, удлиняющий строки

void print_version()
{
    printf("myprogram version %s", VERSION_STRING);
#ifdef DEBUG
    printf(" (debug version)");
#endif
    printf("\n");
}

Некоторые проекты имеют довольно сложные механизмы для отслеживания переключателей компиляции, которые действуют для конкретной сборки. Например, в проектах, управляемых скриптом configure, часто имеется один файл, config.status содержащий один единственный запись всех вариантов компиляции, для потомков.

person Steve Summit    schedule 02.09.2019
comment
Обратите внимание, что вы можете grep получить двоичный файл, чтобы увидеть, было ли определено имя макроса, если вы компилируете с -gdwarf-4 -g3. - person S.S. Anne; 02.09.2019
comment
@SteveSummit Странно то, что grep MY_MACROS mylib.so приводит к Binary file mylib.so matches. Этот макрос должен быть где-то! :) Проблема в том, что grep -a MY_MACROS mylib.so | less и тут прямой поиск ничего не находит. - person tkrishtop; 02.09.2019
comment
@tkrishtop Ага! Так что мой ответ «нет» выглядит неправильным, а на самом деле ответ «да»! - person Steve Summit; 02.09.2019
comment
@tkrishtop Да, вы можете использовать -a для этой цели. Однако значение макроса (если это целое число) хранится в двоичном формате. - person S.S. Anne; 02.09.2019
comment
@ JL2210 Проблема в том, что grep -a MY_MACROS mylib.so | less, а затем прямой поиск ничего не находит. - person tkrishtop; 02.09.2019
comment
@tkrishtop Это невозможно сделать. Однако я могу написать инструмент, который выполняет эту работу. Дайте мне минуту (или час), и я посмотрю, что я могу сделать. - person S.S. Anne; 02.09.2019
comment
@ JL2210 У меня был соблазн сделать то же самое! Возможно, вы уже это знаете, но прежде чем изобретать велосипед, проверьте внешние ссылки на en.wikipedia.org/wiki/ КАРЛИК . - person Steve Summit; 02.09.2019

Да, но для этого требуется отладочная информация.

Вы можете скомпилировать свой код с помощью -g3:

$ gcc -g3 -shared -fPIC test.c -o test.so

а затем запустите strings для полученного двоичного файла:

$ strings test.so
...
__DEC32_EPSILON__ 1E-6DF
MY_MACROS 1
__UINT_LEAST32_TYPE__ unsigned int
person S.S. Anne    schedule 02.09.2019
comment
Хороший улов. -g3 является ключевым наблюдением. -g2 или ниже не включает определения макросов. (А также см. такие вопросы, как макросы gdb, отсутствующие даже при использовании -g3 или -ggdb3 или -gdwarf-4). - person jww; 02.09.2019