Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här artikeln beskrivs hur du upprättar en WinDbg-live-anslutning till Linux. Direkt fjärrprocessfelsökning i Linux kräver WinDbg version 1.2402.24001.0 eller senare.
GNU Debugger – GDBServer, används i Linux för att stödja WinDbg-anslutningen. Mer information om GDBServer finns i https://en.wikipedia.org/wiki/Gdbserver. En plats där du kan visa dokumentationen för gdb-fjärrfelsökning finns här – https://sourceware.org/gdb/current/onlinedocs/gdb#Remote-Debugging
Exemplen här använder Windows-undersystemet för Linux (WSL), men andra Linux-implementeringar kan också användas.
WinDbg-typer av fjärrprocessfelsökning
Det finns två primära metoder för att utföra fjärrfelsökning med WinDbg – en processserver eller en KD-anslutningsserver. Processservrar används för felsökning i användarläge. KD-anslutningsservrar används för felsökning i kernelläge. Se Processservrar (användarläge) och KD-anslutningsservrar (kernelläge) för allmän information om dessa WinDbg-anslutningstyper.
Det finns två sätt att börja felsöka processer i Linux-användarläge. Du kan antingen starta gdbserver på en viss process eller starta gdbserver som en processserver som kan lista och koppla till befintliga processer. Detta är ungefär som DbgSrv (dbgsrv.exe) processervern i Windows. Mer information finns i Aktivera en processserver.
Felsökning av Linux-process i användarläge
Det går att ansluta till en specifik process för en enskild användare, eller i flera lägen, för att se hela processen i en lista och välja en att ansluta till. Båda metoderna beskrivs i det här avsnittet. Båda metoderna delar samma anslutningssträngssyntax, som beskrivs härnäst.
Format för gdbserver-anslutningssträng
Det format som används för att ansluta till gdbserver är "protocol:arguments" där argument är en kommaavgränsad lista med "argument=value". För en gdbserver-anslutning i användarläge är protokollet gdb och argumentuppsättningen är följande.
              server=<address> – Obligatoriskt: anger IP-adressen för den gdbserver som ska anslutas till.
              port=<port> – Obligatoriskt: anger portnumret för den gdbserver som ska anslutas till.
              threadEvents=<true|false> – Valfritt: anger om trådhändelser för den här versionen av gdbserver fungerar korrekt i stoppläge.
Det finns ett problem i de aktuella gdbserver-versionerna, där aktivering av trådhändelser med en server i stoppläge (som WinDbg använder) gör att gdbserver kraschar. Om det här värdet är falskt (standardvärdet) syntetiseras trådstarts- och stopphändelser men kan visas betydligt senare än den faktiska tiden då tråden skapades/förstördes. När en korrigering för detta är tillgänglig i gdbserver kan de faktiska händelserna aktiveras via det här alternativet.
Ansluta till en process i enkelt användarläge
I det här avsnittet beskrivs hur du identifierar och ansluter till en process i enkelt användarläge i Linux med WinDbg.
WSL (Windows-undersystem för Linux)
Exemplen här använder WSL (Windows-undersystem för Linux), men andra Linux-implementeringar kan användas. Information om hur du konfigurerar och använder WSL finns i:
- Så här installerar du Linux i Windows med WSL
 - Konfigurera en WSL-utvecklingsmiljö
 - Åtkomst till nätverksprogram med WSL
 - Intune-inställningar för WSL
 
Välj önskad process
Visa en lista över processer i Linux med hjälp av ps -A kommandot för att fastställa vilken process som körs att ansluta till.
user1@USER1:/mnt/c/Users/USER1$ ps -A
    PID TTY          TIME CMD
    458 pts/1    00:00:00 bash
    460 ?        00:00:00 rtkit-daemon
    470 ?        00:00:00 dbus-daemon
    482 ?        00:00:19 python3
   1076 ?        00:00:00 packagekitd
   1196 pts/0    00:00:00 ps
