Как сделать так, чтобы gdb позволял мне вызывать "floor", даже если установлены файлы отладочной информации? - PullRequest
1 голос
/ 29 марта 2020

В ответ на Ответ занятого русского языка Я проверил, что у меня есть отладочные пакеты, которые должны предоставлять отладочную информацию, достаточную для вызова таких функций, как floor, из командной строки gdb, но что-то по-прежнему ведет себя странно в GDB.

Я запускаю эту версию GDB через:

gdb --version

is:

GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Информация об операционной системе Linux машины через:

lsb_release -r -i 

is:

Distributor ID: Ubuntu
Release:    19.10

Отладочные пакеты, которые я ожидаю использовать для gdb, чтобы найти символ floor через:

dpkg --listfiles libc6-dbg | grep libm

:

/usr/lib/debug/lib/x86_64-linux-gnu/libm-2.30.so
/usr/lib/debug/lib/x86_64-linux-gnu/libmemusage.so
/usr/lib/debug/lib/x86_64-linux-gnu/libmvec-2.30.so

Компиляция, запуск и запуск gdb через:

#!/bin/bash

exec 2>&1
set -x

rm -rf "/tmp/testdir"
mkdir -p "/tmp/testdir"
cd "/tmp/testdir"

cat > main.cpp <<'EOF'
#include <stdio.h>
#include <math.h>  // double floor(double x);

int main(int argc, char *argv[], char *const envp[])
{
  printf("From inside C++: floor(2.12) %g\n", floor(2.12));
  return 0;
} // end main
EOF

/usr/bin/c++  -MD -DDEBUG -g  -fPIC  -Wall -Werror -Wsynth -Wno-comment -Wreturn-type $cxx_args main.cpp -c -o main.o
/usr/bin/c++  -MD -DDEBUG -g  -fPIC  -Wall -Werror -Wsynth -Wno-comment -Wreturn-type $cxx_args main.o -L. -L/usr/lib64 -lstdc++  -o main.exe
(./main.exe; exit 0)
cat > /tmp/gdb.commands <<EOF
# https://stackoverflow.com/a/60909020/257924
set trace-commands on
b main
r
info shared
p floor(2.12)
EOF

gdb -batch -x /tmp/gdb.commands main.exe

exit 0

is:

+ rm -rf /tmp/testdir
+ mkdir -p /tmp/testdir
+ cd /tmp/testdir
+ cat
+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type main.cpp -c -o main.o
+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type main.o -L. -L/usr/lib64 -lstdc++ -o main.exe
+ ./main.exe
From inside C++: floor(2.12) 2
+ exit 0
+ cat
+ gdb -batch -x /tmp/gdb.commands main.exe
+b main
Breakpoint 1 at 0x1149: file main.cpp, line 5.
+r

