Release 960428
[wine] / debugger / stack.c
1 /*
2  * Debugger stack handling
3  *
4  * Copyright 1995 Alexandre Julliard
5  */
6
7 #include <stdio.h>
8 #include "windows.h"
9 #include "debugger.h"
10
11
12 typedef struct
13 {
14     WORD bp;
15     WORD ip;
16     WORD cs;
17 } FRAME16;
18
19 typedef struct
20 {
21     DWORD bp;
22     DWORD ip;
23     WORD cs;
24 } FRAME32;
25
26
27
28 /***********************************************************************
29  *           DEBUG_InfoStack
30  *
31  * Dump the top of the stack
32  */
33 void DEBUG_InfoStack(void)
34 {
35     DBG_ADDR addr;
36
37     fprintf(stderr,"Stack dump:\n");
38     if ((SS_reg(DEBUG_context) == WINE_DATA_SELECTOR) ||
39         (GET_SEL_FLAGS(SS_reg(DEBUG_context)) & LDT_FLAGS_32BIT))
40     {  /* 32-bit mode */
41         addr.seg = 0;
42         addr.off = ESP_reg(DEBUG_context);
43         DEBUG_ExamineMemory( &addr, 24, 'x' );
44     }
45     else  /* 16-bit mode */
46     {
47         addr.seg = SS_reg(DEBUG_context);
48         addr.off = SP_reg(DEBUG_context);
49         DEBUG_ExamineMemory( &addr, 24, 'w' );
50     }
51     fprintf(stderr,"\n");
52 }
53
54
55 /***********************************************************************
56  *           DEBUG_BackTrace
57  *
58  * Display a stack back-trace.
59  */
60 void DEBUG_BackTrace(void)
61 {
62     DBG_ADDR addr;
63     int frameno = 0;
64
65     fprintf(stderr,"Backtrace:\n");
66     if (SS_reg(DEBUG_context) == WINE_DATA_SELECTOR)  /* 32-bit mode */
67     {
68         addr.seg = 0;
69         fprintf(stderr,"%d ",frameno++);
70         addr.off = EIP_reg(DEBUG_context);
71         DEBUG_PrintAddress( &addr, 32 );
72         fprintf( stderr, "\n" );
73         addr.off = EBP_reg(DEBUG_context);
74         while (addr.off)
75         {
76             FRAME32 *frame = (FRAME32 *)addr.off;
77             if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME32) )) return;
78             if (!frame->ip) break;
79             fprintf(stderr,"%d ",frameno++);
80             addr.off = frame->ip;
81             DEBUG_PrintAddress( &addr, 32 );
82             fprintf( stderr, "\n" );
83             addr.off = frame->bp;
84         }
85     }
86     else  /* 16-bit mode */
87     {
88       WORD ss = SS_reg(DEBUG_context), cs = CS_reg(DEBUG_context);
89       if (GET_SEL_FLAGS(ss) & LDT_FLAGS_32BIT)
90       {
91           fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
92           return;
93       }
94       fprintf( stderr,"%d ", frameno++ );
95       addr.seg = cs;
96       addr.off = IP_reg(DEBUG_context);
97       DEBUG_PrintAddress( &addr, 16 );
98       fprintf( stderr, "\n" );
99       addr.seg = ss;
100       addr.off = BP_reg(DEBUG_context) & ~1;
101       for (;;)
102       {
103           FRAME16 *frame = (FRAME16 *)DBG_ADDR_TO_LIN(&addr);
104           if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME16) )) return;
105           if (!frame->bp) break;
106           if (frame->bp & 1) cs = frame->cs;
107           fprintf( stderr,"%d ", frameno++ );
108           addr.seg = cs;
109           addr.off = frame->ip;
110           DEBUG_PrintAddress( &addr, 16 );
111           fprintf( stderr, "\n" );
112           addr.seg = ss;
113           addr.off = frame->bp & ~1;
114       }
115   }
116   fprintf( stderr, "\n" );
117 }