FAQ программирования Linux: использование инструментария |
![]() |
Добавил(а) microsin |
Здесь приведен перевод главы 6 из FAQ по программированию Linux [1], посвященной инструментарию. Описание незнакомых терминов и аббревиатур см. в Словарике статьи [2]. [Список вопросов] 6. Использование инструментов 6.1 Как можно отлаживать дочерний процесс после fork? 6.2 Как собрать библиотеку из других библиотек? 6.3 Как создать совместно используемые библиотеки (shared libraries / dll)? 6.4 Как заменить объекты в shared library? 6.5 Как сгенерировать дамп стека из работающей программы? 6.1 Как можно отлаживать дочерний процесс после fork? В зависимости от наличия доступного инструментария есть несколько путей. У вашего отладчика могут быть опции для выбора, отлаживать родительский процесс, или дочерний (или их обоих) после вызова fork(), что может быть достаточно для некоторых целей. Альтернативно у вашего отладчика может быть опция, которая позволит вам подключиться к запущенному процессу. Это можно использовать для подключения к дочернему процессу после того, как он был запущен. Если вам не нужно очень раннюю стадию запуска дочернего процесса, то этого обычно достаточно. Иначе вы можете захотеть вставить вызов sleep() после fork() в дочерний процесс, или выполнить примерно такой цикл: { volatile int f = 1; while(f); } Этот цикл приведет к зависанию дочернего процесса, пока вы явно не установите в 0 переменную f с помощью отладчика. Также следует помнить, что активное использование отладчика не единственный путь искать ошибки в программе; доступны утилиты для трассировки системных вызовов и сигналов на многих разновидностях unix-систем, и часто полезен бывает подробный вывод в лог. 6.2 Как собрать библиотеку из других библиотек? Если мы говорим об архиве (*.a, т. е. о статической библиотеке), самый простой путь состоит в том, чтобы расчленить все составляющие библиотеки на их исходные объекты, используя ar x в пустой директории, и потом скомбинировать их обратно. Конечно, существует вероятность коллизии имен файлов, однако если библиотеки большие, то возможно вы не захотите их объединять в первую очередь... 6.3 Как создать совместно используемые библиотеки (shared libraries / dll)? Правильный метод создания shared-библиотек меняется в зависимости от используемой операционной системы. У этого процесса 2 основные части; сначала должны быть скомпилированы объекты, которые должны быть включены в shared-библиотеку, обычно с опциями, которые указывают, что код не зависит от позиции в памяти; затем эти объекты линкуются друг с другом, формируя библиотеку. Вот пример, иллюстрирующий эту идею: /* Файл shrobj.c */ const char *myfunc() { return "Hello World"; } /* Конец shrobj.c */ /* Файл hello.c */ #include < stdio.h> extern const char *myfunc(); main() { printf("%s\n", myfunc()); return 0; } /* Конец hello.c */ Компиляция: $ gcc -fpic -c shrobj.c $ gcc -shared -o libshared.so shrobj.o $ gcc hello.c libshared.so $ ./a.out Hello World Безусловно, если вы хотите достичь какой-то допустимой портируемости библиотеки и процедуры сборки, то самый лучший способ это использование GNU Libtool. Это небольшой набор утилит, которые знают про зависимые от платформы аспекты сборки shared-библиотек; вы можете распространить необходимые биты вместе со своей программой, так что когда инсталлятор конфигурирует пакет, он может решить, какие библиотеки собирать. Libtool хорошо работает на системах, которые не поддерживают shared-библиотеки. Он также знает, как использовать GNU Autoconf и GNU Automake (если вы используете эти инструменты для поддержки процедуры сборки вашей программы). Если вы не хотите использовать Libtool, то для компиляторов, отличающихся от gcc, вы должны поменять опции компилятора следующим образом: AIX 3.2 при использовании xlc (не проверено) SCO OpenServer 5 при использовании SCO Development System (не проверено) Solaris при использовании компиляторов SparcWorks (Если кто-то знает другие рецепты, буду рад, если поделитесь.) Другие вопросы, на которые следует обратить внимание: * AIX и (что вероятно) Digital Unix не требуют опции -fpic, потому что весь код не зависит от расположения в памяти (position independent). 6.4 Как заменить объекты в shared library? В основном никак. На большинстве систем (кроме AIX), когда вы линкуете объекты для формирования shared-библиотеки, это одно и то же, что и делать линковку исполняемого кода; объекты не сохраняют свою индивидуальную идентичность. В результате как правило нельзя извлечь или заменить отдельные объекты из shared-библиотеки. 6.5 Как сгенерировать дамп стека из работающей программы? Некоторые системы предоставляют библиотечные функции для разматывания стека, так что вы можете (например) создать дамп стека в функции обработки ошибок. Тем не менее, они сильно зависят от системы, и только в меньшинстве систем они есть. Возможное обходное решение состоит в том, чтобы заставить вашу программу вызвать отладчик "на себе" - детали этой процедуры все еще незначительно отличаются между системами, однако основная идея состоит в том, чтобы сделать следующее: void dump_stack(void) { char s[160]; sprintf(s, "/bin/echo 'where\ndetach' | dbx -a %d", getpid()); system(s); return; } Вам нужно будет настроить команды и параметры dbx в соответствии с вашей системой, или даже заменить на другой отладчик, такой как gdb, однако это вероятно все еще основное решение для такой частной проблемы. Спасибо за это Ralph Corderoy :-) Список строк команд, требуемых для некоторых систем: Большинство систем, использующих dbx: AIX: IRIX: [Ссылки] 1. Unix Programming FAQ (v1.37) site:opennet.ru. |