I den här exempelgenomgången ansluter vi till python3.
Leta upp målsystemets IP-adress
Om du ansluter till ett linux-fjärrmål använder du ett kommando som till exempel ip route showför att fastställa den externa IP-adressen.
user1@USER1:/mnt/c/Users/USER1$ ip route show
default via 192.168.1.1 dev enp3s0 proto dhcp metric 100
172.25.144.0/24 dev enp3s0 proto kernel scope link src 192.168.1.107 metric 100
I den här genomgången ansluter vi till WSL som körs på samma dator och använder IP-adressen för localhost.
Koppla GDBServer till den valda processen
I WSL Linux-konsolen anger du gdbserver localhost:1234 python3 för att starta gdbservern på port 1234 och koppla den till python3-processen.
USER1@USER1:/mnt/c/Users/USER1$ gdbserver localhost:1234 python3
Process python3 created; pid = 1211
Listening on port 1234
För vissa Linux-miljöer kan kommandot behöva köras som administratör, till exempel med sudo – sudo gdbserver localhost:1234 python3. Var försiktig med att aktivera åtkomst på rotnivå för felsökningsadministratören och använd endast detta när det behövs.
Skapa processserveranslutningen i WinDbg
Öppna WinDbg och välj "Arkiv/Anslut till fjärrfelsökare" och ange en protokollsträng för anslutningen. I det här exemplet använder vi: gdb:server=localhost,port=1234.
              
              
            
När du klickar på OK-knappen ska felsökaren ansluta till gdbservern och du bör vara vid den första startpausen för processen.
När du är vid den första brytpunkten kan du trycka på "g" flera gånger. Du får modulinläsningsmeddelanden (och händelser av sxe-typen "bryt vid modulinläsning" bör fungera korrekt).
Observera att det kan ta en stund att komma till den punkten, eftersom felsökningssymboler läses in i cacheminnet. Förutom att söka efter symboler och binärfiler via symbolservern eller din lokala sökväg har GDBServer-integreringen möjlighet att hämta dessa filer från fjärrfilsystemet om de inte kan hittas via symsrv eller lokalt. Detta är vanligtvis en mycket långsammare åtgärd än att få symboler från symsrv eller en lokal sökväg, men det gör den övergripande upplevelsen bättre genom att hitta lämpliga symboler.
Använd kommandot k stacks för att visa en lista över stacken. Den visar python3-moduler, så detta bekräftar att vi felsöker Python3 i Linux med WinDbg.
0:000> k
 # Child-SP          RetAddr               Call Site
