Udostępnij przez


Symbole i źródła systemu Linux

W tym artykule opisano, jak usługa WinDbg obsługuje standardowe symbole i źródła systemu Linux. Obsługa debugowania w systemie Linux wymaga systemu WinDbg w wersji 1.2402.24001.0 lub nowszej.

Serwery symboli DebugInfoD

Debuger okna używa standardu DebugInfoD do automatycznego pobierania artefaktów kompilacji dla systemu Linux. Co do porównania, DebugInfoD to kombinacja technologii serwera symboli firmy Microsoft i serwera źródłowego. To narzędzie umożliwia automatyczne pobieranie trzech typów artefaktów (wykonywalnych (ELF), informacji debugującej (DWARF) i źródłowego (kod)) na podstawie identyfikatora kompilacji. Różne dystrybucje systemu Linux hostują teraz własne serwery DebugInfoD, które udostępniają niektóre typy artefaktów. Różne serwery DebugInfoD są wymienione na stronie ELFUTILS https://debuginfod.elfutils.org.

Ogólne informacje o DebugInfoD są dostępne tutaj:

Tag DebugInfoD* może wskazywać jeden lub więcej serwerów DebugInfoD, gdzie każdy adres URL serwera jest sformatowany jako https://domain.com i oddzielony znakiem *. Serwery będą przeszukiwane w tej samej kolejności, co wymienione w ścieżce źródłowej, a pliki zostaną pobrane z pierwszego pasującego adresu URL.

Możesz na przykład ustawić ścieżkę symbolu w następujący sposób.

.sympath+ DebugInfoD*https://debuginfod.elfutils.org

Użyj polecenia !sym noisy, aby wyświetlić informacje o ładowaniu symboli. Aby uzyskać więcej informacji, zobacz !sym.

Polecenie ścieżki źródłowej (.srcpath, .lsrcpath (Ustaw ścieżkę źródłową)) obsługuje pobieranie plików z serwerów DebugInfoD za pośrednictwem tagu DebugInfoD*, co umożliwia pobieranie artefaktów kodu źródłowego. Możesz na przykład ustawić ścieżkę źródłową w następujący sposób.

.srcpath+ DebugInfoD*https://debuginfod.elfutils.org

Aby uzyskać więcej informacji, zobacz wydłużony dostęp do kodu źródłowego.

Symbole DWARF

DWARF to powszechnie używany, ustandaryzowany format danych debugowania. DWARF został pierwotnie zaprojektowany wraz z formatem wykonywalnym i linkowalnym (ELF), chociaż jest niezależny od formatów plików obiektów. Aby uzyskać więcej informacji, zobacz https://en.wikipedia.org/wiki/DWARF, a dla standardu wersji 5 zobacz DWARF Version 5.

Użyj polecenia zrzutu obiektu, aby określić wersję symbolu DWARF. W tym przykładzie wersja 5.

bob@BOB:/mnt/c/Users/BOB$ objdump -g DisplayGreeting | grep -A 2 'Compilation Unit @'
  Compilation Unit @ offset 0x0:
   Length:        0x285c (32-bit)
   Version:       5

Obsługa DWARF w WinDbg

WinDbg obsługuje następujące zastosowania DWARF i ELF.

  • tryb użytkownika systemu Linux — otwieranie zrzutów core systemu Linux ELF (-z <core dump>) i wykonywanie debugowania i analizy pośmiertnej z pełnymi prywatnymi symbolami DWARF.

  • Tryb jądra systemu Linux — otwieranie zrzutów jądra systemu Linux (ELF VMCORE) i przeprowadzanie debugowania i analizy pośmiertnej z pełnymi prywatnymi symbolami DWARF.

  • tryb jądra Linuksa — otwieranie skompresowanych zrzutów jądra Linuksa i wykonywanie debugowania i analizy pośmiertnej za pomocą pełnych prywatnych symboli DWARF (WinDbg obsługuje tylko pliki KDUMP skompresowane przy użyciu ZLIB. Pliki KDUMP skompresowane przy użyciu LZO i Snappy są nieobsługiwane).

  • Otwieranie obrazów ELF (-z <ELF image>) i analiza zawartości, deasemblacji itp.

  • Inne scenariusze — opis obrazów ELF i symboli DWARF w mieszanych środowiskach PE/ELF (np. debugowanie składników Open Enclave załadowanych w systemie Windows). Aby uzyskać więcej informacji, zobacz debugowanie Open Enclave.)

