|
By Maxim Kartashev, Sun Microsystems, April 25, 2006
|
|
|
В случае, если dbx, отладчик Sun Studio, не находит
всю необходимую ему отладочную информацию, он будет выдавать
предупреждающие сообщения об ее отсутствии. В этой статье описаны
сообщения об ошибках, которые могут появиться, объясняются
возможные причины возниконовения этих ошибок и даются советы как
их исправить или избежать.
»
Read English version
Часто встречающиеся сообщения об ошибках
Ниже
представлены типичные ошибки, которые могут встретиться при
использовании dbx, отладчика Sun Studio.
(dbx) stop in foo
dbx: warning: 'foo' has no debugger info -- will trigger on first
instruction
-----
(dbx) stop at b.c:5
dbx: no executable code at line "b.c":5
-----
dbx: warning: can't find file "/.../a.o"
dbx: warning: see `help finding-files'
-----
(dbx) stop at a.c:5
dbx: cannot find object file corresponding to "a.c"
-----
(dbx) list foo
dbx: no source lines for "foo"
Возможные причины возникновения ошибок
- Объектные файлы скомпилированы без указания опции -g
-
Проверьте, указана ли опция компилятора -g в make-файлах,
просмотрите также вывод сценария построения программы на предмет
наличия этой опции. См. также как
определить, содержит ли
a.out/.so/.o отладочную
информацию в следующем параграфе.
-
Отладочная информация была удалена из загружаемых объектов
(т.е. a.out/.so)
-
Посмотрите, удаляется ли отладочная информация из a.out/.so
в make-файлах после их построения. Удалите команды strip из
make-файлов.
-
Объектные файлы могут находится не там, где dbx ожидает их
обнаружить
-
Объектные файлы могут быть перемещены после создания
программы (a.out или .so) или же директория, в которой они
хранятся, может быть подмонтирована под другим именем. В этом
случае должна помочь команда dbx pathmap (см. как
пользоваться pathmap ниже). Эта проблема может возникнуть
только с одним типом отладочной информации - stabs, но не с
dwarf. Подробнее см. ниже.
-
Разделяемая библиотека может быть еще не загружена
-
Если отлаживаемая программа содержит
разделяемую библиотекy, может случиться так, что эта библиотека
еще не загружена. Этот факт можно проверить с помощью команды
loadobject -list | grep <your library>. Также
можно один раз запустить свою программу под dbx для того,
чтобы все библиотеки загрузились, а начать отлаживать ее на
следующем запуске. Еще один способ - это принудительная загрузка
библиотеки с помощью команды dbx loadobject -load <your
.so path>. Как только библиотека загружена, ее можно
отлаживать. Примечение: библиотеки, слинкованные с помошью
опции компоновщика -l, загружаются dbx автоматически, а
библиотеки, загружаемые с помощью dlopen, невидимы для dbx до тех
пор, пока программа не будет запущена.
Как определить причину ошибки
В том случае, если известно имя функции, которую требуется
отлаживать (путь это будет foo(), например), введите
(dbx) whereis foo
Если вывод будет похож на приведенные ниже
function: `a.out`#__1cDfoo6Fipc_i_ [non -g,
demangles to: foo(int,char*)]
(обратите внимание на отсутствие имени файла после a.out)
можно быть уверенным в том, что файл, содержащий эту
функцию, был скомпилирован без отладочной информации или же
отладочная информация была удалена командой strip. Для того чтобы
получить возможность отлаживать foo(), придется перекомпилировать
содержащий ее файл с опцией -g, скомпоновать программу и
убедиться в отсутствии вызовов strip в сценарии построения
программы.
Следующий вывод (обратите внимание на наличие a.c после
a.out)
function: `a.out`a.c`#__1cDbar6Fi_pc_
[non -g, demangles to: bar(int)]
означает, что dbx не может найти объектный файл, содержащий
функцию вместе с отладочной информацией. Воспользуйтесь командой
pathmap (см. ниже) для того, чтобы указать dbx
местоположение объектного файла.
И наконец, отсутствие вывода означает, что dbx ничего не
знает об указанном символе. Если известно, что символ с таким
именем существует, это значит что символ принадлежит
еще не загруженной библиотеке. Воспользуйтесь командой
loadobject -load чтобы загрузить ее (см. выше).
Если известно имя объектного файла, содержащего нужную функцию,
можно воспользоваться командой module -v.
Введите команду
module -v <имя
объектного файла> и посмотрите на вывод этой
команды.
Если dbx выводит сообщение о том, что объектный файл не
доступен, значит он был скомпилирован без опции -g.
Если dbx печатает исходный (ожидаемый) путь к .o-файлу, а также
выводит сообщение о том, что этот файл не найдет, это означает что
объектный файл был перемещен из того каталога, в котором был
сгенерирован компилятором. Убедитесь что этот файл существует и
воспользуйтесь командой pathmap.
Вывод dbx "Can't find module ..." может
означать одно из двух: либо загружаемый объект не содержит
отладочной информации (индекса), либо этот объектный файл не
принадлежит ни к одному из загружаемых объектов (то есть
исполняемых файлов или библиотек), находящихся в памяти в данный
момент. Воспользуйтесь командой loadobject -list чтобы
получить список всех библиотек, находящихся в данный момент в
памяти процесса.
Как определить наличие отладочной информации
в a.out/.so/.o
Компиляторы Sun Studio могут генерировать отладочную информацию
в одном из двух форматах: stabs или dwarf (см. ниже). В Sun
Studio 11, компилятор C по умолчанию генерирует dwarf , в то
время как компиляторы C++ и Fortran - stabs. В следующих
релизах все копиляторы будут использовать dwarf по умолчанию.
Если Вы не уверены в том, есть в объектном файле отладочная
информация или нет, воспользуйтесь утилитами, входящими в Sun
Studio: dwarfdump/dumpstabs (каждая отвечает за
соответсвующий формат отладочной информации). Обе утилиты работают
с любым ELF файлом (a.out/.so/.o). Основная проблема
здесь в том, что отсутствие отладочной информации одного типа не
значит ничего -- чтобы быть уверенным в ее полном отсутствии
приходится восстановить полную картину.
Попробуйте
запустить dwarfdump:
$ dwarfdump -l <a.out/.so/.o>
Если эта команда напечатает "No DWARF information
present in a.out", значит a.out не содержит отладочной
информации или же эта информации в формате stabs.
Если dwarfdump выводит секцию .debug_line,
посмотрите, содержит ли эта секция какую-нибудь информацию. Если
она пуста, значит тип используемой отладочной информации dwarf, но
сама отладочная информация отсутствует (это может случиться если
задана опция C++ компилятора -xdebugformat=dwarf, а опция -g
- нет). И наконец, в том случае если секция .debug_line
не пуста, отладочная информация dwarf присутствует.
Если отладочная информация в формате dwarf не была обнаружена,
попробуйте воспользоваться командой
$ dumpstabs -s <a.out/.so/.o>
Для файла без отладочной информации, выводимая
Index Stab Table будет содержать малое количество элементов
(три) или вовсе отсутствовать. Если же элементов больше
(десятки, сотни, тысячи), значит файл содержит отладочную
информацию stabs.
Как пользоваться pathmap чтобы указать
путь к объектным файлам
Если при отладке используется другой путь (директория
подмонтирована через NFS и т.п.), отличный от исходного, или
объектные файлы были перемещены с момента их построения, dbx не
сможет обнаружить объектные файлы, поскольку индексная отладочная
информация ссылается на файлы, используя абсолютный путь.
Чтобы обойти эту проблему, воспользуйтесь командой pathmap.
Предположим, файлы исходно были построены в каталоге
/home/me/program, а отладка происходит с другого компьютера
и доступ к файлам производится с помощью NFS по такому пути:
/net/machine/myprogram
В таком случае, можно
ввести команду
(dbx) pathmap /home/me/program
/net/machine/myprogram
и dbx заменит все ссылки на старое местоположение
(/home/me/program) на новое (/net/machine/myprogram).
Дополнительная информация
Команда dbx help finding-files дает хорошее описание
возможных проблем и их решений в этой области.
- Следующие опции компилятора
относятся к генерации отладочной информации и применимы к
компиляторам С, С++ и Fortran:
-
-g - генерировать отладочную информацию. Небольшое
количество отладочной информации будет сгенерировано в объектный
файл даже без этой опции.
-xs -
использование этой опции приводит к тому, что отладочная
информация помещается в объектные файлы таким образом, что
в конечном итоге при компоновке она оказывается в a.out или
разделяемой библиотеке. Это не оказывает большого влияния на
скорость работы dbx и самой программы, но требует больше
дискового пространства. Опция имеет смысл только для формата
stabs.
-xdebugformat=[stabs|dwarf]
- указывает какой тип отладочной информации нужно генерировать.
- Некоторые полезные команды dbx:
-
module
-
modules
-
pathmap
-
loadobject
-
(используйте
help <команда> в dbx для
получения более подробной информации). -
Еще несколько полезных ресурсов:
-
-
stabs
-
Stabs это более старый формат представления отладочной
информации; он, однако, все еще является форматом по умолчанию
для компиляторов C++ и Fortran Sun Studio. Дополнительная
информация может быть найдена по этой ссылке:
http://blogs.sun.com/roller/page/quenelle?entry=the_story_of_lazy_stabs
-
dwarf
-
DWARF (Debug With Arbitrary Record Format) является более новым и
расширяемым форматом, теперь поддерживаемым компиляторами
Sun Studio; последние версии g++ и компилятор C Sun Studio
генерируют dwarf по умолчанию.
|
|