comparison src/breakpoint.d @ 1:4a9dcbd9e54f

-files of 0.13 beta -fixes so that it now compiles with the current dmd version
author marton@basel.hu
date Tue, 05 Apr 2011 20:44:01 +0200
parents
children
comparison
equal deleted inserted replaced
0:586e4a649642 1:4a9dcbd9e54f
1 /* Ddbg - Win32 Debugger for the D programming language
2 * Copyright (c) 2007 Jascha Wetzel
3 * All rights reserved. See LICENSE.TXT for details.
4 */
5 module breakpoint;
6
7 import std.string;
8 import std.c.string;
9
10 import dbgthread;
11 import codeview.codeview;
12 import dbgprocess;
13 import util;
14
15 import win32.windef;
16
17 enum StepMode {
18 e_in, e_over, e_out
19 }
20
21 /**************************************************************************************************
22 Represents a software breakpoint.
23 **************************************************************************************************/
24 class Breakpoint
25 {
26 //---------------------------------------------------------------------------------------------
27 // constants
28 const ubyte BREAKPOINT_OPCODE = 0xccu;
29
30 //---------------------------------------------------------------------------------------------
31 // variables
32 byte old_opcode;
33 bool active,
34 temporary,
35 deactivate_d_exception_handler,
36 propagate, /// when hit on a jmp/call/ret instruction, shall be reactivated on it's destination
37 hardware;
38 Breakpoint foreach_end;
39 Location location;
40 size_t frame_ptr,
41 threadId,
42 old_dr_value;
43 ubyte dr_index;
44
45 //---------------------------------------------------------------------------------------------
46 // properties
47 string file() { return location is null?null:location.file; }
48 uint line() { return location is null?0:location.line; }
49 uint address() { return location is null?0:location.address; }
50
51
52 //---------------------------------------------------------------------------------------------
53 // construction
54 this(Location loc, bool temp, uint _threadId, bool _hardware=false)
55 {
56 hardware = _hardware;
57 threadId = _threadId;
58 temporary = temp;
59 location = loc;
60 }
61
62
63 //---------------------------------------------------------------------------------------------
64 // methods
65
66 /**
67 *
68 */
69 string toString()
70 {
71 string tmp;
72 tmp.length = 100;
73 tmp.length = 0;
74 if ( location.path.length > 0 )
75 tmp ~= format("%s ", location.path);
76 if ( file.length > 0 )
77 tmp ~= format("%s:%d ", file, line);
78 if ( location.address > 0 )
79 tmp ~= format("0x%x ", location.address);
80 if ( hardware )
81 tmp ~= "hw ";
82 if ( threadId > 0 )
83 tmp ~= format("thread %s", threadId);
84 else
85 tmp ~= format("all threads");
86 return tmp;
87 }
88
89 /**********************************************************************************************
90 Restores the opcode that has been overwritten for the given breakpoint.
91 Returns success.
92 **********************************************************************************************/
93 bool deactivate(DbgProcess proc)
94 {
95 if ( !active )
96 return true;
97 if ( proc is null )
98 return false;
99
100 if ( hardware )
101 {
102 if ( threadId == 0 )
103 {
104 foreach ( thread; proc.threads.values )
105 clearHWBP(thread, 0);
106 }
107 else
108 clearHWBP(proc.threads[threadId], 0);
109 }
110 else if( !proc.writeProcessMemory(location.address, &old_opcode, ubyte.sizeof))
111 {
112 DbgIO.println("restoreBreakpoint(): Failed to write original opcode at 0x%x", location.address);
113 return false;
114 }
115
116 active = false;
117 return true;
118 }
119
120 /**********************************************************************************************
121 Writes an int 3 opcode at the address of this breakpoint, saving the overwritten code.
122 Returns success.
123 **********************************************************************************************/
124 bool activate(DbgProcess proc)
125 {
126 if( active )
127 return true;
128 if( location.address == 0 || proc is null )
129 return false;
130
131 debug DbgIO.println("activating bp at 0x%x", location.address);
132
133 if ( hardware )
134 {
135 if ( threadId == 0 )
136 {
137 foreach ( thread; proc.threads.values )
138 setHWBP(thread, location.address, 0);
139 }
140 else
141 setHWBP(proc.threads[threadId], location.address, 0);
142 }
143 else
144 {
145 uint oldprot, oldprot2;
146 ubyte ccByte = cast(ubyte)0xcc;
147
148 if( ubyte.sizeof > proc.readProcessMemory(location.address, &old_opcode, ubyte.sizeof) ) {
149 DbgIO.println( "readProcessMemory(): failed to read breakpoint opcode at 0x%08x", location.address );
150 return false;
151 }
152
153 ubyte opcode = BREAKPOINT_OPCODE;
154 if( ubyte.sizeof > proc.writeProcessMemory(location.address, &opcode, ubyte.sizeof) ) {
155 DbgIO.println("writeProcessMemory(): Failed to write breakpoint at 0x%08x", location.address );
156 return false;
157 }
158 }
159
160 active = true;
161 return true;
162 }
163
164 /**********************************************************************************************
165
166 **********************************************************************************************/
167 void setHWBP(DbgThread thread, size_t address, ubyte index)
168 {
169 assert(index < 4);
170
171 CONTEXT ctx;
172 thread.getContext(ctx, CONTEXT_DEBUG_REGISTERS);
173 DbgIO.println("Dr0 = %x\nDr1 = %x\nDr2 = %x\nDr3 = %x\nDr7 = %x\n", ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr7);
174
175 old_dr_value = *(&ctx.Dr0 + index);
176 *(&ctx.Dr0 + index) = address+thread.getDsBase;
177 dr_index = index;
178
179 ctx.Dr7 |= 1<<10 | (1 << index) | (15 << (16+index*4));
180 DbgIO.println("Dr0 = %x\nDr1 = %x\nDr2 = %x\nDr3 = %x\nDr7 = %x\n", ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr7);
181 thread.setContext(ctx);
182 }
183
184 /**********************************************************************************************
185
186 **********************************************************************************************/
187 void clearHWBP(DbgThread thread, ubyte index)
188 {
189 assert(index < 4);
190
191 CONTEXT ctx;
192 thread.getContext(ctx, CONTEXT_DEBUG_REGISTERS);
193 DbgIO.println("Dr0 = %x\nDr1 = %x\nDr2 = %x\nDr3 = %x\nDr7 = %x\n", ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr7);
194
195 ctx.Dr7 &= ~((1 << index) | (15 << (16+index*4)));
196 DbgIO.println("Dr0 = %x\nDr1 = %x\nDr2 = %x\nDr3 = %x\nDr7 = %x\n", ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr7);
197 thread.setContext(ctx);
198 }
199 }