Breakpoint 1, main (argc=0, argv=0x7fffffffdbc0, envp=0x555555555060 <_start>) at main.cpp:5
5   {
+info shared
From                To                  Syms Read   Shared Object Library
0x00007ffff7fd1100  0x00007ffff7ff23f4  Yes         /lib64/ld-linux-x86-64.so.2
0x00007ffff7dc9670  0x00007ffff7f3e74f  Yes         /lib/x86_64-linux-gnu/libc.so.6
+p floor(2.12)
/tmp/gdb.commands:6: Error in sourced command file:
No symbol "floor" in current context.
+ exit 0

Даже если у меня установлена ​​отладочная информация, как показано выше Почему GDB не может позволить мне вызывать функцию, которую может вызывать сама программа?

Как это исправить?

Обновление 1

По справке от Занимал русский в { ссылка }, я использовал set trace-command on в командах GDB.

Обновление 2

В Занято Русси комментарий , вставленный в info shared в команды gdb.

Обновление 3

Per Ответ занятого русского языка , я перестроил с помощью -fno-builtin через:

#!/bin/bash

exec 2>&1
set -x

cxx_args='-fno-builtin'
rm -rf "/tmp/testdir"
mkdir -p "/tmp/testdir"
cd "/tmp/testdir"

cat > main.cpp <<'EOF'
#include <stdio.h>
#include <math.h>  // double floor(double x);

int main(int argc, char *argv[], char *const envp[])
{
  printf("From inside C++: floor(2.12) %g\n", floor(2.12));
  return 0;
} // end main
EOF

/usr/bin/c++  -MD -DDEBUG -g  -fPIC  -Wall -Werror -Wsynth -Wno-comment -Wreturn-type $cxx_args main.cpp -c -o main.o
/usr/bin/c++  -MD -DDEBUG -g  -fPIC  -Wall -Werror -Wsynth -Wno-comment -Wreturn-type $cxx_args main.o -L. -L/usr/lib64 -lstdc++  -o main.exe
(./main.exe; exit 0)
cat > /tmp/gdb.commands <<EOF
# https://stackoverflow.com/a/60909020/257924
set trace-commands on
b main
r
info shared
p floor(2.12)
EOF

gdb -batch -x /tmp/gdb.commands main.exe

exit 0

- это:

+ cxx_args=-fno-builtin
+ rm -rf /tmp/testdir
+ mkdir -p /tmp/testdir
+ cd /tmp/testdir
+ cat
+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type -fno-builtin main.cpp -c -o main.o
+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type -fno-builtin main.o -L. -L/usr/lib64 -lstdc++ -o main.exe
+ ./main.exe
From inside C++: floor(2.12) 2
+ exit 0
+ cat
+ gdb -batch -x /tmp/gdb.commands main.exe
+b main
Breakpoint 1 at 0x1169: file main.cpp, line 5.
+r

Breakpoint 1, main (argc=0, argv=0x7fffffffdbc0, envp=0x555555555080 <_start>) at main.cpp:5
5   {
+info shared
From                To                  Syms Read   Shared Object Library
0x00007ffff7fd1100  0x00007ffff7ff23f4  Yes         /lib64/ld-linux-x86-64.so.2
0x00007ffff7e553c0  0x00007ffff7efbe78  Yes         /lib/x86_64-linux-gnu/libm.so.6
0x00007ffff7c7a670  0x00007ffff7def74f  Yes         /lib/x86_64-linux-gnu/libc.so.6
+p floor(2.12)
$1 = 2
+ exit 0

1 Ответ

2 голосов
/ 29 марта 2020

Я воспроизвел это. Проблема двоякая:

  1. Компилятор может вычислять floor(2.12) без вызова libm.so.6 и
  2. Компилятор настроен на передачу аргумента --as-needed компоновщику .

Проблема 1) приводит к тому, что libm.so.6 не требуется. Разборка main показывает:

=> 0x0000555555555148 <+19>:    mov    0xee1(%rip),%rax        # 0x555555556030
   0x000055555555514f <+26>:    movq   %rax,%xmm0
   0x0000555555555154 <+31>:    lea    0xead(%rip),%rdi        # 0x555555556008
   0x000055555555515b <+38>:    mov    $0x1,%eax
   0x0000555555555160 <+43>:    callq  0x555555555030 <printf@plt>

(gdb) p *(double*)0x555555556030
$1 = 2

И info shared показывает, что GDB не загружал libm.so.6 (так как он не нужен), поэтому отладочная информация для него также никогда не загружалась.

Немного изменив источник:

1       #include <stdio.h>
2       #include <math.h>  // double floor(double x);
3
4       int main(int argc, char *argv[], char *const envp[])
5       {
6         double d = 2.12;
7         printf("From inside C++: floor(2.12) %g\n", floor(d));
8         return 0;
9       } // end main

Результат:

(gdb) start
Temporary breakpoint 1 at 0x1158: file main.cpp, line 6.
Starting program: /tmp/testdir/a.out 

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdca8, envp=0x7fffffffdcb8) at main.cpp:6
6         double d = 2.12;
(gdb) n
7         printf("From inside C++: floor(2.12) %g\n", floor(d));
(gdb) p floor
$1 = {<text gnu-indirect-function variable, no debug info>} 0x7ffff7e8e820 <__floor_ifunc>
(gdb) p floor(d)
$2 = 2

PS Вместо изменения источника вы также можете запретить компилятору знать, что floor с -fno-builtin или -fno-builtin-floor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...