Obsługa GDBServer Linux w WinDbg

Debuger GNU GDBServer jest używany w systemie Linux do obsługi połączenia WinDbg. Aby uzyskać więcej informacji na temat serwera GDBServer, zobacz https://en.wikipedia.org/wiki/Gdbserver. Jedną z miejsc do wyświetlenia dokumentacji zdalnego debugowania bazy danych gdb jest tutaj — https://sourceware.org/gdb/current/onlinedocs/gdb#Remote-Debugging

Aby uzyskać więcej informacji na temat korzystania z GDBServer z WinDbg oraz przeglądu kodu, zobacz debugowanie zdalnych procesów na żywo w systemie Linux . W tym przykładzie użyto systemu Ubuntu działającego w ramach podsystemu Windows dla systemu Linux (WSL), ale mogą być również używane inne implementacje systemu Linux.

Implementacja DWARF

Symbole DWARF są obsługiwane jako osadzone w oryginalnym obrazie (binaria debugowania) lub wyeksportowane do oddzielnego obrazu ELF (pakiet debugowania).

Aby przechodzenie stosu DWARF w systemie Linux zakończyło się pomyślnie, oryginalny plik wykonywalny dowolnego modułu załadowanego do procesu systemu Linux musi być odnaleziony.

Symbole DWARF/obrazy ELF (usunięte lub nie) można znaleźć za pośrednictwem ścieżki symboli debugera lub serwera symboli (indeksowane zgodnie z .NET Core poprzez skrót identyfikatora kompilacji GNU).

Symbole DWARF można znaleźć, instalując pakiet debugowania w stylu Linux. Jest to określone przez katalog o nazwie .build-id w ścieżce symboli. Poniżej znajdują się katalogi nazwane zgodnie z pierwszym bajtem skrótu identyfikatora kompilacji GNU. W każdym takim katalogu znajduje się plik o nazwie <remaining 18 bytes of GNU Build ID hash>.debug.

Gdy debuger otwiera symbole DWARF, wykonuje początkowy krok indeksowania, ponieważ sam format nie zawiera niezbędnych tabel wyszukiwania. W przypadku dużych zestawów symboli DWARF (prywatnych danych DWARF dla jądra systemu Linux) może to potrwać od 10 do 30 sekund.

!addsourcemap dla automatycznego pobierania źródła z znanego repozytorium / commitu

Jeśli debugujesz składniki utworzone na podstawie znanego repozytorium i zatwierdzenia, istnieje rozszerzenie, !addsourcemap, które za pomocą polecenia debugera umożliwia wskazanie, że dla danego modułu i ścieżki chcesz automatycznie pobrać źródła ze znanego adresu URL. Użycie rozszerzenia jest następujące:

!addsourcemap <module> <local spec> <remote spec>

Gdzie:

<module> jest nazwą interesującego modułu.

<local spec> to ścieżka źródeł w ramach tego modułu, która zostanie wyszukana za pośrednictwem adresu URL. Ta ścieżka powinna kończyć się symbolem wieloznacznym.

<remote spec> to adres URL, pod którym będą wyszukiwane pliki zgodne z <local spec>. Ta ścieżka powinna kończyć się symbolem wieloznacznym, który zostanie zastąpiony zgodnie z tym, jak symbol wieloznaczny w <local spec> dopasowuje się do określonej ścieżki źródłowej.

Aby ustawić mapę źródłową, upewnij się, że moduł jest obecny, używając lm (List Loaded Modules). Następnie określ zdalną lokalizację źródła.

W tym przykładzie moduł vmlinux jest ustawiany na określoną kompilację dostępną w usłudze GitHub.

