Как узнать, где определяются символы при связывании кода C - PullRequest
4 голосов
/ 19 марта 2019

Я столкнулся с неопределенной ссылочной проблемой с конкретными символами в моей связи.

error: undefined reference to 'g_queue_pop_nth'

Я работаю на платформах LOP & ARM.Мы используем одну и ту же среду на обеих платформах.Наша сборка ARM связывает без проблем.Но на платформе LOP я поражаю отказ выше.Я хочу проверить, из какой библиотеки этот символ определяется на хосте ARM.Существуют ли какие-либо флаги или параметры для GCC, чтобы получить информацию о том, какая библиотека предоставляет определение этого символа?

Ответы [ 2 ]

1 голос
/ 19 марта 2019

Во время компоновки вы можете попросить компоновщика сообщить вам, в каком входном файле (объектный файл, член статической библиотеки или совместно используемая библиотека) он находит определение любого символа и в каких файлах он находит этот символ, на который ссылаются, используя опцию компоновщика.-trace-symbol=name.

Например:

$ cat main.c
extern void foo(void);

int main(void)
{
    foo();
    return 0;
}

$ cat foo.c
#include <stdio.h>

void foo(void)
{
    fputs(__func__,stdout);
}

Скомпилировать источники:

$ gcc -Wall -c main.c foo.c

Создать статическую библиотеку:

$ ar rcs libfoo.a foo.o

Свяжите программу, запрашивая трассировку символов для foo и fputs:

$ gcc -o prog main.o -L. -lfoo -Wl,-trace-symbol=foo,-trace-symbol=fputs
/usr/bin/ld: main.o: reference to foo
/usr/bin/ld: ./libfoo.a(foo.o): definition of foo
/usr/bin/ld: ./libfoo.a(foo.o): reference to fputs
/usr/bin/ld: //lib/x86_64-linux-gnu/libc.so.6: definition of fputs

Таким образом, foo определено в элементе архива foo.o из ./libfoo.a и fputsопределяется в /lib/x86_64-linux-gnu/libc.so.6

1 голос
/ 19 марта 2019

Я только что написал сценарий в пятницу, чтобы сделать это почти точно. Этот скрипт находит как определенные, так и неопределенные ссылки на символ в данном каталоге:

#!/bin/bash
#findsym.sh
PATTERN=${1:-"symbol"}
OBJDUMP=armdir/arm-linux-gnuabi-objdump

for f in $(find . -name "*.so" -o -name "*.[ao]"); do
    ${OBJDUMP} -tT $f 2>/dev/null | grep -q ${PATTERN}  2>/dev/null
    [[ ${PIPESTATUS[0]} -eq 0 && ${PIPESTATUS[1]} -eq 0 ]] || continue
    echo "FILE: $f"
    ${OBJDUMP} -tT $f | grep  ${PATTERN}
    echo
done

Использование:

 findsym.sh g_queue_pop_nth

Вам придется изменить путь к objdump, и если вы просматриваете файлы, созданные в C ++, вы можете добавить -C к своим флагам objdump.

...