#ubuntu #math #gcc #gdb #symbols
#ubuntu #математика #gcc #gdb #символы
Вопрос:
Я попытался вызвать свою собственную функцию и стандартную функцию в отладчике:
#include<stdlib.h>
#include<math.h>
#include<stdio.h>
int i=3;
void f(){
i;
printf("%dn",i);
}
int main(){
i;
int j=i 2;
double d=cos(0.0);
printf("%fn",d);
return 0;
}
Скомпилируйте эту программу и запустите, она выведет «1.000000», как я и ожидал.
В gdb я попытался:
(gdb) b main
Breakpoint 1 at 0x40055b: file x.c, line 10.
(gdb) r
Starting program: /home/x/a.out
Breakpoint 1, main () at x.c:10
10 i;
(gdb) call f()
4
(gdb) call f()
5
(gdb) call cos(0.0)
No symbol "cos" in current context. # WHY?????
(gdb) call printf("%dn",i)
5
$1 = 2
(gdb) call putchar('a')
$2 = 97
Почему gdb не может даже найти символ? Я полагаю, опция «-g» предоставит отладочную информацию как для моей программы, так и для стандартной библиотеки, верно? Или мне нужно установить дополнительный пакет для отладки / исходный код для стандартной библиотеки? Я на ubuntu16.04
Большое спасибо.
Ответ №1:
Несмотря на непосредственный внешний вид, эта часть gdb работает хорошо. Итак, мое первое предположение заключается в том, что мы находимся в какой-то сложной ситуации — gdb необычайно восприимчива к вражеским действиям компиляторов и ядер — и требуется некоторое расследование.
Вы не говорите, используете ли вы C или C .
В C я вижу, что для cos
не генерируется debuginfo, и вызов полностью оптимизирован. Вы можете проверить это, запустив nm
и отметив, что cos
это не отображается в виде неопределенного символа; или просто заметив, что эта программа прекрасно связывается без -lm
.
Моя теория для C заключается в том, что это происходит потому, что в области видимости есть constexpr
версия cos
(я вижу это в предварительно обработанном выводе, но я не пытался по-настоящему проверить), и поэтому g оптимизирует весь вызов.
Для C я вижу то же самое по умолчанию. Однако я могу получить вызов, cos
передав -fno-builtin-cos
в gcc. Но, ха-ха, этого все еще нет в debuginfo!
Мне это кажется ошибкой gcc. Обычно вам не нужен debuginfo для библиотеки, просто чтобы иметь доступ к типу или функции из библиотеки, используемой вашей программой.
Вы также можете заметить, что происходит что-то странное, пытаясь распечатать саму функцию:
(gdb) p cos
$1 = {<text gnu-indirect-function variable, no debug info>} 0x7ffff7aebc50 <cos>
Это вдвойне плохая новость, потому что «непрямые» функции GNU — это волшебные создания, которые не всегда правильно понимаются gdb. В частности, я не думаю, что их можно вызвать из отладчика, даже с установленным debuginfo.
На самом деле, единственное, что я мог заставить работать, это взять адрес cos
в программе, затем вызвать через этот указатель, например:
mumble *my_cos = amp;cos;
...
(gdb) print my_cos(0.0)
Ну, это не совсем так. Я также мог бы заставить это работать:
(gdb) info func cos@plt
All functions matching regular expression "cos@plt":
Non-debugging symbols:
0x0000000000400500 cos@plt
(gdb) p ((double(*)(double))0x0000000000400500)(0.0)
$6 = 1
Это позволяет избежать непрямых действий GNU. Тем не менее, это довольно неприятно.
Комментарии:
1. Спасибо, ваш ответ по существу. Вы могли видеть из gdb print, я использую файл «x.c», который не является C . Ну, сначала мне было интересно, почему я могу скомпилировать ее без -lm, теперь я знаю, что она заменяется встроенными функциями gcc. При указании -fno-builtin требуется -lm.
Ответ №2:
- функция cos реализована в libm, а не libc. Вы вообще связались с -lm?
- Компилятор оптимизирует постоянные выражения. Нет причин вычислять cos (0) во время выполнения. Таким образом, нет необходимости включать функцию cos и нет причин для привязки математической библиотеки. Ссылка на libm удалена из вашего исполняемого файла (что вы можете проверить с помощью readelf или аналогичного инструмента), следовательно, gdb ничего не известно о cos (или любой другой функции из math library).
- Как объяснил Том Троми, одним из возможных обходных путей является отключение встроенных функций gcc. После этого я могу вызвать cos из gdb (например, так:print cos(1.0)).