0:000> !addsourcemap vmlinux /build/linux/* https://raw.githubusercontent.com/torvalds/linux/6e61dde82e8bfe65e8ebbe43da45e615bc529236/
Source map /build/linux/* -> https://raw.githubusercontent.com/torvalds/linux/6e61dde82e8bfe65e8ebbe43da45e615bc529236/ successfully added

Po wydaniu polecenia sourcemap, pewne działania wyzwolą ładowanie źródła, na przykład przełączanie ramek w tę i z powrotem lub ponowne ładowanie przy użyciu polecenia .reload. Następnie nastąpi automatyczne ściąganie źródła z usługi GitHub.

!sourcemaps (mapy źródłowe)

Użyj polecenia !sourcemaps, aby wyświetlić listę istniejących map źródłowych.

0:000> !sourcemaps
Source maps for vmlinux.6:
    /build/linux/* -> https://raw.githubusercontent.com/torvalds/linux/6e61dde82e8bfe65e8ebbe43da45e615bc529236/

!removesourcemaps

Użyj polecenia !removesourcemaps, aby usunąć istniejącą mapę źródłową.

0:000> !removesourcemaps vmlinux /build/linux/* https://raw.githubusercontent.com/torvalds/linux/6e61dde82e8bfe65e8ebbe43da45e615bc529236/
1 source maps successfully removed

Rozwiązywanie problemów z symbolami DWARF

Jeśli debugujesz zrzuty systemu Linux/Android (lub inne obiekty docelowe używające symboli DWARF), warto przyjrzeć się nieprzetworzonej zawartości symboli, aby zrozumieć, dlaczego zmienne lokalne, definicje typów lub definicje funkcji są nieprawidłowe. Aby to zrobić, debuger ma wbudowane polecenia rozszerzeń do zrzucania surowych treści symboli DWARF. Ponadto użyj narzędzi systemu Linux, takich jak readelf, i dumpdwarf, aby wyświetlić informacje o wewnętrznych symbolach.

polecenie readelf

Użyj polecenia readelf w wierszu polecenia systemu Linux, aby wyświetlić identyfikator kompilacji debugowania utworzony dla przykładowego programu DisplayGreeting w Linux live zdalnego debugowania procesów. W tym przykładzie zwracany jest identyfikator kompilacji aba822dd158b997b09903d4165f3dbfd37f5e5c1.

Bob@BOB6:/mnt/c/Users/Bob$ readelf -n DisplayGreeting

Displaying notes found in: .note.gnu.property
  Owner                Data size        Description
  GNU                  0x00000020       NT_GNU_PROPERTY_TYPE_0
      Properties: x86 feature: IBT, SHSTK
        x86 ISA needed: x86-64-baseline

Displaying notes found in: .note.gnu.build-id
  Owner                Data size        Description
  GNU                  0x00000014       NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: aba822dd158b997b09903d4165f3dbfd37f5e5c1

Displaying notes found in: .note.ABI-tag
  Owner                Data size        Description
  GNU                  0x00000010       NT_GNU_ABI_TAG (ABI version tag)
    OS: Linux, ABI: 3.2.0

Readelf może być używany z komendą grep, aby zwrócić wersję symbolu.

 readelf --debug-dump=info DisplayGreeting | grep -A 2 'Compilation Unit @'
  Compilation Unit @ offset 0x0:
   Length:        0x285c (32-bit)
   Version:       5

dwarfdump

Polecenie dwarfdump linux drukuje lub sprawdza sekcje DWARF zgodnie z żądaniem określonych opcji. Użyj dwarfdump -h, aby wyświetlić wiele opcji.

bob@BOB6:/mnt/c/Users/BOB$ dwarfdump -h

Aby uzyskać więcej informacji na temat korzystania z dwarfdump w Ubuntu, zobacz dwarfdump .

!diesym

To polecenie debugera wyświetli DIE (lub poddrzewo DIE) dla każdego symbolu znajdującego się w danym wyrażeniu (może być adresem, nazwą funkcji itp.) z możliwym do zdefiniowania poziomem rekurencji. Lokalizuje DIE dla symbolu (zazwyczaj funkcji, ale może to być również dane itp.) zawartego pod danym adresem i wykonuje diagnostyczny zrzut DIE, podobny do uruchomienia dwarfdump lub llvm-dwarfdump na symbolach i znalezienia DIE.

!diesym [options] <expression>

-r#: zrzut N poziomów rekursywnie. Zwykle jest to jeden i tylko sam DIE jest po cenach dumpingowych.

<expression> — adres do zlokalizowania DIE jest podawany za pomocą wyrażenia. Może to być prosty adres szesnastkowy (0x<blah>) lub może być unikatową nazwą funkcji.

Musi ona zostać ewaluowana przez standardową ocenę modelu danych. Użyj polecenia dx, aby zweryfikować poprawność wyrażenia modelu. Aby uzyskać więcej informacji na temat używania polecenia dx, zobacz dx (Display Debugger Object Model Expression).

0:000> dx DisplayGreeting!GetCppConGreeting
DisplayGreeting!GetCppConGreeting                 : DisplayGreeting!GetCppConGreeting+0x0 [Type: GetCppConGreeting]

Wyświetl informacje o symbolach DIE dla przykładowego programu DisplayGreeting i funkcji GetCppConGreeting.

0:000> !diesym DisplayGreeting!GetCppConGreeting
0x2816: DW_TAG_subprogram [^^^]
    DW_AT_external          (true)
    DW_AT_name              'GetCppConGreeting'
    DW_AT_decl_file         1 ('/mnt/c/Users/BOB/DisplayGreeting.cpp')
    DW_AT_decl_line         0x7
    DW_AT_decl_column       0x6
    DW_AT_linkage_name      '_Z17GetCppConGreetingPwm'
    DW_AT_low_pc            0x11E9
    DW_AT_high_pc           +0x3c (== 0x1225)
    DW_AT_frame_base        DW_OP_call_frame_cfa 
    DW_AT_call_all_tail_calls   (true)

Użyj opcji -r2, aby wyświetlić dodatkowy poziom informacji o symbolach DIE.

0:000> !diesym -r2 DisplayGreeting!GetCppConGreeting
0x2816: DW_TAG_subprogram [^^^]
    DW_AT_external          (true)
    DW_AT_name              'GetCppConGreeting'
    DW_AT_decl_file         1 ('/mnt/c/Users/BOB/DisplayGreeting.cpp')
    DW_AT_decl_line         0x7
    DW_AT_decl_column       0x6
    DW_AT_linkage_name      '_Z17GetCppConGreetingPwm'
    DW_AT_low_pc            0x11E9
    DW_AT_high_pc           +0x3c (== 0x1225)
    DW_AT_frame_base        DW_OP_call_frame_cfa 
    DW_AT_call_all_tail_calls   (true)

    0x2834: DW_TAG_formal_parameter [^^^]
        DW_AT_name              'buffer'
        DW_AT_decl_file         1 ('/mnt/c/Users/BOB/DisplayGreeting.cpp')
        DW_AT_decl_line         0x7
        DW_AT_decl_column       0x21
        DW_AT_type              (CU + 0x12f7 == 0x12f7)
        DW_AT_location          DW_OP_fbreg(-40) 

!umrzyj

!die wyświetli DIE (lub poddrzewo DIE) dla dowolnego DIE w danym wyrażeniu przesunięcia w sekcji debugowania DWARF z opcjonalnie określonym poziomem rekursji.

!die [-r#] [-t] -m <module base expression> <offset expression>

-r#: zrzut N poziomów rekursywnie.

-t: Jeśli DIE znajduje się w jednostce typu w .debug_types zamiast w jednostce kompilacji w .debug_info, należy określić przełącznik -t.

Podaj -m <module base expression>, który daje podstawowy adres dowolnego modułu, którego dotyczy zapytanie.

<offset expression> oznacza wielkość przesunięcia DIE.

Na wierszu poleceń systemu Linux użyj narzędzia dwarfdump z -r, aby wyświetlić sekcję .debug_aranges pliku DWARF w celu zlokalizowania przesunięcia DIE.

bob@BOB6:/mnt/c/Users/BOB$ dwarfdump -r DisplayGreeting

.debug_aranges

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000c>  DW_TAG_compile_unit
                    DW_AT_producer              GNU C++17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
                    DW_AT_language              DW_LANG_C_plus_plus_14
                    DW_AT_name                  DisplayGreeting.cpp
                    DW_AT_comp_dir              /mnt/c/Users/BOB
                    DW_AT_ranges                0x0000000c

      Offset of rnglists entries: 0x0000000c
      [ 0] start,end             0x000011e9 0x0000134a
      [ 1] start,end             0x0000134a 0x00001368
      [ 2] start,end             0x00001368 0x0000137b
      [ 3] start,end             0x0000137b 0x0000138d
      [ 4] end of list
                    DW_AT_low_pc                0x00000000
                    DW_AT_stmt_list             0x00000000


arange starts at 0x000011e9, length of 0x00000161, cu_die_offset = 0x0000000c
arange starts at 0x0000134a, length of 0x0000001e, cu_die_offset = 0x0000000c
arange starts at 0x00001368, length of 0x00000013, cu_die_offset = 0x0000000c
arange starts at 0x0000137b, length of 0x00000012, cu_die_offset = 0x0000000c

Zanotuj wartość 0x0000000cdla DW_AT_ranges. W debugerze użyj tej wartości przesunięcia i nazwy modułu DisplayGreeting, aby wyświetlić informacje o symbolu DIE.

0:000> !die -m DisplayGreeting 0x0000000c
0xc: DW_TAG_compile_unit [^^^]
    DW_AT_producer          'GNU C++17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection'
    DW_AT_language          0x21
    DW_AT_name              
    DW_AT_comp_dir          
    DW_AT_ranges            
        [0x11e9 - 0x134a)
        [0x134a - 0x1368)
        [0x1368 - 0x137b)
        [0x137b - 0x138d)
    DW_AT_low_pc            0x0
    DW_AT_stmt_list        

!dieancestry

Polecenie !dieancestry działa podobnie do !die z tą różnicą, że przechodzi drzewo DIE w kierunku zawierającej kompilacji lub jednostki typu, a nie w dół drzewa.

!dieancestry [-r#] [-t] -m <module base expression> <offset expression>

-r#: zrzut N poziomów rekursywnie.

Podaj -m <module base expression>, który daje podstawowy adres dowolnego modułu, którego dotyczy zapytanie.

<offset expression> oznacza wielkość przesunięcia DIE.

Przykład:

0:000> !dieancestry -m DisplayGreeting 0x0000000c
0xc: DW_TAG_compile_unit [^^^]
    DW_AT_producer          'GNU C++17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection'
    DW_AT_language          0x21
    DW_AT_name              
    DW_AT_comp_dir          
    DW_AT_ranges            
        [0x11e9 - 0x134a)
        [0x134a - 0x1368)
        [0x1368 - 0x137b)
        [0x137b - 0x138d)
    DW_AT_low_pc            0x0
    DW_AT_stmt_list       

Należy pamiętać, że linki, na przykład do rodziców lub rodzeństwa, można kliknąć, aby umożliwić dalsze przechodzenie drzewa symboli DWARF.

0:000> !die -r2 -m 0x555555554000 0xc
0xc: DW_TAG_compile_unit [^^^]
    DW_AT_producer          'GNU C++17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection'
    DW_AT_language          0x21
    DW_AT_name              
    DW_AT_comp_dir          
    DW_AT_ranges            
        [0x11e9 - 0x134a)
        [0x134a - 0x1368)
        [0x1368 - 0x137b)
        [0x137b - 0x138d)
    DW_AT_low_pc            0x0
    DW_AT_stmt_list         

    0x2a: DW_TAG_namespace [^^^]
        DW_AT_name              'std'
        DW_AT_decl_file         9 ('/usr/include/c++/11/bits/exception_ptr.h')
        DW_AT_decl_line         0x116
        DW_AT_decl_column       0xb
        DW_AT_sibling           (CU + 0xf01 == 0xf01)

    0xf01: DW_TAG_base_type [^^^]
        DW_AT_byte_size         0x1
        DW_AT_encoding          DW_ATE_boolean (2)
        DW_AT_name              'bool'

    0xf08: DW_TAG_base_type [^^^]
        DW_AT_byte_size         0x8
        DW_AT_encoding          DW_ATE_unsigned (7)
        DW_AT_name              'long unsigned int'

...
   

Nie wszystkie dane wyjściowe są wyświetlane.

!dwunwind

!dwunwind jest nieco podobna do .fnent (Wyświetlanie danych funkcji) dla obrazów PE. Wyświetla reguły odwujności DWARF dla adresu podanego przez wyrażenie. Jest on również podobny do readelf --unwind polecenia, który wyświetla informacje odwijane, gdy jest dostępny.

!dwunwind <expression>

W tym przykładzie przedstawiono reguły zwijania dla funkcji GetCppConGreeting w programie DisplayGreeting.

0:000> !dwunwind DisplayGreeting!GetCppConGreeting
DW_FRAME_SAME_VAL: 0('rax'), 1('rdx'), 2('rcx'), 3('rbx'), 4('rsi'), 5('rdi'), 6('rbp'), 7('rsp'), 8('r8'), 9('r9'), 10('r10'), 11('r11'), 12('r12'), 13('r13'), 14('r14'), 15('r15')
0('CFA'): DW_EXPR_OFFSET 7('rsp') + 8
16('<Return Address>'): DW_EXPR_OFFSET 12290('CFA') + -8

Spowoduje to wyświetlenie stosu rozwijającego dla rejestru wskaźnika instrukcji.

0:000> !dwunwind @rip
DW_FRAME_SAME_VAL: 0('rax'), 1('rdx'), 2('rcx'), 4('rsi'), 5('rdi'), 7('rsp'), 8('r8'), 9('r9'), 10('r10'), 11('r11'), 14('r14'), 15('r15')
0('CFA'): DW_EXPR_OFFSET 7('rsp') + 208
3('rbx'): DW_EXPR_OFFSET 12290('CFA') + -40
6('rbp'): DW_EXPR_OFFSET 12290('CFA') + -32
12('r12'): DW_EXPR_OFFSET 12290('CFA') + -24
13('r13'): DW_EXPR_OFFSET 12290('CFA') + -16
16('<Return Address>'): DW_EXPR_OFFSET 12290('CFA') + -8

Oto przykład licznika programu.

   0:000> !dwunwind @pc
   DW_FRAME_SAME_VAL: 0('x0'), 1('x1'), 2('x2'), 3('x3'), 4('x4'), 5('x5'), 6('x6'), 7('x7'), 8('x8'), 9('x9'), 10('x10'), 11('x11'), 12('x12'), 13('x13'), 14('x14'), 15('x15'), 16('x16'), 17('x17'), 18('x18'), 31('sp'), 32('pc')
   0('CFA'): DW_EXPR_OFFSET 31('sp') + 208
   19('x19'): DW_EXPR_OFFSET 1436('CFA') + -192
   20('x20'): DW_EXPR_OFFSET 1436('CFA') + -184
   21('x21'): DW_EXPR_OFFSET 1436('CFA') + -176
   22('x22'): DW_EXPR_OFFSET 1436('CFA') + -168
   23('x23'): DW_EXPR_OFFSET 1436('CFA') + -160
   24('x24'): DW_EXPR_OFFSET 1436('CFA') + -152
   25('x25'): DW_EXPR_OFFSET 1436('CFA') + -144
   26('x26'): DW_EXPR_OFFSET 1436('CFA') + -136
   27('x27'): DW_EXPR_OFFSET 1436('CFA') + -128
   28('x28'): DW_EXPR_OFFSET 1436('CFA') + -120
   29('fp'): DW_EXPR_OFFSET 1436('CFA') + -208
   30('lr'): DW_EXPR_OFFSET 1436('CFA') + -200

!dietree

Tworzy zrzut drzewa DIE dla danego modułu na określonym poziomie rekurencji, podobne do działania narzędzia dwarfdump lub llvm-dwarfdump na symbolach w celu znalezienia DIE.

!dietree [OPTIONS] -m <module base> <offset expression>

-r#: Określ poziom rekursji

-t: Zrzuć .debug_types, a nie .debug_info

Baza modułu dla modułu zawierającego DIE musi być podana opcją -m <expression>.

<offset expression> oznacza wielkość przesunięcia DIE.

Przykład:

0:000> !dietree -m DisplayGreeting 0x0000000c
0xc: DW_TAG_compile_unit [^^^]
    DW_AT_producer          'GNU C++17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection'
    DW_AT_language          0x21
    DW_AT_name              
    DW_AT_comp_dir          
    DW_AT_ranges            
        [0x11e9 - 0x134a)
        [0x134a - 0x1368)
        [0x1368 - 0x137b)
        [0x137b - 0x138d)
    DW_AT_low_pc            0x0
    DW_AT_stmt_list  

Użyj opcji -r2, aby wyświetlić dodatkowe wartości w dietree.

0:000> !dietree -r2 -m DisplayGreeting 0x0000000c
0xc: DW_TAG_compile_unit [^^^]
    DW_AT_producer          'GNU C++17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection'
    DW_AT_language          0x21
    DW_AT_name              
    DW_AT_comp_dir          
    DW_AT_ranges            
        [0x11e9 - 0x134a)
        [0x134a - 0x1368)
        [0x1368 - 0x137b)
        [0x137b - 0x138d)
    DW_AT_low_pc            0x0
    DW_AT_stmt_list         

    0x2a: DW_TAG_namespace [^^^]
        DW_AT_name              'std'
        DW_AT_decl_file         9 ('/usr/include/c++/11/bits/exception_ptr.h')
        DW_AT_decl_line         0x116
        DW_AT_decl_column       0xb
        DW_AT_sibling           (CU + 0xf01 == 0xf01)

    0xf01: DW_TAG_base_type [^^^]
        DW_AT_byte_size         0x1
        DW_AT_encoding          DW_ATE_boolean (2)
        DW_AT_name              'bool'

    0xf08: DW_TAG_base_type [^^^]
        DW_AT_byte_size         0x8
        DW_AT_encoding          DW_ATE_unsigned (7)
        DW_AT_name              'long unsigned int'

    0xf0f: DW_TAG_base_type [^^^]
        DW_AT_byte_size         0x1
        DW_AT_encoding          DW_ATE_unsigned_char (8)
        DW_AT_name              'unsigned char'

...

Nie wszystkie dane wyjściowe są wyświetlane. Należy pamiętać, że linki, na przykład do rodzeństwa, można kliknąć, aby pozwolić na dalsze przechodzenie drzewa symboli DWARF.

!dielocal

Lokalizuje DIE dla zmiennej lokalnej o nazwie "name" i wykonuje zrzut diagnostyczny DIE podobny do uruchomienia narzędzi dwarfdump lub llvm-dwarfdump na symbolach w celu znalezienia DIE.

!dielocal [options] <name>

-r#: zrzut N poziomów rekursywnie. Zwykle jest to jeden i tylko sam DIE jest po cenach dumpingowych.

<name> : zmienna lokalna o nazwie "name".

Przykład:

0:000> !dielocal greeting
0x2806: DW_TAG_variable [^^^]
    DW_AT_name              'greeting'
    DW_AT_decl_file         1 ('/mnt/c/Users/BOB/DisplayGreeting.cpp')
    DW_AT_decl_line         0xf
    DW_AT_decl_column       0x1d
    DW_AT_type              (CU + 0xb18 == 0xb18)
    DW_AT_location          DW_OP_fbreg(-240) 

Zobacz też

Rozszerzony dostęp do kodu źródłowego

ELFUTILS DEBUGINFOD

DWARF Wersja 5

przy użyciu symboli

!sym

zrzuty awaryjne systemu Linux

debugowanie procesów zdalnych systemu Linux