Toolchain-ul GNU pentru arhitectura Cell BE conține, pe lângă o versiune a compilatorului GCC specifică acestei arhitecuri, și o versiune a GDB care poate fi folosită pentru a depana programe scrise pentru Cell BE. Toate funcțiile GDB sunt disponibile și pe arhitectura Cell BE.
GDB este disponibil sub numele de ppu-gdb
. Contrar numelui executabilului, se poate depana atât cod PPU cât și cod SPU.
Pentru exemplificare vom folosi următorul program, care conține mai multe bug-uri. Compilarea este făcută cu ajutorul makefile-urilor puse la dispoziție de SDK-ul Cell BE. Arhiva completă poate fi descărcată de aici.
Cod PPU | Cod SPU |
---|---|
|
|
Compilând, observăm ca în mod implicit este generat un program optimizat și fără debug symbols (-O3
). După cum se poate observa, acest program nu este foarte util pentru depanare, lipsind numele funcției, numărul liniei, valoarea parametrilor etc. din momentul producerii erorii.
[dan.dragomir@cell-qs22-1 gdb]$ make [...] /usr/bin/spu-gcc -W -Wall -Winline -I. -I /opt/cell/sdk/usr/spu/include -O3 -c spu_bugs.c [...] /usr/bin/ppu32-gcc -W -Wall -Winline -m32 -I. -I /opt/cell/sdk/usr/include -mabi=altivec -maltivec -O3 -c ppu_bugs.c [...] [dan.dragomir@cell-qs22-1 gdb]$ ppu-gdb ppu/ppu_bugs [...] (gdb) run Starting program: /export/home/acs/external/dan.dragomir/gdb/ppu/ppu_bugs [Thread debugging using libthread_db enabled] Program received signal SIGSEGV, Segmentation fault. 0x000001d8 in main () from spu_bugs@0x1801c00 <5>
În cazul folosirii makefile-urilor de compilare din SDK-ul Cell se poate defini variabila de mediu CC_OPT_LEVEL
pentru a modifica nivelul de optimizare. Vom atribui aceastei variabile flag-urile necesare pentru a genera un program neoptimizat (-O0
) și cu debug symbols (-g
). În cazul în care compilarea nu se face cu makefile-urile din SDK, aceleași flag-uri trebuie pasate totuși compilatorului prin mecanismul specific metodei de compilare folosite.
[dan.dragomir@cell-qs22-1 gdb]$ make clean [...] [dan.dragomir@cell-qs22-1 gdb]$ make CC_OPT_LEVEL="-O0 -g" [...] /usr/bin/spu-gcc -W -Wall -Winline -I. -I /opt/cell/sdk/usr/spu/include -O0 -g -c spu_bugs.c [...] /usr/bin/ppu32-gcc -W -Wall -Winline -m32 -I. -I /opt/cell/sdk/usr/include -mabi=altivec -maltivec -O0 -g -c ppu_bugs.c [dan.dragomir@cell-qs22-1 gdb]$ ppu-gdb ppu/ppu_bugs [...] (gdb) run Starting program: /export/home/acs/external/dan.dragomir/gdb/ppu/ppu_bugs [Thread debugging using libthread_db enabled] Program received signal SIGBUS, Bus error. 0x00000278 in main (speid=7798581337495727215, argp=6134033987286868041) at spu_bugs.c:26 26 mfc_waittag(0);
În momentul opririi programului putem folosi comenzile cunoscute pentru a inspecta starea acestuia:
(gdb) backtrace #0 0x00000278 in main (speid=7798581337495727215, argp=6134033987286868041) at spu_bugs.c:26 #1 0x00000094 in _start () from spu_bugs@0x1801c80 <5>
(gdb) list 21 22 sprintf(msg, "Cell GDB tutorial: hello from SPU " 23 "with ID %llx\n", speid); 24 25 mfc_put(msg, argp, sizeof(msg), 0, 0, 0); 26 mfc_waittag(0); 27 28 return 0; 29 } 30
(gdb) print argp $1 = 6134033987286868041 (gdb) print sizeof(msg) $2 = 16
(gdb) up #1 0x00000094 in _start () from spu_bugs@0x1801c80 <5> (gdb) down #0 0x00000278 in main (speid=7798581337495727215, argp=6134033987286868041) at spu_bugs.c:26 26 mfc_waittag(0); (gdb) frame 1 #1 0x00000094 in _start () from spu_bugs@0x1801c80 <5> (gdb) frame 0 #0 0x00000278 in main (speid=7798581337495727215, argp=6134033987286868041) at spu_bugs.c:26 26 mfc_waittag(0);
watch
, folosită de obicei pentru a cauza oprirea programului la modificarea unei variabile, nu folosește watchpoint-uri hardware în versiunea de GDB disponibilă curent. Din acest motiv funcționarea nu este neaparat cea așteptată. Ea realizează oprirea programului la modificarea variabilei, însă locația în care acesta este oprit nu corespunde instrucțiunii care a modificat-o.
Oprirea programului la prima instrucțiune din codul SPU se poate face cu set spu stop-on-load on
.
(gdb) set spu stop-on-load on (gdb) run Starting program: /export/home/acs/external/dan.dragomir/gdb/ppu/ppu_bugs [Thread debugging using libthread_db enabled] Temporary breakpoint 1 at 0x194: file spu_bugs.c, line 23. Temporary breakpoint 1, main (speid=25296904, argp=0) at spu_bugs.c:23 23 sprintf(msg, "Cell GDB tutorial: hello from SPU "
De asemenea este posibilă activarea unui breakpoint la orice funcție/linie din codul SPU. În cazul unei întrebări legate de lipsa fișierului sursă al codului SPU se răspunde cu y
.
(gdb) break spu_bugs.c:main No source file named spu_bugs.c. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (spu_bugs.c:main) pending. (gdb) run Starting program: /export/home/acs/external/dan.dragomir/gdb/ppu/ppu_bugs [Thread debugging using libthread_db enabled] Breakpoint 1, main (speid=25296904, argp=0) at spu_bugs.c:23 23 sprintf(msg, "Cell GDB tutorial: hello from SPU " | (gdb) break spu_bugs.c:26 No source file named spu_bugs.c. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (spu_bugs.c:26) pending. (gdb) run Starting program: /export/home/acs/external/dan.dragomir/gdb/ppu/ppu_bugs [Thread debugging using libthread_db enabled] Breakpoint 1, main (speid=7798581337495727215, argp=6134033987286868041) at spu_bugs.c:26 26 mfc_put(msg, argp, sizeof(msg), 0, 0, 0); |