inf-ptrace.c revision 1.12 1 1.1 christos /* Low-level child interface to ptrace.
2 1.1 christos
3 1.11 christos Copyright (C) 1988-2024 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "command.h"
21 1.1 christos #include "inferior.h"
22 1.1 christos #include "terminal.h"
23 1.1 christos #include "gdbcore.h"
24 1.1 christos #include "regcache.h"
25 1.6 christos #include "nat/gdb_ptrace.h"
26 1.9 christos #include "gdbsupport/gdb_wait.h"
27 1.1 christos #include <signal.h>
28 1.1 christos
29 1.1 christos #include "inf-ptrace.h"
30 1.1 christos #include "inf-child.h"
31 1.1 christos #include "gdbthread.h"
32 1.8 christos #include "nat/fork-inferior.h"
33 1.8 christos #include "utils.h"
34 1.9 christos #include "gdbarch.h"
35 1.12 christos #include "gdbsupport/eintr.h"
36 1.1 christos
37 1.1 christos
38 1.1 christos
40 1.9 christos static PTRACE_TYPE_RET
41 1.9 christos gdb_ptrace (PTRACE_TYPE_ARG1 request, ptid_t ptid, PTRACE_TYPE_ARG3 addr,
42 1.9 christos PTRACE_TYPE_ARG4 data)
43 1.9 christos {
44 1.10 christos #ifdef __NetBSD__
45 1.10 christos /*
46 1.10 christos * On NetBSD the data field of PT_STEP contains the thread
47 1.10 christos * to be stepped; all other threads are continued if this value is > 0
48 1.10 christos */
49 1.10 christos if (request == PT_STEP)
50 1.9 christos data = ptid.lwp ();
51 1.9 christos return ptrace (request, ptid.pid (), addr, data);
52 1.9 christos #else
53 1.9 christos pid_t pid = get_ptrace_pid (ptid);
54 1.9 christos return ptrace (request, pid, addr, data);
55 1.9 christos #endif
56 1.9 christos }
57 1.10 christos
58 1.10 christos /* The event pipe registered as a waitable file in the event loop. */
59 1.8 christos event_pipe inf_ptrace_target::m_event_pipe;
60 1.8 christos
61 1.8 christos inf_ptrace_target::~inf_ptrace_target ()
62 1.8 christos {}
63 1.1 christos
64 1.1 christos
65 1.1 christos
67 1.1 christos /* Prepare to be traced. */
68 1.1 christos
69 1.1 christos static void
70 1.1 christos inf_ptrace_me (void)
71 1.7 christos {
72 1.7 christos /* "Trace me, Dr. Memory!" */
73 1.1 christos if (ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3) 0, 0) < 0)
74 1.1 christos trace_start_error_with_name ("ptrace");
75 1.1 christos }
76 1.1 christos
77 1.1 christos /* Start a new inferior Unix child process. EXEC_FILE is the file to
78 1.1 christos run, ALLARGS is a string containing the arguments to the program.
79 1.1 christos ENV is the environment vector to pass. If FROM_TTY is non-zero, be
80 1.8 christos chatty about it. */
81 1.8 christos
82 1.8 christos void
83 1.8 christos inf_ptrace_target::create_inferior (const char *exec_file,
84 1.1 christos const std::string &allargs,
85 1.12 christos char **env, int from_tty)
86 1.12 christos {
87 1.12 christos if (exec_file == nullptr)
88 1.10 christos no_executable_specified_error ();
89 1.10 christos
90 1.1 christos inferior *inf = current_inferior ();
91 1.1 christos
92 1.10 christos /* Do not change either targets above or the same target if already present.
93 1.1 christos The reason is the target stack is shared across multiple inferiors. */
94 1.8 christos int ops_already_pushed = inf->target_is_pushed (this);
95 1.1 christos
96 1.1 christos target_unpush_up unpusher;
97 1.1 christos if (! ops_already_pushed)
98 1.10 christos {
99 1.8 christos /* Clear possible core file with its process_stratum. */
100 1.1 christos inf->push_target (this);
101 1.1 christos unpusher.reset (this);
102 1.9 christos }
103 1.9 christos
104 1.1 christos pid_t pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
105 1.9 christos NULL, NULL, NULL);
106 1.8 christos
107 1.8 christos ptid_t ptid (pid);
108 1.8 christos /* We have something that executes now. We'll be running through
109 1.9 christos the shell at this point (if startup-with-shell is true), but the
110 1.9 christos pid shouldn't change. */
111 1.8 christos thread_info *thr = add_thread_silent (this, ptid);
112 1.8 christos switch_to_thread (thr);
113 1.1 christos
114 1.8 christos unpusher.release ();
115 1.1 christos
116 1.1 christos gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
117 1.1 christos
118 1.10 christos /* On some targets, there must be some explicit actions taken after
119 1.1 christos the inferior has been started up. */
120 1.1 christos post_startup_inferior (ptid);
121 1.1 christos }
122 1.1 christos
123 1.8 christos /* Clean up a rotting corpse of an inferior after it died. */
124 1.8 christos
125 1.1 christos void
126 1.1 christos inf_ptrace_target::mourn_inferior ()
127 1.1 christos {
128 1.1 christos int status;
129 1.1 christos
130 1.1 christos /* Wait just one more time to collect the inferior's exit status.
131 1.1 christos Do not check whether this succeeds though, since we may be
132 1.12 christos dealing with a process that we attached to. Such a process will
133 1.1 christos only report its exit status to its original parent. */
134 1.8 christos gdb::waitpid (inferior_ptid.pid (), &status, 0);
135 1.1 christos
136 1.1 christos inf_child_target::mourn_inferior ();
137 1.1 christos }
138 1.1 christos
139 1.1 christos /* Attach to the process specified by ARGS. If FROM_TTY is non-zero,
140 1.8 christos be chatty about it. */
141 1.8 christos
142 1.1 christos void
143 1.10 christos inf_ptrace_target::attach (const char *args, int from_tty)
144 1.1 christos {
145 1.1 christos inferior *inf = current_inferior ();
146 1.1 christos
147 1.10 christos /* Do not change either targets above or the same target if already present.
148 1.1 christos The reason is the target stack is shared across multiple inferiors. */
149 1.10 christos int ops_already_pushed = inf->target_is_pushed (this);
150 1.1 christos
151 1.12 christos pid_t pid = parse_pid_to_attach (args);
152 1.1 christos
153 1.1 christos if (pid == getpid ())
154 1.8 christos error (_("I refuse to debug myself!"));
155 1.1 christos
156 1.1 christos target_unpush_up unpusher;
157 1.1 christos if (! ops_already_pushed)
158 1.1 christos {
159 1.10 christos /* target_pid_to_str already uses the target. Also clear possible core
160 1.8 christos file with its process_stratum. */
161 1.1 christos inf->push_target (this);
162 1.1 christos unpusher.reset (this);
163 1.10 christos }
164 1.1 christos
165 1.1 christos target_announce_attach (from_tty, pid);
166 1.1 christos
167 1.1 christos #ifdef PT_ATTACH
168 1.1 christos errno = 0;
169 1.1 christos ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
170 1.1 christos if (errno != 0)
171 1.1 christos perror_with_name (("ptrace"));
172 1.1 christos #else
173 1.1 christos error (_("This system does not support attaching to a process"));
174 1.1 christos #endif
175 1.10 christos
176 1.1 christos inferior_appeared (inf, pid);
177 1.1 christos inf->attach_flag = true;
178 1.1 christos
179 1.9 christos /* Always add a main thread. If some target extends the ptrace
180 1.9 christos target, it should decorate the ptid later with more info. */
181 1.9 christos thread_info *thr = add_thread_silent (this, ptid_t (pid));
182 1.8 christos switch_to_thread (thr);
183 1.8 christos
184 1.9 christos /* Don't consider the thread stopped until we've processed its
185 1.1 christos initial SIGSTOP stop. */
186 1.8 christos set_executing (this, thr->ptid, true);
187 1.1 christos
188 1.1 christos unpusher.release ();
189 1.8 christos }
190 1.1 christos
191 1.8 christos /* Detach from the inferior. If FROM_TTY is non-zero, be chatty about it. */
192 1.8 christos
193 1.1 christos void
194 1.8 christos inf_ptrace_target::detach (inferior *inf, int from_tty)
195 1.1 christos {
196 1.6 christos pid_t pid = inferior_ptid.pid ();
197 1.1 christos
198 1.1 christos target_announce_detach (from_tty);
199 1.1 christos
200 1.1 christos #ifdef PT_DETACH
201 1.1 christos /* We'd better not have left any breakpoints in the program or it'll
202 1.1 christos die when it hits one. Also note that this may only work if we
203 1.1 christos previously attached to the inferior. It *might* work if we
204 1.8 christos started the process ourselves. */
205 1.1 christos errno = 0;
206 1.1 christos ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0);
207 1.1 christos if (errno != 0)
208 1.1 christos perror_with_name (("ptrace"));
209 1.1 christos #else
210 1.1 christos error (_("This system does not support detaching from a process"));
211 1.8 christos #endif
212 1.6 christos
213 1.6 christos detach_success (inf);
214 1.6 christos }
215 1.6 christos
216 1.6 christos /* See inf-ptrace.h. */
217 1.8 christos
218 1.6 christos void
219 1.9 christos inf_ptrace_target::detach_success (inferior *inf)
220 1.8 christos {
221 1.1 christos switch_to_no_thread ();
222 1.8 christos detach_inferior (inf);
223 1.1 christos
224 1.1 christos maybe_unpush_target ();
225 1.1 christos }
226 1.1 christos
227 1.8 christos /* Kill the inferior. */
228 1.8 christos
229 1.1 christos void
230 1.8 christos inf_ptrace_target::kill ()
231 1.1 christos {
232 1.1 christos pid_t pid = inferior_ptid.pid ();
233 1.1 christos int status;
234 1.1 christos
235 1.1 christos if (pid == 0)
236 1.1 christos return;
237 1.12 christos
238 1.1 christos ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0);
239 1.7 christos gdb::waitpid (pid, &status, 0);
240 1.1 christos
241 1.1 christos target_mourn_inferior (inferior_ptid);
242 1.9 christos }
243 1.9 christos
244 1.9 christos #ifndef __NetBSD__
245 1.5 christos
246 1.6 christos /* See inf-ptrace.h. */
247 1.5 christos
248 1.5 christos pid_t
249 1.5 christos get_ptrace_pid (ptid_t ptid)
250 1.5 christos {
251 1.5 christos pid_t pid;
252 1.5 christos
253 1.8 christos /* If we have an LWPID to work with, use it. Otherwise, we're
254 1.5 christos dealing with a non-threaded program/target. */
255 1.8 christos pid = ptid.lwp ();
256 1.5 christos if (pid == 0)
257 1.5 christos pid = ptid.pid ();
258 1.9 christos return pid;
259 1.5 christos }
260 1.1 christos #endif
261 1.1 christos
262 1.1 christos /* Resume execution of thread PTID, or all threads if PTID is -1. If
263 1.1 christos STEP is nonzero, single-step it. If SIGNAL is nonzero, give it
264 1.8 christos that signal. */
265 1.8 christos
266 1.1 christos void
267 1.9 christos inf_ptrace_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
268 1.1 christos {
269 1.8 christos PTRACE_TYPE_ARG1 request;
270 1.1 christos
271 1.1 christos if (minus_one_ptid == ptid)
272 1.9 christos /* Resume all threads. Traditionally ptrace() only supports
273 1.1 christos single-threaded processes, so simply resume the inferior. */
274 1.11 christos ptid = ptid_t (inferior_ptid.pid ());
275 1.1 christos
276 1.1 christos if (catch_syscall_enabled ())
277 1.1 christos request = PT_SYSCALL;
278 1.1 christos else
279 1.1 christos request = PT_CONTINUE;
280 1.1 christos
281 1.1 christos if (step)
282 1.9 christos {
283 1.9 christos /* If this system does not support PT_STEP, a higher level
284 1.9 christos function will have called the appropriate functions to transmute the
285 1.9 christos step request into a continue request (by setting breakpoints on
286 1.1 christos all possible successor instructions), so we don't have to
287 1.9 christos worry about that here. */
288 1.1 christos request = PT_STEP;
289 1.1 christos }
290 1.1 christos
291 1.1 christos /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
292 1.1 christos where it was. If GDB wanted it to start some other way, we have
293 1.9 christos already written a new program counter value to the child. */
294 1.1 christos errno = 0;
295 1.1 christos gdb_ptrace (request, ptid, (PTRACE_TYPE_ARG3)1, gdb_signal_to_host (signal));
296 1.1 christos if (errno != 0)
297 1.1 christos perror_with_name (("ptrace"));
298 1.1 christos }
299 1.1 christos
300 1.1 christos /* Wait for the child specified by PTID to do something. Return the
301 1.1 christos process ID of the child, or MINUS_ONE_PTID in case of error; store
302 1.8 christos the status in *OURSTATUS. */
303 1.8 christos
304 1.10 christos ptid_t
305 1.1 christos inf_ptrace_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
306 1.1 christos target_wait_flags target_options)
307 1.10 christos {
308 1.10 christos pid_t pid;
309 1.10 christos int options, status, save_errno;
310 1.10 christos
311 1.10 christos options = 0;
312 1.1 christos if (target_options & TARGET_WNOHANG)
313 1.1 christos options |= WNOHANG;
314 1.1 christos
315 1.1 christos do
316 1.1 christos {
317 1.12 christos set_sigint_trap ();
318 1.12 christos
319 1.1 christos pid = gdb::waitpid (ptid.pid (), &status, options);
320 1.1 christos save_errno = errno;
321 1.1 christos
322 1.10 christos clear_sigint_trap ();
323 1.10 christos
324 1.10 christos if (pid == 0)
325 1.10 christos {
326 1.10 christos gdb_assert (target_options & TARGET_WNOHANG);
327 1.10 christos ourstatus->set_ignore ();
328 1.10 christos return minus_one_ptid;
329 1.1 christos }
330 1.1 christos
331 1.10 christos if (pid == -1)
332 1.10 christos {
333 1.10 christos /* In async mode the SIGCHLD might have raced and triggered
334 1.10 christos a check for an event that had already been reported. If
335 1.10 christos the event was the exit of the only remaining child,
336 1.10 christos waitpid() will fail with ECHILD. */
337 1.10 christos if (ptid == minus_one_ptid && save_errno == ECHILD)
338 1.10 christos {
339 1.10 christos ourstatus->set_no_resumed ();
340 1.10 christos return minus_one_ptid;
341 1.10 christos }
342 1.10 christos
343 1.10 christos gdb_printf (gdb_stderr,
344 1.10 christos _("Child process unexpectedly missing: %s.\n"),
345 1.10 christos safe_strerror (save_errno));
346 1.10 christos
347 1.1 christos ourstatus->set_ignore ();
348 1.1 christos return minus_one_ptid;
349 1.1 christos }
350 1.9 christos
351 1.1 christos /* Ignore terminated detached child processes. */
352 1.1 christos if (!WIFSTOPPED (status) && find_inferior_pid (this, pid) == nullptr)
353 1.1 christos pid = -1;
354 1.1 christos }
355 1.10 christos while (pid == -1);
356 1.10 christos
357 1.8 christos *ourstatus = host_status_to_waitstatus (status);
358 1.1 christos
359 1.1 christos return ptid_t (pid);
360 1.7 christos }
361 1.7 christos
362 1.7 christos /* Transfer data via ptrace into process PID's memory from WRITEBUF, or
363 1.7 christos from process PID's memory into READBUF. Start at target address ADDR
364 1.7 christos and transfer up to LEN bytes. Exactly one of READBUF and WRITEBUF must
365 1.7 christos be non-null. Return the number of transferred bytes. */
366 1.9 christos
367 1.7 christos static ULONGEST
368 1.7 christos inf_ptrace_peek_poke (ptid_t ptid, gdb_byte *readbuf,
369 1.7 christos const gdb_byte *writebuf,
370 1.7 christos ULONGEST addr, ULONGEST len)
371 1.7 christos {
372 1.7 christos ULONGEST n;
373 1.7 christos unsigned int chunk;
374 1.7 christos
375 1.7 christos /* We transfer aligned words. Thus align ADDR down to a word
376 1.7 christos boundary and determine how many bytes to skip at the
377 1.7 christos beginning. */
378 1.7 christos ULONGEST skip = addr & (sizeof (PTRACE_TYPE_RET) - 1);
379 1.7 christos addr -= skip;
380 1.7 christos
381 1.7 christos for (n = 0;
382 1.7 christos n < len;
383 1.7 christos n += chunk, addr += sizeof (PTRACE_TYPE_RET), skip = 0)
384 1.7 christos {
385 1.7 christos /* Restrict to a chunk that fits in the current word. */
386 1.7 christos chunk = std::min (sizeof (PTRACE_TYPE_RET) - skip, len - n);
387 1.7 christos
388 1.7 christos /* Use a union for type punning. */
389 1.7 christos union
390 1.7 christos {
391 1.7 christos PTRACE_TYPE_RET word;
392 1.7 christos gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
393 1.7 christos } buf;
394 1.7 christos
395 1.7 christos /* Read the word, also when doing a partial word write. */
396 1.7 christos if (readbuf != NULL || chunk < sizeof (PTRACE_TYPE_RET))
397 1.9 christos {
398 1.9 christos errno = 0;
399 1.7 christos buf.word = gdb_ptrace (PT_READ_I, ptid,
400 1.7 christos (PTRACE_TYPE_ARG3)(uintptr_t) addr, 0);
401 1.7 christos if (errno != 0)
402 1.7 christos break;
403 1.7 christos if (readbuf != NULL)
404 1.7 christos memcpy (readbuf + n, buf.byte + skip, chunk);
405 1.7 christos }
406 1.7 christos if (writebuf != NULL)
407 1.7 christos {
408 1.9 christos memcpy (buf.byte + skip, writebuf + n, chunk);
409 1.7 christos errno = 0;
410 1.7 christos gdb_ptrace (PT_WRITE_D, ptid, (PTRACE_TYPE_ARG3)(uintptr_t) addr,
411 1.7 christos buf.word);
412 1.7 christos if (errno != 0)
413 1.7 christos {
414 1.7 christos /* Using the appropriate one (I or D) is necessary for
415 1.9 christos Gould NP1, at least. */
416 1.9 christos errno = 0;
417 1.7 christos gdb_ptrace (PT_WRITE_I, ptid, (PTRACE_TYPE_ARG3)(uintptr_t) addr,
418 1.7 christos buf.word);
419 1.7 christos if (errno != 0)
420 1.7 christos break;
421 1.7 christos }
422 1.7 christos }
423 1.7 christos }
424 1.7 christos
425 1.7 christos return n;
426 1.3 christos }
427 1.1 christos
428 1.8 christos /* Implement the to_xfer_partial target_ops method. */
429 1.8 christos
430 1.8 christos enum target_xfer_status
431 1.8 christos inf_ptrace_target::xfer_partial (enum target_object object,
432 1.8 christos const char *annex, gdb_byte *readbuf,
433 1.1 christos const gdb_byte *writebuf,
434 1.9 christos ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
435 1.1 christos {
436 1.1 christos ptid_t ptid = inferior_ptid;
437 1.1 christos
438 1.1 christos switch (object)
439 1.1 christos {
440 1.1 christos case TARGET_OBJECT_MEMORY:
441 1.1 christos #ifdef PT_IO
442 1.1 christos /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO
443 1.1 christos request that promises to be much more efficient in reading
444 1.1 christos and writing data in the traced process's address space. */
445 1.1 christos {
446 1.1 christos struct ptrace_io_desc piod;
447 1.1 christos
448 1.1 christos /* NOTE: We assume that there are no distinct address spaces
449 1.1 christos for instruction and data. However, on OpenBSD 3.9 and
450 1.1 christos later, PIOD_WRITE_D doesn't allow changing memory that's
451 1.1 christos mapped read-only. Since most code segments will be
452 1.1 christos read-only, using PIOD_WRITE_D will prevent us from
453 1.1 christos inserting breakpoints, so we use PIOD_WRITE_I instead. */
454 1.1 christos piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D;
455 1.1 christos piod.piod_addr = writebuf ? (void *) writebuf : readbuf;
456 1.1 christos piod.piod_offs = (void *) (long) offset;
457 1.1 christos piod.piod_len = len;
458 1.9 christos
459 1.3 christos errno = 0;
460 1.3 christos if (gdb_ptrace (PT_IO, ptid, (caddr_t)&piod, 0) == 0)
461 1.3 christos {
462 1.3 christos /* Return the actual number of bytes read or written. */
463 1.3 christos *xfered_len = piod.piod_len;
464 1.1 christos return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
465 1.1 christos }
466 1.1 christos /* If the PT_IO request is somehow not supported, fallback on
467 1.1 christos using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
468 1.3 christos to indicate failure. */
469 1.1 christos if (errno != EINVAL)
470 1.1 christos return TARGET_XFER_EOF;
471 1.9 christos }
472 1.7 christos #endif
473 1.7 christos *xfered_len = inf_ptrace_peek_poke (ptid, readbuf, writebuf,
474 1.1 christos offset, len);
475 1.1 christos return *xfered_len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
476 1.3 christos
477 1.1 christos case TARGET_OBJECT_UNWIND_TABLE:
478 1.1 christos return TARGET_XFER_E_IO;
479 1.1 christos
480 1.1 christos case TARGET_OBJECT_AUXV:
481 1.12 christos #if defined (PT_IO) && defined (PIOD_READ_AUXV)
482 1.1 christos /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO
483 1.1 christos request that allows us to read the auxiliary vector. Other
484 1.1 christos BSD's may follow if they feel the need to support PIE. */
485 1.1 christos {
486 1.1 christos struct ptrace_io_desc piod;
487 1.3 christos
488 1.1 christos if (writebuf)
489 1.1 christos return TARGET_XFER_E_IO;
490 1.1 christos piod.piod_op = PIOD_READ_AUXV;
491 1.1 christos piod.piod_addr = readbuf;
492 1.1 christos piod.piod_offs = (void *) (long) offset;
493 1.1 christos piod.piod_len = len;
494 1.9 christos
495 1.3 christos errno = 0;
496 1.3 christos if (gdb_ptrace (PT_IO, ptid, (caddr_t)&piod, 0) == 0)
497 1.3 christos {
498 1.3 christos /* Return the actual number of bytes read or written. */
499 1.3 christos *xfered_len = piod.piod_len;
500 1.1 christos return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
501 1.1 christos }
502 1.3 christos }
503 1.1 christos #endif
504 1.1 christos return TARGET_XFER_E_IO;
505 1.3 christos
506 1.1 christos case TARGET_OBJECT_WCOOKIE:
507 1.1 christos return TARGET_XFER_E_IO;
508 1.3 christos
509 1.1 christos default:
510 1.1 christos return TARGET_XFER_E_IO;
511 1.1 christos }
512 1.1 christos }
513 1.1 christos
514 1.8 christos /* Return non-zero if the thread specified by PTID is alive. */
515 1.8 christos
516 1.1 christos bool
517 1.1 christos inf_ptrace_target::thread_alive (ptid_t ptid)
518 1.8 christos {
519 1.1 christos /* ??? Is kill the right way to do this? */
520 1.1 christos return (::kill (ptid.pid (), 0) != -1);
521 1.1 christos }
522 1.1 christos
523 1.8 christos /* Print status information about what we're accessing. */
524 1.8 christos
525 1.1 christos void
526 1.1 christos inf_ptrace_target::files_info ()
527 1.1 christos {
528 1.10 christos struct inferior *inf = current_inferior ();
529 1.10 christos
530 1.11 christos gdb_printf (_("\tUsing the running image of %s %s.\n"),
531 1.1 christos inf->attach_flag ? "attached" : "child",
532 1.1 christos target_pid_to_str (ptid_t (inf->pid)).c_str ());
533 1.9 christos }
534 1.8 christos
535 1.1 christos std::string
536 1.1 christos inf_ptrace_target::pid_to_str (ptid_t ptid)
537 1.1 christos {
538 1.10 christos return normal_pid_to_str (ptid);
539 1.10 christos }
540 1.10 christos
541 1.10 christos /* Implement the "close" target method. */
542 1.10 christos
543 1.10 christos void
544 1.10 christos inf_ptrace_target::close ()
545 1.10 christos {
546 1.10 christos /* Unregister from the event loop. */
547 1.10 christos if (is_async_p ())
548 1.10 christos async (false);
549 1.10 christos
550 inf_child_target::close ();
551 }
552