00 00007fff`ffffce10 00007fff`f786d515     libc_so!_select+0xbd
01 00007fff`ffffce80 00005555`55601ce8     readline_cpython_310_x86_64_linux_gnu!PyInit_readline+0xac5
02 00007fff`ffffcf60 00005555`556f06a1     python3!PyOS_Readline+0x109
03 00007fff`ffffcfa0 00005555`556eee7e     python3!PyFrame_LocalsToFast+0x62a1
04 00007fff`ffffd000 00005555`556edcf0     python3!PyFrame_LocalsToFast+0x4a7e
05 00007fff`ffffdb80 00005555`557a18e9     python3!PyFrame_LocalsToFast+0x38f0
06 00007fff`ffffdc00 00005555`557a1470     python3!PyCodec_LookupError+0xb09
07 00007fff`ffffdc50 00005555`557b89dc     python3!PyCodec_LookupError+0x690
08 00007fff`ffffdc70 00005555`5560b42f     python3!PyUnicode_Tailmatch+0xc6c
09 00007fff`ffffdcb0 00005555`5560b012     python3!PyRun_InteractiveLoopObject+0x4e0
0a 00007fff`ffffdd50 00005555`557b7678     python3!PyRun_InteractiveLoopObject+0xc3
0b 00007fff`ffffdda0 00005555`555f55c8     python3!PyRun_AnyFileObject+0x68
0c 00007fff`ffffddd0 00005555`555ea6e8     python3!PyRun_AnyFileExFlags+0x4f
0d 00007fff`ffffde00 00005555`55780cad     python3!Py_str_to_int+0x2342a
0e 00007fff`ffffdef0 00007fff`f7c7cd90     python3!Py_BytesMain+0x2d
0f 00007fff`ffffdf20 00007fff`f7c7ce40     libc_so!_libc_init_first+0x90
10 00007fff`ffffdfc0 00005555`55780ba5     libc_so!_libc_start_main+0x80
11 00007fff`ffffe010 ffffffff`ffffffff     python3!start+0x25
12 00007fff`ffffe018 00000000`00000000     0xffffffff`ffffffff
I det här läget bör du kunna göra nästan allt som kan göras med WinDbg som är anslutet till ett fjärranslutet Windows-felsökningsprogram via en fjärrprocessserver. Du kan stega igenom, felsöka på källkodenivå, ange brytpunkter, inspektera lokala variabler, osv.
När du är klar med felsökningen använder du CTRL+D för att avsluta gbdserverfönstret i WSL.
Ansluta till en processserver
Förutom att ansluta till en enda process via en GDBServer i användarläge kan du konfigurera en som en processserver och lista och ansluta till befintliga processer i systemet. För att göra detta startas gdbserver med kommandoradsargumentet "--multi" - gdbserver --multi localhost:1234
user1@USER1:/mnt/c/Users/USER1$ sudo gdbserver --multi localhost:1234
Listening on port 1234
Om du vill ansluta till processervern väljer du "File/Connect to process server" i WinDbg och anger samma protokollsträng som du gjorde med gdbserverexemplet för en enda process ovan:
gdb:server=localhost,port=1234
När du klickar på knappen "OK" bör du vara ansluten till gdbservern som en processserver. Precis som med dbgsrv kan du antingen skapa en ny process eller så kan du lista de befintliga processerna och koppla till en.
I det här exemplet använder du alternativet "Bifoga för att bearbeta".
              
              
            
Observera att du ser många av samma saker som visas för Windows-processer (inklusive PID, användare och kommandorad). Vissa av kolumnerna i dialogrutan "bifoga till process" är inte relevanta för Linux och kommer inte att innehålla data.
Avsluta sessionen
Använd CTRL +D för att avsluta gbdserverfönstret i WSL och välj Stoppa felsökning i WinDbg. För att avsluta sessionen kan du i vissa fall behöva avsluta felsökningsprogrammet.
Återansluter till processervern
WinDbg identifierar en "processserver" jämfört med ett "enskilt mål" via om gdbservern är kopplad till en process eller inte. Om du ansluter till någon process lämnar du den låst, stänger felsökningsprogrammet och försöker återansluta till processervern, med all sannolikhet kommer vi inte att känna igen den som en processserver. I det här fallet, starta om den riktade gdbservern och återanslut debuggern.
Linux WinDbg-funktionalitet
Även om mycket av funktionerna i felsökningsprogrammet fungerar som förväntat i felsökning av kärndumpar (t.ex. stackvandring, symboler, typinformation, lokala variabler, demontering osv.) är det viktigt att notera att hela felsökningsverktyget inte har gjorts medveten om ELF, DWARF och de resulterande skillnaderna från Windows-semantik. Vissa kommandon i felsökningsprogrammet kan för närvarande resultera i oväntade utdata. Till exempel, lm kommer fortfarande att visa felaktig information för en ELF-modul eftersom den förväntar sig PE-huvuden och parsar dem manuellt.
Linux Kernel-läge via EXDI
Windows-felsökningsprogrammet stöder kernelfelsökning med hjälp av EXDI. På så sätt kan du felsöka en mängd olika maskinvaru- och operativsystem. Allmän information om hur du konfigurerar och felsöker EXDI-anslutningar finns i Konfigurera EXDI-felsökningsprogrammets transport.
Information om hur du konfigurerar QEMU-Kernel-Mode felsökning med EXDI finns i Konfigurera QEMU-Kernel-Mode felsökning med EXDI.
Linux-symboler och -källor
I det här avsnittet beskrivs grundläggande användning och tillgänglighet för Linux-symboler. Mer detaljerad information finns i Linux-symboler och -källor och Källkod utökad åtkomst.
DebugInfoD-symbolservrar
Från och med WinDbg version 1.2104 stöder källsökvägskommandot (.srcpath, .lsrcpath (Ange källsökväg)) filhämtning från DebugInfoD-servrar via taggen DebugInfoD* .
Taggen DebugInfoD* kan peka på en eller flera DebugInfoD-servrar med varje server-URL formaterad som https://domain.com och avgränsad med *. Servrarna genomsöks i samma ordning som i källsökvägen och filerna hämtas från den första matchande URL:en. För mer information, se Källkodens utökade åtkomst.
Du kan till exempel använda kommandot .sympath (Ange symbolsökväg) för att ange en DebugInfoD-sökväg som den här.
.sympath+ DebugInfoD*https://debuginfod.elfutils.org
Allmän information om hur du anger symbolsökvägen finns i Använda symboler.
Om du vill visa information om symboler som läses in använder du !sym noisy. Mer information finns i !sym.
Det stöds också automatisk nedladdning av källor från DebugInfoD-servrar som har stöd för att returnera den artefakttypen. Du kan i huvudsak göra:
.srcpath+ DebugInfoD*https://debuginfod.elfutils.org
Mer information om hur du arbetar med DWARF-symboler och Linux-symbolverktyg, till exempel !sourcemap och !diesym, finns i Linux-symboler och -källor.
Genomgång av C++-app
- Använd en textredigerare (t.ex. nano eller vi) för att skapa C++-filen. Till exempel:
 
nano DisplayGreeting.cpp
- Skriv C++-programmet i textredigeraren. Här är ett enkelt program som visar hälsningar, som måste avlusas:
 
#include <array>
#include <cwchar>
#include <cstdio>
#include <iostream>
using namespace std;
void GetCppConGreeting(wchar_t* buffer, size_t size)
{
    wchar_t const* const message = L"HELLO FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YOUR TIME TRAVEL DEBUGGING!";
    wcsncpy(buffer, message, size);
}
int main()
{
    std::array<wchar_t, 50> greeting{};
    GetCppConGreeting(greeting.data(), greeting.size());
    cin.get();
    wprintf(L"%ls\n", greeting.data());
    return 0;
}
Spara (CTRL-O) och avsluta (CTRL-X) nanoredigeraren.
Kompilera C++-filen med hjälp av g++. Alternativet -o används för att ange namnet på utdatafilen och alternativet -g genererar en symbolfil:
g++ DisplayGreeting.cpp -g -o DisplayGreeting
Om det inte finns några fel i koden skapar kommandot g++ en körbar fil med namnet DisplayGreeting i katalogen.
Du kan köra programmet med följande kommando:
./DisplayGreeting
- När du trycker på returnyckeln visas meddelandet i appen. När du tittar på utdata verkar det som att hälsningen avkortas och att "????" visas istället.
 
HELLO FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YO????
Felsöka DisplayGreeting
- När koden är redo att köras kan vi starta appen med hjälp av gdbservern.
 
gdbserver localhost:1234 DisplayGreeting
Öppna WinDbg och välj "Arkiv/Anslut till fjärrfelsökare" och ange en protokollsträng för anslutningen. I det här exemplet använder vi:
gdb:server=localhost,port=1234.När anslutningen är etablerad bör utdata indikera att det lyssnar på port 1234 och att en fjärrfelsökningsanslutning har upprättats.
Bob@Bob6:/mnt/c/Users/bob$ gdbserver localhost:1234 DisplayGreeting
Process /mnt/c/Users/bob/DisplayGreeting created; pid = 725
Listening on port 1234
Remote debugging from host 127.0.0.1, port 47700
Som tidigare nämnts kan kommandot för vissa Linux-miljöer behöva köras som administratör, vanligtvis med sudo. Var försiktig med att aktivera åtkomst på rotnivå för felsökningsadministratören och använd endast detta när det behövs.
Lägg till käll- och symbolsökvägarna i felsökningssessionen
Om du vill ange brytpunkter och visa källkoden och variablerna anger du symbolerna och källsökvägen. Allmän information om hur du anger symbolsökvägen finns i Använda symboler.
Använd .sympath för att lägga till symbolsökvägen i felsökningssessionen. I det här exemplet körs koden på den här platsen i WSL Linux Ubuntu för en användare med namnet Bob.
\\wsl$\Ubuntu\mnt\c\Users\Bob\
I WSL mappar den här katalogen till Windows OS-platsen för: C:\Users\Bob\
De här två kommandona används alltså.
.sympath C:\Users\Bob\
.srcpath C:\Users\Bob\
Mer information om WSL-filsystemet finns i Filbehörigheter för WSL.
- Om du vill dra nytta av ytterligare Linux OS-symboler lägger du till DebugInfoD-symbolerna med hjälp av .sympath-platsen, så här.
 
.sympath+ DebugInfoD*https://debuginfod.elfutils.org
- Det stöds också automatisk nedladdning av källor från DebugInfoD-servrar som har stöd för att returnera den artefakttypen. Om du vill dra nytta av detta lägger du till elfutils-servern med hjälp av .srcpath.
 
.srcpath+ DebugInfoD*https://debuginfod.elfutils.org
Ange en brytpunkt
Ange en brytpunkt i huvudappen DisplayGreeting.
0:000> bp DisplayGreeting!main
0:000> bl
     0 e Disable Clear  00005555`55555225  [/mnt/c/Users/bob/DisplayGreeting.cpp @ 14]     0001 (0001)  0:**** DisplayGreeting!main
