ΠΡΠ»ΠΈ Π²Ρ Π·Π°Π±ΡΠ»ΠΈ ΡΠΊΠ°Π·Π°ΡΡ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠ΅ ΠΈΠΌΠ΅Π½Π° ΡΠ°ΠΉΠ»ΠΎΠ², Π΄Π»Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ GDB ΠΈΠΌΠ΅Π½ΠΈ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ 'file ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ-ΡΠ°ΠΉΠ»', Π° Π΄Π»Ρ ΠΈΠΌΠ΅Π½ΠΈ ΡΠ°ΠΉΠ»Π° Π΄Π°ΠΌΠΏΠ° β 'core-file ΠΈΠΌΡ-ΡΠ°ΠΉΠ»Π°-Π΄Π°ΠΌΠΏΠ°'.
ΠΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ Π΄Π°ΠΌΠΏΠ° ΡΠ΄ΡΠ° GDB ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΌΠ΅ΡΡΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. Π‘Π»Π΅Π΄ΡΡΡΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°, ch15-abort.c, Π΄Π΅Π»Π°Π΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΉ, Π° Π·Π°ΡΠ΅ΠΌ Π½Π°ΠΌΠ΅ΡΠ΅Π½Π½ΠΎ Π·Π°Π²Π΅ΡΡΠ°Π΅ΡΡΡ ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²ΠΎΠΌ abort(), ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π΄Π°ΠΌΠΏ ΡΠ΄ΡΠ°:
/* ch15-abort.c --- ΡΠΎΠ·Π΄Π°Π΅Ρ Π΄Π°ΠΌΠΏ ΡΠ΄ΡΠ° */
#include <stdio.h>
#include <stdlib.h>
/* recurse --- ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΉ */
void recurse(void)
{
static int i;
if (++i == 3)
abort();
else
recurse();
}
int main(int argc, char **argv)
{
recurse();
}
ΠΠΎΡ Π½Π΅Π±ΠΎΠ»ΡΡΠΎΠΉ ΡΠ΅Π°Π½Ρ GDB Ρ ΡΡΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΎΠΉ:
$ gcc -g ch15-abort.c -o ch15-abort /* ΠΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π±Π΅Π· -O */
$ ch15-abort /* ΠΠ°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ */
Aborted (core dumped) /* ΠΠ½Π° ΠΏΠ΅ΡΠ°Π»ΡΠ½ΠΎ Π·Π°Π²Π΅ΡΡΠ°Π΅ΡΡΡ */
$ gdb ch15-abort core.4124 /* ΠΠ°ΠΏΡΡΡΠΈΡΡ Π΄Π»Ρ Π½Π΅Π΅ GDB */
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU
General Public License, and you are
welcome to change it and/or distribute copies of it
under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Core was generated by 'ch15-abort'.
Program terminated with signal 6, Aborted.
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x42028ccl in kill() from /lib/i686/libc.so.6
(gdb) where /* ΠΡΠ²Π΅ΡΡΠΈ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΡ ΡΡΠ΅ΠΊΠ° */
#0 0x42028cc1 in kill() from /lib/i686/libc.so.6
#1 0x42028ac8 in raise() from /lib/i686/libc.so.6
#2 0x4202a019 in abort() from /lib/1686/libc.so.6
#3 0x08048342 in recurse() at ch15-abort.c:13
/* <-- ΠΠ°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ Π·Π΄Π΅ΡΡ */
#4 0x08048347 in recurse() at ch15-abort.Ρ:15
#5 0x08048347 in recurse() at ch15-abort.c:15
#6 0x0804835f in main (argc=1, argv=0xbffff8f4) at ch15-abort.c:20
#7 0x420158d4 in __libc_start_main() from /lib/i686/libc.so.6
ΠΠΎΠΌΠ°Π½Π΄Π° where Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΡ ΡΡΠ΅ΠΊΠ°, ΡΠΎ Π΅ΡΡΡ ΡΠΏΠΈΡΠΎΠΊ Π²ΡΠ΅Ρ Π²ΡΠ·Π²Π°Π½Π½ΡΡ ΡΡΠ½ΠΊΡΠΈΠΉ, Π½Π°ΡΠΈΠ½Π°Ρ Ρ ΡΠ°ΠΌΡΡ Π½Π΅Π΄Π°Π²Π½ΠΈΡ . ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ ΠΈΠΌΠ΅Π΅ΡΡΡ ΡΡΠΈ Π²ΡΠ·ΠΎΠ²Π° ΡΡΠ½ΠΊΡΠΈΠΈ recurse(). ΠΠΎΠΌΠ°Π½Π΄Π° bt, ΠΎΠ·Π½Π°ΡΠ°ΡΡΠ°Ρ 'back trace' (ΠΎΠ±ΡΠ°ΡΠ½Π°Ρ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΠ°), ΡΠ²Π»ΡΠ΅ΡΡΡ Π΄ΡΡΠ³ΠΈΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ Π΄Π»Ρ where; Π΅Π΅ Π»Π΅Π³ΡΠ΅ Π½Π°Π±ΠΈΡΠ°ΡΡ.
ΠΡΠ·ΠΎΠ² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π² ΡΡΠ΅ΠΊΠ΅ Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ ΡΡΠ΅ΠΉΠΌΠΎΠΌ. ΠΡΠΎΡ ΡΠ΅ΡΠΌΠΈΠ½ ΠΏΡΠΈΡΠ΅Π» ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠΎΠ², Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ, Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΈ Π°Π΄ΡΠ΅ΡΠ° Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΠ³ΡΡΠΏΠΏΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Π² ΡΡΠ΅ΠΊΠ΅, Π½Π°Π·ΡΠ²Π°ΡΡΡΡ ΡΡΠ΅ΠΉΠΌΠΎΠΌ ΡΡΠ΅ΠΊΠ°. ΠΠΎΠΌΠ°Π½Π΄Π° frame GDB Π΄Π°Π΅Ρ Π²Π°ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ ΡΡΠ΅ΠΉΠΌ. Π Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π½Π°ΠΌ Π½ΡΠΆΠ΅Π½ ΡΡΠ΅ΠΉΠΌ 3. ΠΡΠΎ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ Π²ΡΠ·ΠΎΠ² recurse(), ΠΊΠΎΡΠΎΡΡΠΉ Π²ΡΠ·Π²Π°Π» abort():
(gdb) frame 3 /* ΠΠ΅ΡΠ΅ΠΌΠ΅ΡΡΠΈΡΡΡΡ Π² ΡΡΠ΅ΠΉΠΌ 3 */
#3 0x08048342 in recurse() at ch15-abort.Ρ:13
13 abort(); /* GDB Π²ΡΠ²ΠΎΠ΄ΠΈΡ Π² ΡΡΠ΅ΠΉΠΌΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ */
(gdb) list /* ΠΠΎΠΊΠ°Π·Π°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΡΡΠΎΠΊ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° */
8 void recurse(void)
9 {
10 static int i;
11
12 if (++i == 3)
13 abort();
14 else
15 recurse();
16 }
17
(gdb) /* ΠΠ°ΠΆΠ°ΡΠΈΠ΅ ENTER ΠΏΠΎΠ²ΡΠΎΡΡΠ΅Ρ ΠΏΠΎΡΠ»Π΅Π΄Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ */
18 int main(int argc, char **argv)
19 {
20 recurse();
21 }
(gdb) quit /* ΠΡΠΉΡΠΈ ΠΈΠ· ΠΎΡΠ»Π°Π΄ΡΠΈΠΊΠ° (ΠΏΠΎΠΊΠ°) */
ΠΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, Π½Π°ΠΆΠ°ΡΠΈΠ΅ ENTER ΠΏΠΎΠ²ΡΠΎΡΡΠ΅Ρ ΠΏΠΎΡΠ»Π΅Π΄Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ list, Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΡΡΠΎΠΊ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. ΠΡΠΎ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΏΡΠΎΡ ΠΎΠΆΠ΄Π΅Π½ΠΈΡ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°.
ΠΠ»Ρ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ GDB ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ readline, ΠΏΠΎΡΡΠΎΠΌΡ Π΄Π»Ρ ΠΏΠΎΠ²ΡΠΎΡΠ΅Π½ΠΈΡ ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ°Π½Π΅Π΅ Π²Π²Π΅Π΄Π΅Π½Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Emacs ΠΈΠ»ΠΈ vi. ΠΠ±ΠΎΠ»ΠΎΡΠΊΠ° Bash ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΡ ΠΆΠ΅ ΡΠ°ΠΌΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ, ΠΏΠΎΡΡΠΎΠΌΡ Π΅ΡΠ»ΠΈ Π²Π°ΠΌ Π±ΠΎΠ»Π΅Π΅ Π·Π½Π°ΠΊΠΎΠΌΠΎ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ Π² ΠΏΡΠΈΠ³Π»Π°ΡΠ΅Π½ΠΈΠΈ ΠΎΠ±ΠΎΠ»ΠΎΡΠΊΠΈ, GDB ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠ°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ. ΠΡΠ° ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΡ Π΄Π°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΡΡΠΎΠΌΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΡΡΠ½ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°.
15.3.2. Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΊΠΎΠ½ΡΡΠΎΠ»ΡΠ½ΡΡ ΡΠΎΡΠ΅ΠΊ, ΠΏΠΎΡΠ°Π³ΠΎΠ²ΠΎΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΡΠ΅ ΡΠΎΡΠΊΠΈ
Π§Π°ΡΡΠΎ ΠΏΡΠΈ ΠΎΡΠΈΠ±ΠΊΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π΄Π°ΠΌΠΏ ΡΠ΄ΡΠ°. ΠΠ΅ΡΠ²ΡΠΌ ΡΠ°Π³ΠΎΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ GDB Ρ ΡΠ°ΠΉΠ»ΠΎΠΌ core Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ΠΡΠ»ΠΈ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ Π΄Π²ΠΎΠΈΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» Π½Π΅ Π±ΡΠ» ΠΎΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°Π½ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ (Ρ.Π΅. Π±Π΅Π· -g), Π²ΡΠ΅, ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ ΡΠΎΠΎΠ±ΡΠΈΡΡ GDB, ΡΡΠΎ ΠΈΠΌΡ ΡΡΠ½ΠΊΡΠΈΠΈ, Π½ΠΎ Π±ΠΎΠ»ΡΡΠ΅ Π½ΠΈΠΊΠ°ΠΊΠΈΡ Π΄Π΅ΡΠ°Π»Π΅ΠΉ.
Π‘Π»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠ°Π³ΠΎΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠ΅ΡΠ΅ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΡ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΠΈ Π±Π΅Π· ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΎΠ½Π° Π²ΡΠ΅ Π΅ΡΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΎΡΠΈΠ±ΠΊΡ. ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠ², ΡΡΠΎ ΡΡΠΎ ΡΠ°ΠΊ, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΏΠΎΠ΄ ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅ΠΌ ΠΎΡΠ»Π°Π΄ΡΠΈΠΊΠ° ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»ΡΠ½ΡΡ ΡΠΎΡΠΊΡ Π² ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ΅, Π²ΡΠ·ΡΠ²Π°ΡΡΠ΅ΠΉ ΠΎΡΠΈΠ±ΠΊΡ.
ΠΠΎΠ½ΡΡΠΎΠ»ΡΠ½Π°Ρ ΡΠΎΡΠΊΠ° (breakpoint) ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎΡΠΊΠΎΠΉ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡΠ΅ΡΠ²Π°ΡΡΡΡ, ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡΡ. ΠΠΎΠ½ΡΡΠΎΠ»ΡΠ½ΡΠ΅ ΡΠΎΡΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ, Π½ΠΎΠΌΠ΅ΡΡ ΡΡΡΠΎΠΊΠΈ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°, ΡΠ°ΠΉΠ»Ρ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ Ρ Π½ΠΎΠΌΠ΅ΡΠΎΠΌ ΡΡΡΠΎΠΊΠΈ, Π° ΡΠ°ΠΊΠΆΠ΅ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΡΠΏΠΎΡΠΎΠ±Π°ΠΌΠΈ.
ΠΠΎΡΠ»Π΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΠΊΠΎΠ½ΡΡΠΎΠ»ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ run, Π·Π° ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΠΎΠ³ΡΡ ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Ρ ΠΎΡΠ»Π°ΠΆΠΈΠ²Π°Π΅ΠΌΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅. (GDB ΡΠ΄ΠΎΠ±Π½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ Π·Π° Π²Π°Ρ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ; Π΅ΡΠ»ΠΈ Π½ΡΠΆΠ½ΠΎ ΡΠ½ΠΎΠ²Π° Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Ρ Π½Π°ΡΠ°Π»Π°, Π²ΡΠ΅ ΡΡΠΎ Π½ΡΠΆΠ½ΠΎ β ΡΡΠΎ Π½Π°ΠΏΠ΅ΡΠ°ΡΠ°ΡΡ Π»ΠΈΡΡ ΡΠ°ΠΌΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ run, ΠΈ GDB Π·Π°ΠΏΡΡΡΠΈΡ Π½ΠΎΠ²ΡΡ ΠΊΠΎΠΏΠΈΡ Ρ ΡΠ΅ΠΌΠΈ ΠΆΠ΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°ΠΌΠΈ, ΠΊΠ°ΠΊ ΠΈ ΡΠ°Π½Π΅Π΅). ΠΠΎΡ ΠΊΠΎΡΠΎΡΠΊΠΈΠΉ ΡΠ΅Π°Π½Ρ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ gawk:
$ gdb gawk /* ΠΠ°ΠΏΡΡΠΊ GDB Π΄Π»Ρ gawk */
GNU gdb 5.3
...
(gdb) break do_print /* ΠΡΠ΅ΡΡΠ²Π°Π½ΠΈΠ΅ Π² do_print */
Breakpoint 1 at 0x805a36a: file builtin.c, line 1504.
(gdb) run 'BEGIN { print "hello, world" }' /* ΠΠ°ΠΏΡΡΠΊ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ */
Starting program: /home/arnold/Gnu/gawk/gawk-3.1.3/gawk 'BEGIN { print "hello, world" }'
Breakpoint 1, do_print (tree=0x8095290) at builtin.c:1504
1504 struct redirect *rp = NULL; /* ΠΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΠΈΠ³Π°Π΅Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠΈ */
(gdb) list /* ΠΠΎΠΊΠ°Π·Π°ΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ */
1499
1500 void
1501 do_print(register NODE *tree)
1502 {
1503 register NODE **t;
1504 struct redirect *rp = NULL;
1505 register FILE *fp;
1506 int numnodes, i;
1507 NODE *save;
1508 NODE *tval;
ΠΠΎ Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΠΈ ΠΊΠΎΠ½ΡΡΠΎΠ»ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠΈ Π²Ρ ΠΏΡΠΎΡ ΠΎΠ΄ΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π² ΠΏΠΎΡΠ°Π³ΠΎΠ²ΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ GDB ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΠΈΡΠΏΠΎΠ»Π½ΡΡΡ Π»ΠΈΡΡ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π·Π° ΡΠ°Π·. GDB Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΡΡΠΎΠΊΡ, ΠΊΠΎΡΠΎΡΡΡ ΡΠΎΠ±ΠΈΡΠ°Π΅ΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ, ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΠΏΡΠΈΠ³Π»Π°ΡΠ΅Π½ΠΈΠ΅. Π§ΡΠΎΠ±Ρ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π° next:
(gdb) next /* ΠΡΠΏΠΎΠ»Π½ΠΈΡΡ ΡΠ΅ΠΊΡΡΠΈΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ (ΡΡΡΠΎΠΊΠ° 1504 Π²ΡΡΠ΅) */
1510 fp = redirect_to_fp(tree->rnode, &rp); /* GDB Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ */
(gdb) /* ΠΠ°ΠΆΠΌΠΈΡΠ΅ ENTER Π΄Π»Ρ Π΅Π³ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΈ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄Π° ΠΊ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ */
1511 if (fp == NULL)
(gdb) /* ΡΠ½ΠΎΠ²Π° ENTER */
1519 save = tree = tree->lnode; (gdb) /* Π ΡΠ½ΠΎΠ²Π° */
1520 for (numnodes = 0; tree != NULL; tree = tree->rnode)
ΠΠΎΠΌΠ°Π½Π΄Π° step ΡΠ²Π»ΡΠ΅ΡΡΡ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Π΄Π»Ρ ΠΏΠΎΡΠ°Π³ΠΎΠ²ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ. ΠΠ΅ΠΆΠ΄Ρ next ΠΈ step Π΅ΡΡΡ Π²Π°ΠΆΠ½ΠΎΠ΅ ΡΠ°Π·Π»ΠΈΡΠΈΠ΅, next Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ. ΠΡΠ»ΠΈ ΡΡΠΎΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π²ΡΠ·ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ Π΄ΠΎ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ GDB Π²Π΅ΡΠ½Π΅Ρ ΡΠ΅Π±Π΅ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΡ ΡΠ°Π±ΠΎΡΠ°ΡΡΠ΅ΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ.
Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, ΠΊΠΎΠ³Π΄Π° Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΌ Π²ΡΠ·ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠΎΠΌ step, GDB Π²Ρ ΠΎΠ΄ΠΈΡ Π² Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡ Π²Π°ΠΌ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ ΠΏΠΎΡΠ°Π³ΠΎΠ²ΠΎΠ΅ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ (ΠΈΠ»ΠΈ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΡ) ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ΠΡΠ»ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ Π½Π΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π²ΡΠ·ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΈ, step Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½Π° next.
ΠΠΠΠΠ§ΠΠΠΠ. ΠΠ΅Π³ΠΊΠΎ Π·Π°Π±ΡΡΡ, ΠΊΠ°ΠΊΠ°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π° Π±ΡΠ»Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π°, ΠΈ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡΡ Π½Π°ΠΆΠΈΠΌΠ°ΡΡ ENTER Π΄Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠΎΠ². ΠΡΠ»ΠΈ Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ step, Π²Ρ ΡΠ»ΡΡΠ°ΠΉΠ½ΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΠΎΠΉΡΠΈ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΡΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΡΠ°ΠΊΡΡ ΠΊΠ°ΠΊ strlen() ΠΈΠ»ΠΈ printf(), Ρ ΠΊΠΎΡΠΎΡΠΎΠΉ Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ Π½Π΅ Ρ ΠΎΡΠΈΡΠ΅ Π²ΠΎΠ·ΠΈΡΡΡΡ. Π ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ finish, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄ΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΠΈΠ· ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ
ΠΡΠ²Π΅ΡΡΠΈ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΠΏΠ°ΠΌΡΡΠΈ ΠΌΠΎΠΆΠ½ΠΎ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ print. GDB ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π΅Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π‘, ΡΡΠΎ ΡΠΏΡΠΎΡΠ°Π΅Ρ ΠΈ Π΄Π΅Π»Π°Π΅Ρ Π΅ΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΌ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ ΡΡΡΡΠΊΡΡΡ, Π½Π° ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡΡΠ»Π°ΡΡΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ:
(gdb) print *save /* ΠΡΠ²Π΅ΡΡΠΈ ΡΡΡΡΠΊΡΡΡΡ, Π½Π° ΠΊΠΎΡΠΎΡΡΡ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ save */
$1 = {sub = {nodep = {l = {lptr = 0x8095250, param_name = 0x8095250 "pR\t\b",
l1 = 134828624}, r = {rptr = 0x0, pptr = 0, preg = 0x0,
hd = 0x0, av = 0x0, r_ent =0}, x = {extra = 0x0, x1 = 0,
param_list = 0x0},
name = 0x0, number = 1, reflags = 0}, val = {