]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/coregrind/m_debugger.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / coregrind / m_debugger.c
1
2 /*--------------------------------------------------------------------*/
3 /*--- Attaching a debugger.                           m_debugger.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9
10    Copyright (C) 2000-2010 Julian Seward 
11       jseward@acm.org
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27
28    The GNU General Public License is contained in the file COPYING.
29 */
30
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_libcsetjmp.h"
34 #include "pub_core_threadstate.h"
35 #include "pub_core_xarray.h"
36 #include "pub_core_clientstate.h"
37 #include "pub_core_debugger.h"
38 #include "pub_core_libcbase.h"
39 #include "pub_core_libcprint.h"
40 #include "pub_core_libcproc.h"
41 #include "pub_core_libcsignal.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_options.h"
44
45
46 #define WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
47 #define WSTOPSIG(status) (((status) & 0xff00) >> 8)
48
49 static Int ptrace_setregs(Int pid, VexGuestArchState* vex)
50 {
51 #if defined(VGP_x86_linux)
52    struct vki_user_regs_struct regs;
53    VG_(memset)(&regs, 0, sizeof(regs));
54    regs.cs     = vex->guest_CS;
55    regs.ss     = vex->guest_SS;
56    regs.ds     = vex->guest_DS;
57    regs.es     = vex->guest_ES;
58    regs.fs     = vex->guest_FS;
59    regs.gs     = vex->guest_GS;
60    regs.eax    = vex->guest_EAX;
61    regs.ebx    = vex->guest_EBX;
62    regs.ecx    = vex->guest_ECX;
63    regs.edx    = vex->guest_EDX;
64    regs.esi    = vex->guest_ESI;
65    regs.edi    = vex->guest_EDI;
66    regs.ebp    = vex->guest_EBP;
67    regs.esp    = vex->guest_ESP;
68    regs.eflags = LibVEX_GuestX86_get_eflags(vex);
69    regs.eip    = vex->guest_EIP;
70    return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &regs);
71
72 #elif defined(VGP_amd64_linux)
73    struct vki_user_regs_struct regs;
74    VG_(memset)(&regs, 0, sizeof(regs));
75    regs.rax    = vex->guest_RAX;
76    regs.rbx    = vex->guest_RBX;
77    regs.rcx    = vex->guest_RCX;
78    regs.rdx    = vex->guest_RDX;
79    regs.rsi    = vex->guest_RSI;
80    regs.rdi    = vex->guest_RDI;
81    regs.rbp    = vex->guest_RBP;
82    regs.rsp    = vex->guest_RSP;
83    regs.r8     = vex->guest_R8;
84    regs.r9     = vex->guest_R9;
85    regs.r10    = vex->guest_R10;
86    regs.r11    = vex->guest_R11;
87    regs.r12    = vex->guest_R12;
88    regs.r13    = vex->guest_R13;
89    regs.r14    = vex->guest_R14;
90    regs.r15    = vex->guest_R15;
91    regs.eflags = LibVEX_GuestAMD64_get_rflags(vex);
92    regs.rip    = vex->guest_RIP;
93    /* Set %{c,d,e,f,s,g}s and %{fs,gs}_base (whatever those are) to
94       values which don't fail the kernel's sanity checks.  I have no
95       idea what these should really be set to.  Anyway, mostly it
96       seems that zero is an allowable value, except for %cs and %ss
97       which have to have their lowest 2 bits be 11.  See putreg() in
98       linux-2.6.23/arch/x86_64/kernel/ptrace.c for the apparently
99       relevant sanity checks.  This fixes #145622. */
100    regs.cs      = 3;
101    regs.ds      = 0;
102    regs.es      = 0;
103    regs.fs      = 0;
104    regs.ss      = 3;
105    regs.gs      = 0;
106    regs.fs_base = 0;
107    regs.gs_base = 0;
108    return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &regs);
109
110 #elif defined(VGP_ppc32_linux)
111    Int rc = 0;
112    /* apparently the casting to void* is the Right Thing To Do */
113    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R0  * 4), (void*)vex->guest_GPR0);
114    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R1  * 4), (void*)vex->guest_GPR1);
115    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R2  * 4), (void*)vex->guest_GPR2);
116    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R3  * 4), (void*)vex->guest_GPR3);
117    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R4  * 4), (void*)vex->guest_GPR4);
118    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R5  * 4), (void*)vex->guest_GPR5);
119    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R6  * 4), (void*)vex->guest_GPR6);
120    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R7  * 4), (void*)vex->guest_GPR7);
121    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R8  * 4), (void*)vex->guest_GPR8);
122    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R9  * 4), (void*)vex->guest_GPR9);
123    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R10 * 4), (void*)vex->guest_GPR10);
124    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R11 * 4), (void*)vex->guest_GPR11);
125    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R12 * 4), (void*)vex->guest_GPR12);
126    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R13 * 4), (void*)vex->guest_GPR13);
127    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R14 * 4), (void*)vex->guest_GPR14);
128    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R15 * 4), (void*)vex->guest_GPR15);
129    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R16 * 4), (void*)vex->guest_GPR16);
130    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R17 * 4), (void*)vex->guest_GPR17);
131    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R18 * 4), (void*)vex->guest_GPR18);
132    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R19 * 4), (void*)vex->guest_GPR19);
133    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R20 * 4), (void*)vex->guest_GPR20);
134    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R21 * 4), (void*)vex->guest_GPR21);
135    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R22 * 4), (void*)vex->guest_GPR22);
136    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R23 * 4), (void*)vex->guest_GPR23);
137    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R24 * 4), (void*)vex->guest_GPR24);
138    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R25 * 4), (void*)vex->guest_GPR25);
139    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R26 * 4), (void*)vex->guest_GPR26);
140    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R27 * 4), (void*)vex->guest_GPR27);
141    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R28 * 4), (void*)vex->guest_GPR28);
142    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R29 * 4), (void*)vex->guest_GPR29);
143    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R30 * 4), (void*)vex->guest_GPR30);
144    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R31 * 4), (void*)vex->guest_GPR31);
145    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_NIP * 4), (void*)vex->guest_CIA);
146    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CCR * 4),
147                      (void*)LibVEX_GuestPPC32_get_CR(vex));
148    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_LNK * 4), (void*)vex->guest_LR);
149    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CTR * 4), (void*)vex->guest_CTR);
150    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_XER * 4),
151                      (void*)LibVEX_GuestPPC32_get_XER(vex));
152    return rc;
153
154 #elif defined(VGP_ppc64_linux)
155    Int rc = 0; 
156    /* FRJ: copied nearly verbatim from the ppc32 case. I compared the 
157       vki-ppc64-linux.h with its ppc32 counterpart and saw no 
158       appreciable differences, other than the registers being 8 bytes 
159       instead of 4. No idea why we don't set all of the entries 
160       declared in vki_pt_regs, but ppc32 doesn't so there must be a 
161       reason. 
162  
163       Finally, note that CR and XER are 32 bits even for ppc64 (see 
164       libvex_guest_ppc64.h), but the vki_pt_regs struct still gives 
165       them 64 bits. 
166    */ 
167    /* apparently the casting to void* is the Right Thing To Do */ 
168    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R0  * 8), (void*)vex->guest_GPR0); 
169    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R1  * 8), (void*)vex->guest_GPR1); 
170    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R2  * 8), (void*)vex->guest_GPR2); 
171    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R3  * 8), (void*)vex->guest_GPR3); 
172    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R4  * 8), (void*)vex->guest_GPR4); 
173    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R5  * 8), (void*)vex->guest_GPR5); 
174    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R6  * 8), (void*)vex->guest_GPR6); 
175    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R7  * 8), (void*)vex->guest_GPR7); 
176    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R8  * 8), (void*)vex->guest_GPR8); 
177    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R9  * 8), (void*)vex->guest_GPR9); 
178    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R10 * 8), (void*)vex->guest_GPR10); 
179    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R11 * 8), (void*)vex->guest_GPR11); 
180    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R12 * 8), (void*)vex->guest_GPR12); 
181    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R13 * 8), (void*)vex->guest_GPR13); 
182    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R14 * 8), (void*)vex->guest_GPR14); 
183    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R15 * 8), (void*)vex->guest_GPR15); 
184    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R16 * 8), (void*)vex->guest_GPR16); 
185    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R17 * 8), (void*)vex->guest_GPR17); 
186    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R18 * 8), (void*)vex->guest_GPR18); 
187    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R19 * 8), (void*)vex->guest_GPR19); 
188    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R20 * 8), (void*)vex->guest_GPR20); 
189    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R21 * 8), (void*)vex->guest_GPR21); 
190    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R22 * 8), (void*)vex->guest_GPR22); 
191    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R23 * 8), (void*)vex->guest_GPR23); 
192    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R24 * 8), (void*)vex->guest_GPR24); 
193    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R25 * 8), (void*)vex->guest_GPR25); 
194    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R26 * 8), (void*)vex->guest_GPR26); 
195    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R27 * 8), (void*)vex->guest_GPR27); 
196    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R28 * 8), (void*)vex->guest_GPR28); 
197    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R29 * 8), (void*)vex->guest_GPR29); 
198    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R30 * 8), (void*)vex->guest_GPR30); 
199    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R31 * 8), (void*)vex->guest_GPR31); 
200    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_NIP * 8), (void*)vex->guest_CIA); 
201    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CCR * 8), 
202                                               (void*)(long)LibVEX_GuestPPC64_get_CR(vex)); 
203    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_LNK * 8), (void*)vex->guest_LR); 
204    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CTR * 8), (void*)vex->guest_CTR); 
205    rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_XER * 8), 
206                                               (void*)(long)LibVEX_GuestPPC64_get_XER(vex)); 
207    return rc; 
208
209 #elif defined(VGP_arm_linux)
210    struct vki_user_regs_struct uregs;
211    VG_(memset)(&uregs, 0, sizeof(uregs));
212    uregs.ARM_r0   = vex->guest_R0; 
213    uregs.ARM_r1   = vex->guest_R1; 
214    uregs.ARM_r2   = vex->guest_R2; 
215    uregs.ARM_r3   = vex->guest_R3; 
216    uregs.ARM_r4   = vex->guest_R4; 
217    uregs.ARM_r5   = vex->guest_R5; 
218    uregs.ARM_r6   = vex->guest_R6; 
219    uregs.ARM_r7   = vex->guest_R7; 
220    uregs.ARM_r8   = vex->guest_R8; 
221    uregs.ARM_r9   = vex->guest_R9; 
222    uregs.ARM_r10  = vex->guest_R10; 
223    uregs.ARM_fp   = vex->guest_R11; 
224    uregs.ARM_ip   = vex->guest_R12; 
225    uregs.ARM_sp   = vex->guest_R13; 
226    uregs.ARM_lr   = vex->guest_R14; 
227    // Remove the T bit from the bottom of R15T.  It will get shipped
228    // over in CPSR.T instead, since LibVEX_GuestARM_get_cpsr copies
229    // it from R15T[0].
230    uregs.ARM_pc   = vex->guest_R15T & 0xFFFFFFFE;
231    uregs.ARM_cpsr = LibVEX_GuestARM_get_cpsr(vex);
232    return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &uregs);
233
234 #elif defined(VGP_ppc32_aix5)
235    I_die_here;
236
237 #elif defined(VGP_ppc64_aix5)
238    I_die_here;
239
240 #elif defined(VGP_x86_darwin)
241    I_die_here;
242
243 #elif defined(VGP_amd64_darwin)
244    I_die_here;
245
246 #elif defined(VGP_x86_l4re)
247    I_die_here;
248
249 #elif defined(VGP_s390x_linux)
250    struct vki_user_regs_struct regs;
251    vki_ptrace_area pa;
252
253    /* We don't set the psw mask and start at offset 8 */
254    pa.vki_len = (unsigned long) &regs.per_info - (unsigned long) &regs.psw.addr;
255    pa.vki_process_addr = (unsigned long) &regs.psw.addr;
256    pa.vki_kernel_addr = 8;
257
258    VG_(memset)(&regs, 0, sizeof(regs));
259    regs.psw.addr = vex->guest_IA;
260
261    /* We don't set the mask */
262    regs.gprs[0] = vex->guest_r0;
263    regs.gprs[1] = vex->guest_r1;
264    regs.gprs[2] = vex->guest_r2;
265    regs.gprs[3] = vex->guest_r3;
266    regs.gprs[4] = vex->guest_r4;
267    regs.gprs[5] = vex->guest_r5;
268    regs.gprs[6] = vex->guest_r6;
269    regs.gprs[7] = vex->guest_r7;
270    regs.gprs[8] = vex->guest_r8;
271    regs.gprs[9] = vex->guest_r9;
272    regs.gprs[10] = vex->guest_r10;
273    regs.gprs[11] = vex->guest_r11;
274    regs.gprs[12] = vex->guest_r12;
275    regs.gprs[13] = vex->guest_r13;
276    regs.gprs[14] = vex->guest_r14;
277    regs.gprs[15] = vex->guest_r15;
278
279    regs.acrs[0] = vex->guest_a0;
280    regs.acrs[1] = vex->guest_a1;
281    regs.acrs[2] = vex->guest_a2;
282    regs.acrs[3] = vex->guest_a3;
283    regs.acrs[4] = vex->guest_a4;
284    regs.acrs[5] = vex->guest_a5;
285    regs.acrs[6] = vex->guest_a6;
286    regs.acrs[7] = vex->guest_a7;
287    regs.acrs[8] = vex->guest_a8;
288    regs.acrs[9] = vex->guest_a9;
289    regs.acrs[10] = vex->guest_a10;
290    regs.acrs[11] = vex->guest_a11;
291    regs.acrs[12] = vex->guest_a12;
292    regs.acrs[13] = vex->guest_a13;
293    regs.acrs[14] = vex->guest_a14;
294    regs.acrs[15] = vex->guest_a15;
295
296    /* only used for system call restart and friends, just use r2 */
297    regs.orig_gpr2 = vex->guest_r2;
298
299    regs.fp_regs.fprs[0].ui = vex->guest_f0;
300    regs.fp_regs.fprs[1].ui = vex->guest_f1;
301    regs.fp_regs.fprs[2].ui = vex->guest_f2;
302    regs.fp_regs.fprs[3].ui = vex->guest_f3;
303    regs.fp_regs.fprs[4].ui = vex->guest_f4;
304    regs.fp_regs.fprs[5].ui = vex->guest_f5;
305    regs.fp_regs.fprs[6].ui = vex->guest_f6;
306    regs.fp_regs.fprs[7].ui = vex->guest_f7;
307    regs.fp_regs.fprs[8].ui = vex->guest_f8;
308    regs.fp_regs.fprs[9].ui = vex->guest_f9;
309    regs.fp_regs.fprs[10].ui = vex->guest_f10;
310    regs.fp_regs.fprs[11].ui = vex->guest_f11;
311    regs.fp_regs.fprs[12].ui = vex->guest_f12;
312    regs.fp_regs.fprs[13].ui = vex->guest_f13;
313    regs.fp_regs.fprs[14].ui = vex->guest_f14;
314    regs.fp_regs.fprs[15].ui = vex->guest_f15;
315    regs.fp_regs.fpc = vex->guest_fpc;
316
317    return VG_(ptrace)(VKI_PTRACE_POKEUSR_AREA, pid,  &pa, NULL);
318
319 #else
320 #  error Unknown arch
321 #endif
322 }
323
324 /* Start debugger and get it to attach to this process.  Called if the
325    user requests this service after an error has been shown, so she can
326    poke around and look at parameters, memory, etc.  You can't
327    meaningfully get the debugger to continue the program, though; to
328    continue, quit the debugger.  */
329 void VG_(start_debugger) ( ThreadId tid )
330 {
331 #  define N_BUF 4096
332    Int pid, rc;
333
334    pid = VG_(fork)();
335
336    if (pid == 0) {
337       /* child */
338       rc = VG_(ptrace)(VKI_PTRACE_TRACEME, 0, NULL, NULL);
339       vg_assert(rc == 0);
340       rc = VG_(kill)(VG_(getpid)(), VKI_SIGSTOP);
341       vg_assert(rc == 0);
342
343    } else if (pid > 0) {
344       /* parent */
345       Int status;
346       Int res;
347
348       if ((res = VG_(waitpid)(pid, &status, 0)) == pid &&
349           WIFSTOPPED(status) && WSTOPSIG(status) == VKI_SIGSTOP &&
350           ptrace_setregs(pid, &(VG_(threads)[tid].arch.vex)) == 0 &&
351           VG_(kill)(pid, VKI_SIGSTOP) == 0 &&
352           VG_(ptrace)(VKI_PTRACE_DETACH, pid, NULL, 0) == 0)
353       {
354          Char pidbuf[15];
355          Char file[50];
356          Char buf[N_BUF];
357          Char *bufptr;
358          Char *cmdptr;
359          
360          VG_(sprintf)(pidbuf, "%d", pid);
361          VG_(sprintf)(file, "/proc/%d/fd/%d", pid, VG_(cl_exec_fd));
362  
363          bufptr = buf;
364          cmdptr = VG_(clo_db_command);
365          
366          while (*cmdptr) {
367             /* each iteration can advance bufptr by at most the length
368                of file[], so the following assertion is generously
369                over-paranoid. */
370             vg_assert(bufptr - buf < N_BUF-15-50-10/*paranoia*/);
371             switch (*cmdptr) {
372                case '%':
373                   switch (*++cmdptr) {
374                      case 'f':
375                         VG_(memcpy)(bufptr, file, VG_(strlen)(file));
376                         bufptr += VG_(strlen)(file);
377                         cmdptr++;
378                         break;
379                      case 'p':
380                         VG_(memcpy)(bufptr, pidbuf, VG_(strlen)(pidbuf));
381                         bufptr += VG_(strlen)(pidbuf);
382                         cmdptr++;
383                         break;
384                      default:
385                         *bufptr++ = *cmdptr++;
386                         break;
387                   }
388                   break;
389                default:
390                   *bufptr++ = *cmdptr++;
391                   break;
392             }
393             vg_assert(bufptr - buf < N_BUF-15-50-10/*paranoia*/);
394          }
395          
396          *bufptr++ = '\0';
397   
398          VG_(message)(Vg_UserMsg, "starting debugger with cmd: %s\n", buf);
399          res = VG_(system)(buf);
400          if (res == 0) {      
401             VG_(message)(Vg_UserMsg, "\n");
402             VG_(message)(Vg_UserMsg, 
403                          "Debugger has detached.  Valgrind regains control."
404                          "  We continue.\n");
405          } else {
406             VG_(message)(Vg_UserMsg, 
407                          "Warning: Debugger attach failed! (sys_system)\n");
408             VG_(message)(Vg_UserMsg, "\n");
409          }
410       } else {
411          VG_(message)(Vg_UserMsg, 
412                       "Warning: Debugger attach failed! (ptrace problem?)\n");
413          VG_(message)(Vg_UserMsg, "\n");
414       }
415
416       VG_(kill)(pid, VKI_SIGKILL);
417       VG_(waitpid)(pid, &status, 0);
418    }
419 #  undef N_BUF
420 }
421
422
423
424 /*--------------------------------------------------------------------*/
425 /*--- end                                                          ---*/
426 /*--------------------------------------------------------------------*/