Använd kommandot eller menyalternativet Go för att starta om kodkörningen.
Läser in källkod
Använd kommandot .reload för att läsa in symbolerna igen.
              lm Använd kommandot för att bekräfta att vi kör Appen DisplayGreeting.
0:000> lm
start             end                 module name
00005555`55554000 00005555`55558140   DisplayGreeting T (service symbols: DWARF Private Symbols)        c:\users\bob\DisplayGreeting
00007fff`f7a54000 00007fff`f7a732e8   libgcc_s_so   (deferred)             
00007fff`f7a74000 00007fff`f7b5a108   libm_so    (deferred)             
00007fff`f7b5b000 00007fff`f7d82e50   libc_so  T (service symbols: DWARF Private Symbols)        C:\ProgramData\Dbg\sym\_.debug\elf-buildid-sym-a43bfc8428df6623cd498c9c0caeb91aec9be4f9\_.debug
00007fff`f7d83000 00007fff`f7fae8c0   libstdc___so   (deferred)             
00007fff`f7fc1000 00007fff`f7fc1000   linux_vdso_so   (deferred)             
00007fff`f7fc3000 00007fff`f7ffe2d8   ld_linux_x86_64_so T (service symbols: DWARF Private Symbols)        C:\ProgramData\Dbg\sym\_.debug\elf-buildid-sym-9718d3757f00d2366056830aae09698dbd35e32c\_.debug
När kommandot utlöser åtkomst till visningshälsningskoden visas det i WinDbg.
              
              
            
