GDB: как преобразовать адрес памяти в объект STL

#c #gdb

#c #gdb

Вопрос:

Я анализирую дамп ядра с помощью GDB. Я знаю об адресе памяти, на который он указывает «std::basic_fstream<wchar_t, std::char_traits<wchar_t> >».

Как преобразовать необработанный адрес памяти в этот объект шаблона в приглашении GDB?

Я попытался с помощью приведенной ниже команды:

(gdb) p *(‘std::basic_fstream<wchar_t, std::char_traits<wchar_t> >’ *)0x7fae3800b280 Нет символа «std::basic_fstream<wchar_t, std::char_traits<wchar_t> >» в текущем контексте.

(gdb) p *(std::basic_fstream<wchar_t, std::char_traits<wchar_t> > *)0x7fae3800b280 Синтаксическая ошибка в выражении, рядом с `)0x7fae3800b280′.

Комментарии:

1. gdb, к сожалению, не является компилятором C , и только полноценный компилятор C может полностью понять все о системе типов C , включая шаблоны и перегрузки. gdb может обрабатывать простые вещи, такие как указатели, и справляться с этим. Но когда дело доходит до нетривиальных конструкций C , таких как шаблоны, gdb, к сожалению, не обладает необходимой мощностью мозга. Краткий ответ здесь: gdb не может этого сделать прямо сейчас.

2. std::basic_fstream<wchar_t, std::char_traits<wchar_t> > это не шаблон, хотя получить этот тип из шаблона std::basic_fstream не самая тривиальная вещь, которую нужно сделать

3. @idclev463035818: Я тебя не понял. Не могли бы вы, пожалуйста, уточнить больше, или лучше всего было бы поделиться точной командой для моего запроса

4. я только добавлял к тому, что уже сказал Сэм, и пытался указать вам на недоразумение: std::basic_fstream<wchar_t, std::char_traits<wchar_t> > это не шаблон.

5. @idclev463035818: Извините, я все еще не мог вас получить. basic_fstream — это шаблон только для шаблона < диаграмма классов, признаки класса = char_traits<Диаграмма> > класс basic_fstream;

Ответ №1:

Я попытался с помощью приведенной ниже команды:

Предположение: есть ли у вас set auto-solib-add off в вашем ~/.gdbinit ?

Следующий пример отлично работает для меня:

 cat t.cc
#include <fstream>

int main(int argc, char *argv[])
{
  std::wfstream s("/dev/tty", s.out);
  for (int j = 0; j < argc; j  )
    s << j << " " << argv[j] << std::endl;
  return 0;
}

g   -g t.cc amp;amp; gdb -q ./a.out

(gdb) b 8
Breakpoint 1 at 0x1235: file t.cc, line 8.
(gdb) run foo
Starting program: /tmp/a.out foo
0 /tmp/a.out
1 foo

Breakpoint 1, main (argc=2, argv=0x7fffffffdc28) at t.cc:8
8         return 0;
(gdb) set print static off

(gdb) p s
$1 = {<std::basic_iostream<wchar_t, std::char_traits<wchar_t> >> = {<std::basic_istream<wchar_t, std::char_traits<wchar_t> >> = {<std::basic_ios<wchar_t, std::char_traits<wchar_t> >> = ...

(gdb) p amp;s
$2 = (std::wfstream *) 0x7fffffffd900

(gdb) p *('std::basic_fstream<wchar_t, std::char_traits<wchar_t> >' *)0x7fffffffd900
$3 = {<std::basic_iostream<wchar_t, std::char_traits<wchar_t> >> = {<std::basic_istream<wchar_t, std::char_traits<wchar_t> >> = {<std::basic_ios<wchar_t, std::char_traits<wchar_t> >> = {<std::ios_base> = ...
  

Вы должны попытаться воспроизвести вышеуказанный вывод.

Если вы можете воспроизвести его, ваши инструменты работают должным образом, и вам нужно сосредоточиться на том, как вы анализируете core дамп.

Если приведенный выше пример работает не так, как ожидалось, у вас есть какая-то часть набора инструментов, которая ведет себя неправильно или неправильно настроена.

Один из способов, которым я смог достичь No symbol результата, — это установить auto-solib-add off :

 gdb -q ./a.out
Reading symbols from ./a.out...

(gdb) b 8
Breakpoint 1 at 0x1235: file t.cc, line 8.
(gdb) set auto-solib-add off
(gdb) run
Starting program: /tmp/a.out
0 /tmp/a.out

Breakpoint 1, main (argc=1, argv=0x7fffffffdc28) at t.cc:8
8         return 0;

(gdb) p amp;s
$1 = (std::wfstream *) 0x7fffffffd900

(gdb) p *('std::basic_fstream<wchar_t, std::char_traits<wchar_t> >' *) 0x7fffffffd900
No symbol "std::basic_fstream<wchar_t, std::char_traits<wchar_t> >" in current context.