Подтвердить что ты не робот

Могу ли я связать неразрешенные ссылки для отмены?

Я пытаюсь написать небольшие тесты для довольно небольшой части довольно большого проекта. К сожалению, попытка связать этого зверя довольно сложно без объединения всего проекта, который я не хочу делать (это довольно сложная система для поиска всех зависимостей и т.д., И я не могу вмешиваться в нее).

Теперь я точно знаю, что функции, на которые ссылающиеся функции не будут вызываться во время моего теста, просто являются частью функций, которые делят файл с материалами, которые я тестирую.

Можно ли просто связать эти нерешенные ссылки, допустим, отменить или что-то еще? Или есть инструмент, который создает соответствующий файл-заглушку, где все вызовы приводят к отмене, учитывая набор файлов объектов, которые у меня есть?

Я использую gcc (g++) для компиляции/компоновки, версия 3.4.4. Платформа - unix (solaris/sparc, если это важно).

4b9b3361

Ответ 1

Вы можете просто сказать компоновщику, чтобы игнорировать неразрешенные символы. Я не мог найти вариант, который связывает их с abort или что-то в этом роде.

Политика игнорирования неразрешенных символов в объектных файлах является наиболее естественной, я полагаю:

gcc -Wl,--unresolved-symbols=ignore-in-object-files  obj.o another.o etc.o

Другие варианты включают (цитирование man ld):

   --unresolved-symbols=method
       Determine how to handle unresolved symbols.  There are four possi-
       ble values for method:

       ignore-all
           Do not report any unresolved symbols.

       report-all
           Report all unresolved symbols.  This is the default.

       ignore-in-object-files
           Report  unresolved  symbols  that  are  contained  in   shared
           libraries,  but  ignore  them if they come from regular object
           files.

       ignore-in-shared-libs
           Report unresolved symbols that come from regular object files,
           but  ignore them if they come from shared libraries.  This can
           be useful when creating a dynamic binary and it is known  that
           all  the  shared  libraries  that it should be referencing are
           included on the linker command line.

       The behaviour for shared libraries on their own can also  be  con-
       trolled by the --[no-]allow-shlib-undefined option.

       Normally  the  linker  will  generate  an  error  message for each
       reported unresolved symbol but the  option  --warn-unresolved-sym-
       bols can change this to a warning.

В моей системе Linux попытки вызвать нерешенную функцию приводят к "Ошибка сегментации".

Ответ 2

Ну, один из способов, которым я могу думать, - сначала скомпилировать файлы .o для вашей библиотеки.

Затем используйте инструмент, например nm (обычный в системах * nix), чтобы получить все символы, в nm все "внешние" (такие же, которые не найдены в этом .o) имеют тип U (он может отличаться для версий, отличных от GNU nm, см. вашу документацию).

Если ваша библиотека является всего одним исходным файлом, то она проста, почти все символы типа U будут либо функцией, найденной в другой библиотеке, либо не будут решены во время ссылки. Это немного сложнее, если ваша библиотека будет более чем одним исходным файлом, так как у вас будут зависимости между исходными файлами.

Итак, теперь у вас есть средство для создания потенциального списка нерешенных внешних, тогда вы можете создать "test_stub.c", который имеет символы заглушки для каждого из них, которые вы могли бы заполнить примерно так:

void some_func() { abort(); }

где some_func является a, будет нерешенным внешним. Компилируйте и свяжите это со своей библиотекой, и все вызовы должны привести к прерыванию.

Ответ 3

Попытка скомпилировать следующую программу

#include <iostream>

extern int bar();

int foo()
{
  return bar() + 3;
}

int main()
{
  std::cout << "Hello, world!" << std::endl;
  // std::cout << foo() << std::endl;

  return 0;
}

приводит к

$ g++ -o main main.cc
/tmp/ccyvuYPK.o: In function `foo()':
main.cc:(.text+0x5): undefined reference to `bar()'
collect2: ld returned 1 exit status

Но мы можем сказать, что компоновщик игнорирует неразрешенные символы и запускает его просто отлично:

$ g++ -Wl,--unresolved-symbols=ignore-all -o main main.cc
$ ./main
Hello, world!

Скажите, что какая-то нерешенная функция вызывается вашей тестовой жгутой (имитируйте это, раскомментировав вызов foo), она будет компилироваться и правильно связываться, но при выполнении программы вы получите segfault. Обязательно ulimit -c unlimited, чтобы получить core.

Ответ 4

Попробуйте атрибут GCC alias:

/* cannot directly alias to yet undefined symbols,
 * so need an intermediate function.
 */
static void do_abort() { abort(); }

void func0() __attribute__ ((weak, alias ("do_abort")));
void func1() __attribute__ ((weak, alias ("do_abort")));
...