blob: 2eb6eb2ef2d528c0612e22b4f77f02066fa9b004 [file] [log] [blame]
njn75b65aa2005-06-19 19:25:44 +00001
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
sewardj4d474d02008-02-11 11:34:59 +000010 Copyright (C) 2000-2008 Julian Seward
njn75b65aa2005-06-19 19:25:44 +000011 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"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
njn75b65aa2005-06-19 19:25:44 +000033#include "pub_core_threadstate.h"
sewardj14c7cc52007-02-25 15:08:24 +000034#include "pub_core_xarray.h"
sewardj45f4e7c2005-09-27 19:20:21 +000035#include "pub_core_clientstate.h"
njn75b65aa2005-06-19 19:25:44 +000036#include "pub_core_debugger.h"
37#include "pub_core_libcbase.h"
njn75b65aa2005-06-19 19:25:44 +000038#include "pub_core_libcprint.h"
39#include "pub_core_libcproc.h"
40#include "pub_core_libcsignal.h"
sewardj2c48c7b2005-11-29 13:05:56 +000041#include "pub_core_libcassert.h"
njn75b65aa2005-06-19 19:25:44 +000042#include "pub_core_options.h"
43
sewardjccc89d92005-11-09 14:43:03 +000044
sewardj45f4e7c2005-09-27 19:20:21 +000045#define WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
46#define WSTOPSIG(status) (((status) & 0xff00) >> 8)
njn75b65aa2005-06-19 19:25:44 +000047
48static Int ptrace_setregs(Int pid, VexGuestArchState* vex)
49{
sewardj957ee5d2006-10-17 01:54:20 +000050#if defined(VGP_x86_linux)
sewardjc9e73dc2005-11-09 15:14:16 +000051 struct vki_user_regs_struct regs;
sewardj0313b1e2007-11-19 14:54:09 +000052 VG_(memset)(&regs, 0, sizeof(regs));
njn75b65aa2005-06-19 19:25:44 +000053 regs.cs = vex->guest_CS;
54 regs.ss = vex->guest_SS;
55 regs.ds = vex->guest_DS;
56 regs.es = vex->guest_ES;
57 regs.fs = vex->guest_FS;
58 regs.gs = vex->guest_GS;
59 regs.eax = vex->guest_EAX;
60 regs.ebx = vex->guest_EBX;
61 regs.ecx = vex->guest_ECX;
62 regs.edx = vex->guest_EDX;
63 regs.esi = vex->guest_ESI;
64 regs.edi = vex->guest_EDI;
65 regs.ebp = vex->guest_EBP;
66 regs.esp = vex->guest_ESP;
67 regs.eflags = LibVEX_GuestX86_get_eflags(vex);
68 regs.eip = vex->guest_EIP;
sewardj45f4e7c2005-09-27 19:20:21 +000069 return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &regs);
sewardjc9e73dc2005-11-09 15:14:16 +000070
sewardj957ee5d2006-10-17 01:54:20 +000071#elif defined(VGP_amd64_linux)
sewardjc9e73dc2005-11-09 15:14:16 +000072 struct vki_user_regs_struct regs;
sewardj0313b1e2007-11-19 14:54:09 +000073 VG_(memset)(&regs, 0, sizeof(regs));
tome4fed1c2005-07-19 18:19:48 +000074 regs.rax = vex->guest_RAX;
75 regs.rbx = vex->guest_RBX;
76 regs.rcx = vex->guest_RCX;
77 regs.rdx = vex->guest_RDX;
78 regs.rsi = vex->guest_RSI;
79 regs.rdi = vex->guest_RDI;
80 regs.rbp = vex->guest_RBP;
81 regs.rsp = vex->guest_RSP;
82 regs.r8 = vex->guest_R8;
83 regs.r9 = vex->guest_R9;
84 regs.r10 = vex->guest_R10;
85 regs.r11 = vex->guest_R11;
86 regs.r12 = vex->guest_R12;
87 regs.r13 = vex->guest_R13;
88 regs.r14 = vex->guest_R14;
89 regs.r15 = vex->guest_R15;
90 regs.eflags = LibVEX_GuestAMD64_get_rflags(vex);
91 regs.rip = vex->guest_RIP;
sewardjfc9bf722007-11-19 00:58:18 +000092 /* Set %{c,d,e,f,s,g}s and %{fs,gs}_base (whatever those are) to
93 values which don't fail the kernel's sanity checks. I have no
94 idea what these should really be set to. Anyway, mostly it
95 seems that zero is an allowable value, except for %cs and %ss
96 which have to have their lowest 2 bits be 11. See putreg() in
97 linux-2.6.23/arch/x86_64/kernel/ptrace.c for the apparently
98 relevant sanity checks. This fixes #145622. */
99 regs.cs = 3;
100 regs.ds = 0;
101 regs.es = 0;
102 regs.fs = 0;
103 regs.ss = 3;
104 regs.gs = 0;
105 regs.fs_base = 0;
106 regs.gs_base = 0;
sewardj45f4e7c2005-09-27 19:20:21 +0000107 return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &regs);
sewardjc9e73dc2005-11-09 15:14:16 +0000108
sewardj957ee5d2006-10-17 01:54:20 +0000109#elif defined(VGP_ppc32_linux)
tom01093222005-11-09 08:52:56 +0000110 Int rc = 0;
sewardjc9e73dc2005-11-09 15:14:16 +0000111 /* apparently the casting to void* is the Right Thing To Do */
112 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R0 * 4), (void*)vex->guest_GPR0);
113 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R1 * 4), (void*)vex->guest_GPR1);
114 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R2 * 4), (void*)vex->guest_GPR2);
115 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R3 * 4), (void*)vex->guest_GPR3);
116 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R4 * 4), (void*)vex->guest_GPR4);
117 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R5 * 4), (void*)vex->guest_GPR5);
118 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R6 * 4), (void*)vex->guest_GPR6);
119 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R7 * 4), (void*)vex->guest_GPR7);
120 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R8 * 4), (void*)vex->guest_GPR8);
121 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R9 * 4), (void*)vex->guest_GPR9);
122 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R10 * 4), (void*)vex->guest_GPR10);
123 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R11 * 4), (void*)vex->guest_GPR11);
124 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R12 * 4), (void*)vex->guest_GPR12);
125 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R13 * 4), (void*)vex->guest_GPR13);
126 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R14 * 4), (void*)vex->guest_GPR14);
127 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R15 * 4), (void*)vex->guest_GPR15);
128 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R16 * 4), (void*)vex->guest_GPR16);
129 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R17 * 4), (void*)vex->guest_GPR17);
130 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R18 * 4), (void*)vex->guest_GPR18);
131 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R19 * 4), (void*)vex->guest_GPR19);
132 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R20 * 4), (void*)vex->guest_GPR20);
133 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R21 * 4), (void*)vex->guest_GPR21);
134 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R22 * 4), (void*)vex->guest_GPR22);
135 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R23 * 4), (void*)vex->guest_GPR23);
136 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R24 * 4), (void*)vex->guest_GPR24);
137 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R25 * 4), (void*)vex->guest_GPR25);
138 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R26 * 4), (void*)vex->guest_GPR26);
139 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R27 * 4), (void*)vex->guest_GPR27);
140 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R28 * 4), (void*)vex->guest_GPR28);
141 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R29 * 4), (void*)vex->guest_GPR29);
142 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R30 * 4), (void*)vex->guest_GPR30);
143 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R31 * 4), (void*)vex->guest_GPR31);
144 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_NIP * 4), (void*)vex->guest_CIA);
145 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CCR * 4),
146 (void*)LibVEX_GuestPPC32_get_CR(vex));
147 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_LNK * 4), (void*)vex->guest_LR);
148 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CTR * 4), (void*)vex->guest_CTR);
149 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_XER * 4),
150 (void*)LibVEX_GuestPPC32_get_XER(vex));
tom01093222005-11-09 08:52:56 +0000151 return rc;
sewardjc9e73dc2005-11-09 15:14:16 +0000152
sewardj957ee5d2006-10-17 01:54:20 +0000153#elif defined(VGP_ppc64_linux)
sewardj62c9aa72007-11-19 02:29:07 +0000154 Int rc = 0;
155 /* FRJ: copied nearly verbatim from the ppc32 case. I compared the
156 vki-ppc64-linux.h with its ppc32 counterpart and saw no
157 appreciable differences, other than the registers being 8 bytes
158 instead of 4. No idea why we don't set all of the entries
159 declared in vki_pt_regs, but ppc32 doesn't so there must be a
160 reason.
161
162 Finally, note that CR and XER are 32 bits even for ppc64 (see
163 libvex_guest_ppc64.h), but the vki_pt_regs struct still gives
164 them 64 bits.
165 */
166 /* apparently the casting to void* is the Right Thing To Do */
167 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R0 * 8), (void*)vex->guest_GPR0);
168 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R1 * 8), (void*)vex->guest_GPR1);
169 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R2 * 8), (void*)vex->guest_GPR2);
170 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R3 * 8), (void*)vex->guest_GPR3);
171 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R4 * 8), (void*)vex->guest_GPR4);
172 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R5 * 8), (void*)vex->guest_GPR5);
173 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R6 * 8), (void*)vex->guest_GPR6);
174 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R7 * 8), (void*)vex->guest_GPR7);
175 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R8 * 8), (void*)vex->guest_GPR8);
176 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R9 * 8), (void*)vex->guest_GPR9);
177 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R10 * 8), (void*)vex->guest_GPR10);
178 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R11 * 8), (void*)vex->guest_GPR11);
179 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R12 * 8), (void*)vex->guest_GPR12);
180 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R13 * 8), (void*)vex->guest_GPR13);
181 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R14 * 8), (void*)vex->guest_GPR14);
182 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R15 * 8), (void*)vex->guest_GPR15);
183 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R16 * 8), (void*)vex->guest_GPR16);
184 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R17 * 8), (void*)vex->guest_GPR17);
185 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R18 * 8), (void*)vex->guest_GPR18);
186 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R19 * 8), (void*)vex->guest_GPR19);
187 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R20 * 8), (void*)vex->guest_GPR20);
188 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R21 * 8), (void*)vex->guest_GPR21);
189 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R22 * 8), (void*)vex->guest_GPR22);
190 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R23 * 8), (void*)vex->guest_GPR23);
191 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R24 * 8), (void*)vex->guest_GPR24);
192 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R25 * 8), (void*)vex->guest_GPR25);
193 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R26 * 8), (void*)vex->guest_GPR26);
194 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R27 * 8), (void*)vex->guest_GPR27);
195 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R28 * 8), (void*)vex->guest_GPR28);
196 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R29 * 8), (void*)vex->guest_GPR29);
197 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R30 * 8), (void*)vex->guest_GPR30);
198 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_R31 * 8), (void*)vex->guest_GPR31);
199 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_NIP * 8), (void*)vex->guest_CIA);
200 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CCR * 8),
201 (void*)(long)LibVEX_GuestPPC64_get_CR(vex));
202 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_LNK * 8), (void*)vex->guest_LR);
203 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_CTR * 8), (void*)vex->guest_CTR);
204 rc |= VG_(ptrace)(VKI_PTRACE_POKEUSR, pid, (void*)(VKI_PT_XER * 8),
205 (void*)(long)LibVEX_GuestPPC64_get_XER(vex));
206 return rc;
sewardj957ee5d2006-10-17 01:54:20 +0000207
208#elif defined(VGP_ppc32_aix5)
209 I_die_here;
210
211#elif defined(VGP_ppc64_aix5)
sewardj2c48c7b2005-11-29 13:05:56 +0000212 I_die_here;
213
njn75b65aa2005-06-19 19:25:44 +0000214#else
215# error Unknown arch
216#endif
217}
218
219/* Start debugger and get it to attach to this process. Called if the
220 user requests this service after an error has been shown, so she can
221 poke around and look at parameters, memory, etc. You can't
222 meaningfully get the debugger to continue the program, though; to
223 continue, quit the debugger. */
224void VG_(start_debugger) ( ThreadId tid )
225{
sewardj72892742005-12-18 03:22:50 +0000226# define N_BUF 4096
sewardj7d7ddd22007-11-19 02:01:01 +0000227 Int pid, rc;
njn75b65aa2005-06-19 19:25:44 +0000228
sewardj7d7ddd22007-11-19 02:01:01 +0000229 pid = VG_(fork)();
230
231 if (pid == 0) {
sewardj7d7ddd22007-11-19 02:01:01 +0000232 /* child */
233 rc = VG_(ptrace)(VKI_PTRACE_TRACEME, 0, NULL, NULL);
234 vg_assert(rc == 0);
235 rc = VG_(kill)(VG_(getpid)(), VKI_SIGSTOP);
236 vg_assert(rc == 0);
njn75b65aa2005-06-19 19:25:44 +0000237
238 } else if (pid > 0) {
sewardj7d7ddd22007-11-19 02:01:01 +0000239 /* parent */
njn75b65aa2005-06-19 19:25:44 +0000240 Int status;
241 Int res;
242
243 if ((res = VG_(waitpid)(pid, &status, 0)) == pid &&
sewardj45f4e7c2005-09-27 19:20:21 +0000244 WIFSTOPPED(status) && WSTOPSIG(status) == VKI_SIGSTOP &&
njn75b65aa2005-06-19 19:25:44 +0000245 ptrace_setregs(pid, &(VG_(threads)[tid].arch.vex)) == 0 &&
sewardj45f4e7c2005-09-27 19:20:21 +0000246 VG_(kill)(pid, VKI_SIGSTOP) == 0 &&
247 VG_(ptrace)(VKI_PTRACE_DETACH, pid, NULL, 0) == 0)
njn75b65aa2005-06-19 19:25:44 +0000248 {
249 Char pidbuf[15];
sewardj72892742005-12-18 03:22:50 +0000250 Char file[50];
251 Char buf[N_BUF];
njn75b65aa2005-06-19 19:25:44 +0000252 Char *bufptr;
253 Char *cmdptr;
254
255 VG_(sprintf)(pidbuf, "%d", pid);
sewardj45f4e7c2005-09-27 19:20:21 +0000256 VG_(sprintf)(file, "/proc/%d/fd/%d", pid, VG_(cl_exec_fd));
njn75b65aa2005-06-19 19:25:44 +0000257
258 bufptr = buf;
259 cmdptr = VG_(clo_db_command);
260
261 while (*cmdptr) {
sewardj72892742005-12-18 03:22:50 +0000262 /* each iteration can advance bufptr by at most the length
263 of file[], so the following assertion is generously
264 over-paranoid. */
265 vg_assert(bufptr - buf < N_BUF-15-50-10/*paranoia*/);
njn75b65aa2005-06-19 19:25:44 +0000266 switch (*cmdptr) {
267 case '%':
268 switch (*++cmdptr) {
269 case 'f':
270 VG_(memcpy)(bufptr, file, VG_(strlen)(file));
271 bufptr += VG_(strlen)(file);
272 cmdptr++;
273 break;
sewardj72892742005-12-18 03:22:50 +0000274 case 'p':
275 VG_(memcpy)(bufptr, pidbuf, VG_(strlen)(pidbuf));
276 bufptr += VG_(strlen)(pidbuf);
277 cmdptr++;
278 break;
279 default:
280 *bufptr++ = *cmdptr++;
281 break;
njn75b65aa2005-06-19 19:25:44 +0000282 }
283 break;
284 default:
285 *bufptr++ = *cmdptr++;
286 break;
287 }
sewardj72892742005-12-18 03:22:50 +0000288 vg_assert(bufptr - buf < N_BUF-15-50-10/*paranoia*/);
njn75b65aa2005-06-19 19:25:44 +0000289 }
290
291 *bufptr++ = '\0';
292
293 VG_(message)(Vg_UserMsg, "starting debugger with cmd: %s", buf);
294 res = VG_(system)(buf);
295 if (res == 0) {
296 VG_(message)(Vg_UserMsg, "");
297 VG_(message)(Vg_UserMsg,
sewardj5b9b4412007-11-24 21:24:25 +0000298 "Debugger has detached. Valgrind regains control."
299 " We continue.");
njn75b65aa2005-06-19 19:25:44 +0000300 } else {
sewardj5b9b4412007-11-24 21:24:25 +0000301 VG_(message)(Vg_UserMsg,
302 "Warning: Debugger attach failed! (sys_system)");
njn75b65aa2005-06-19 19:25:44 +0000303 VG_(message)(Vg_UserMsg, "");
304 }
sewardj5b9b4412007-11-24 21:24:25 +0000305 } else {
306 VG_(message)(Vg_UserMsg,
307 "Warning: Debugger attach failed! (ptrace problem?)");
308 VG_(message)(Vg_UserMsg, "");
njn75b65aa2005-06-19 19:25:44 +0000309 }
310
311 VG_(kill)(pid, VKI_SIGKILL);
312 VG_(waitpid)(pid, &status, 0);
313 }
sewardj72892742005-12-18 03:22:50 +0000314# undef N_BUF
njn75b65aa2005-06-19 19:25:44 +0000315}
316
317
318
319/*--------------------------------------------------------------------*/
320/*--- end ---*/
321/*--------------------------------------------------------------------*/