Använd kommandot "k" för att visa en lista över stacken.
0:000> k
 # Child-SP          RetAddr               Call Site
00 00007fff`ffffde00 00007fff`f7b84d90     DisplayGreeting!main+0x1f [/mnt/c/Users/BOB/DisplayGreeting.cpp @ 15] 
01 00007fff`ffffdef0 00007fff`f7b84e40     libc_so!__libc_start_call_main+0x80 [./csu/../sysdeps/x86/libc-start.c @ 58] 
02 00007fff`ffffdf90 00005555`55555125     libc_so!__libc_start_main_impl+0x80 [./csu/../sysdeps/nptl/libc_start_call_main.h @ 379] 
03 00007fff`ffffdfe0 ffffffff`ffffffff     DisplayGreeting!start+0x25
04 00007fff`ffffdfe8 00000000`00000000     0xffffffff`ffffffff```
Använd dx-kommandot för att visa den lokala variabelhälsningen. Observera att storleken är 50.
0:000> dx greeting
greeting                 : { size=50 } [Type: std::array<wchar_t, 50>]
    [<Raw View>]     [Type: std::array<wchar_t, 50>]
Titta igenom koden och observera att 50 kanske inte är tillräckligt stor för hälsningsmeddelandet.
wchar_t const* const message = L"HELLO FROM THE WINDBG TEAM. GOOD LUCK IN ALL OF YOUR TIME TRAVEL
Bekräfta detta genom att expandera variabeln locals för hälsningen och se att hälsningen trunkeras.
Felsöka gdbserver-anslutningen
Använd alternativet --debug för att visa ytterligare information om gdbserver-konsolen för att samla in mer information om anslutningsstatusen. Om du till exempel vill starta en processerver använder du det här kommandot.
gdbserver --debug --multi localhost:1234