Можно ли связать неразрешенную ссылку на прерывание? - PullRequest
12 голосов
/ 05 января 2010

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

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

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

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

Ответы [ 4 ]

15 голосов
/ 05 января 2010

Вы можете просто указать компоновщику игнорировать неразрешенные символы. Я не смог найти опцию, которая связывает их с 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's 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 попытки вызова неразрешенной функции приводят к «Сегментации».

1 голос
/ 05 января 2010

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

#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), она будет хорошо скомпилирована и скомпонована, но при выполнении программа. Обязательно ulimit -c unlimited, чтобы вы получили core.

1 голос
/ 05 января 2010

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

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

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

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

void some_func() { abort(); }

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

0 голосов
/ 05 января 2010

Попробуйте 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")));
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...