inf-ptrace.c revision 1.9 1 1.1 christos /* Low-level child interface to ptrace.
2 1.1 christos
3 1.9 christos Copyright (C) 1988-2020 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 "defs.h"
21 1.1 christos #include "command.h"
22 1.1 christos #include "inferior.h"
23 1.1 christos #include "inflow.h"
24 1.1 christos #include "terminal.h"
25 1.1 christos #include "gdbcore.h"
26 1.1 christos #include "regcache.h"
27 1.6 christos #include "nat/gdb_ptrace.h"
28 1.9 christos #include "gdbsupport/gdb_wait.h"
29 1.1 christos #include <signal.h>
30 1.1 christos
31 1.1 christos #include "inf-ptrace.h"
32 1.1 christos #include "inf-child.h"
33 1.1 christos #include "gdbthread.h"
34 1.8 christos #include "nat/fork-inferior.h"
35 1.8 christos #include "utils.h"
36 1.9 christos #include "gdbarch.h"
37 1.1 christos
38 1.1 christos
39 1.1 christos
41 1.9 christos static PTRACE_TYPE_RET
42 1.9 christos gdb_ptrace (PTRACE_TYPE_ARG1 request, ptid_t ptid, PTRACE_TYPE_ARG3 addr,
43 1.9 christos PTRACE_TYPE_ARG4 data)
44 1.9 christos {
45 1.9 christos #ifdef __NetBSD__
46 1.9 christos return ptrace (request, ptid.pid (), addr, data);
47 1.9 christos #else
48 1.9 christos pid_t pid = get_ptrace_pid (ptid);
49 1.9 christos return ptrace (request, pid, addr, data);
50 1.9 christos #endif
51 1.9 christos }
52 1.8 christos
53 1.8 christos /* A unique_ptr helper to unpush a target. */
54 1.8 christos
55 1.8 christos struct target_unpusher
56 1.8 christos {
57 1.8 christos void operator() (struct target_ops *ops) const
58 1.8 christos {
59 1.8 christos unpush_target (ops);
60 1.8 christos }
61 1.8 christos };
62 1.8 christos
63 1.8 christos /* A unique_ptr that unpushes a target on destruction. */
64 1.8 christos
65 1.8 christos typedef std::unique_ptr<struct target_ops, target_unpusher> target_unpush_up;
66 1.8 christos
67 1.8 christos
68 1.8 christos
70 1.8 christos inf_ptrace_target::~inf_ptrace_target ()
71 1.1 christos {}
72 1.1 christos
73 1.1 christos
74 1.1 christos
76 1.1 christos /* Prepare to be traced. */
77 1.1 christos
78 1.1 christos static void
79 1.7 christos inf_ptrace_me (void)
80 1.7 christos {
81 1.1 christos /* "Trace me, Dr. Memory!" */
82 1.1 christos if (ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3) 0, 0) < 0)
83 1.1 christos trace_start_error_with_name ("ptrace");
84 1.1 christos }
85 1.1 christos
86 1.1 christos /* Start a new inferior Unix child process. EXEC_FILE is the file to
87 1.1 christos run, ALLARGS is a string containing the arguments to the program.
88 1.8 christos ENV is the environment vector to pass. If FROM_TTY is non-zero, be
89 1.8 christos chatty about it. */
90 1.8 christos
91 1.8 christos void
92 1.1 christos inf_ptrace_target::create_inferior (const char *exec_file,
93 1.1 christos const std::string &allargs,
94 1.1 christos char **env, int from_tty)
95 1.8 christos {
96 1.1 christos /* Do not change either targets above or the same target if already present.
97 1.8 christos The reason is the target stack is shared across multiple inferiors. */
98 1.1 christos int ops_already_pushed = target_is_pushed (this);
99 1.1 christos
100 1.1 christos target_unpush_up unpusher;
101 1.8 christos if (! ops_already_pushed)
102 1.8 christos {
103 1.1 christos /* Clear possible core file with its process_stratum. */
104 1.1 christos push_target (this);
105 1.9 christos unpusher.reset (this);
106 1.9 christos }
107 1.1 christos
108 1.9 christos pid_t pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
109 1.8 christos NULL, NULL, NULL);
110 1.8 christos
111 1.8 christos ptid_t ptid (pid);
112 1.9 christos /* We have something that executes now. We'll be running through
113 1.9 christos the shell at this point (if startup-with-shell is true), but the
114 1.8 christos pid shouldn't change. */
115 1.8 christos thread_info *thr = add_thread_silent (this, ptid);
116 1.1 christos switch_to_thread (thr);
117 1.8 christos
118 1.1 christos unpusher.release ();
119 1.1 christos
120 1.1 christos gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
121 1.8 christos
122 1.1 christos /* On some targets, there must be some explicit actions taken after
123 1.1 christos the inferior has been started up. */
124 1.1 christos target_post_startup_inferior (ptid);
125 1.1 christos }
126 1.8 christos
127 1.8 christos /* Clean up a rotting corpse of an inferior after it died. */
128 1.1 christos
129 1.1 christos void
130 1.1 christos inf_ptrace_target::mourn_inferior ()
131 1.1 christos {
132 1.1 christos int status;
133 1.1 christos
134 1.1 christos /* Wait just one more time to collect the inferior's exit status.
135 1.8 christos Do not check whether this succeeds though, since we may be
136 1.1 christos dealing with a process that we attached to. Such a process will
137 1.8 christos only report its exit status to its original parent. */
138 1.1 christos waitpid (inferior_ptid.pid (), &status, 0);
139 1.1 christos
140 1.1 christos inf_child_target::mourn_inferior ();
141 1.1 christos }
142 1.1 christos
143 1.8 christos /* Attach to the process specified by ARGS. If FROM_TTY is non-zero,
144 1.8 christos be chatty about it. */
145 1.1 christos
146 1.1 christos void
147 1.1 christos inf_ptrace_target::attach (const char *args, int from_tty)
148 1.1 christos {
149 1.1 christos pid_t pid;
150 1.1 christos struct inferior *inf;
151 1.8 christos
152 1.1 christos /* Do not change either targets above or the same target if already present.
153 1.1 christos The reason is the target stack is shared across multiple inferiors. */
154 1.1 christos int ops_already_pushed = target_is_pushed (this);
155 1.1 christos
156 1.1 christos pid = parse_pid_to_attach (args);
157 1.1 christos
158 1.8 christos if (pid == getpid ()) /* Trying to masturbate? */
159 1.1 christos error (_("I refuse to debug myself!"));
160 1.1 christos
161 1.1 christos target_unpush_up unpusher;
162 1.1 christos if (! ops_already_pushed)
163 1.8 christos {
164 1.8 christos /* target_pid_to_str already uses the target. Also clear possible core
165 1.1 christos file with its process_stratum. */
166 1.1 christos push_target (this);
167 1.1 christos unpusher.reset (this);
168 1.1 christos }
169 1.9 christos
170 1.1 christos if (from_tty)
171 1.1 christos {
172 1.1 christos const char *exec_file = get_exec_file (0);
173 1.9 christos
174 1.1 christos if (exec_file)
175 1.1 christos printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
176 1.9 christos target_pid_to_str (ptid_t (pid)).c_str ());
177 1.1 christos else
178 1.1 christos printf_unfiltered (_("Attaching to %s\n"),
179 1.1 christos target_pid_to_str (ptid_t (pid)).c_str ());
180 1.1 christos }
181 1.1 christos
182 1.1 christos #ifdef PT_ATTACH
183 1.1 christos errno = 0;
184 1.1 christos ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
185 1.1 christos if (errno != 0)
186 1.1 christos perror_with_name (("ptrace"));
187 1.1 christos #else
188 1.1 christos error (_("This system does not support attaching to a process"));
189 1.1 christos #endif
190 1.1 christos
191 1.1 christos inf = current_inferior ();
192 1.1 christos inferior_appeared (inf, pid);
193 1.1 christos inf->attach_flag = 1;
194 1.9 christos
195 1.9 christos /* Always add a main thread. If some target extends the ptrace
196 1.9 christos target, it should decorate the ptid later with more info. */
197 1.8 christos thread_info *thr = add_thread_silent (this, ptid_t (pid));
198 1.8 christos switch_to_thread (thr);
199 1.9 christos
200 1.1 christos /* Don't consider the thread stopped until we've processed its
201 1.8 christos initial SIGSTOP stop. */
202 1.1 christos set_executing (this, thr->ptid, true);
203 1.1 christos
204 1.8 christos unpusher.release ();
205 1.1 christos }
206 1.8 christos
207 1.8 christos /* Detach from the inferior. If FROM_TTY is non-zero, be chatty about it. */
208 1.1 christos
209 1.8 christos void
210 1.1 christos inf_ptrace_target::detach (inferior *inf, int from_tty)
211 1.6 christos {
212 1.1 christos pid_t pid = inferior_ptid.pid ();
213 1.1 christos
214 1.1 christos target_announce_detach (from_tty);
215 1.1 christos
216 1.1 christos #ifdef PT_DETACH
217 1.1 christos /* We'd better not have left any breakpoints in the program or it'll
218 1.1 christos die when it hits one. Also note that this may only work if we
219 1.8 christos previously attached to the inferior. It *might* work if we
220 1.1 christos started the process ourselves. */
221 1.1 christos errno = 0;
222 1.1 christos ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0);
223 1.1 christos if (errno != 0)
224 1.1 christos perror_with_name (("ptrace"));
225 1.1 christos #else
226 1.8 christos error (_("This system does not support detaching from a process"));
227 1.6 christos #endif
228 1.6 christos
229 1.6 christos detach_success (inf);
230 1.6 christos }
231 1.6 christos
232 1.8 christos /* See inf-ptrace.h. */
233 1.6 christos
234 1.9 christos void
235 1.8 christos inf_ptrace_target::detach_success (inferior *inf)
236 1.1 christos {
237 1.8 christos switch_to_no_thread ();
238 1.1 christos detach_inferior (inf);
239 1.1 christos
240 1.1 christos maybe_unpush_target ();
241 1.1 christos }
242 1.8 christos
243 1.8 christos /* Kill the inferior. */
244 1.1 christos
245 1.8 christos void
246 1.1 christos inf_ptrace_target::kill ()
247 1.1 christos {
248 1.1 christos pid_t pid = inferior_ptid.pid ();
249 1.1 christos int status;
250 1.1 christos
251 1.1 christos if (pid == 0)
252 1.1 christos return;
253 1.1 christos
254 1.7 christos ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0);
255 1.1 christos waitpid (pid, &status, 0);
256 1.1 christos
257 1.9 christos target_mourn_inferior (inferior_ptid);
258 1.9 christos }
259 1.9 christos
260 1.5 christos #ifndef __NetBSD__
261 1.6 christos
262 1.5 christos /* See inf-ptrace.h. */
263 1.5 christos
264 1.5 christos pid_t
265 1.5 christos get_ptrace_pid (ptid_t ptid)
266 1.5 christos {
267 1.5 christos pid_t pid;
268 1.8 christos
269 1.5 christos /* If we have an LWPID to work with, use it. Otherwise, we're
270 1.8 christos dealing with a non-threaded program/target. */
271 1.5 christos pid = ptid.lwp ();
272 1.5 christos if (pid == 0)
273 1.9 christos pid = ptid.pid ();
274 1.5 christos return pid;
275 1.1 christos }
276 1.1 christos #endif
277 1.1 christos
278 1.1 christos /* Resume execution of thread PTID, or all threads if PTID is -1. If
279 1.8 christos STEP is nonzero, single-step it. If SIGNAL is nonzero, give it
280 1.8 christos that signal. */
281 1.1 christos
282 1.9 christos void
283 1.1 christos inf_ptrace_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
284 1.8 christos {
285 1.1 christos PTRACE_TYPE_ARG1 request;
286 1.1 christos
287 1.9 christos if (minus_one_ptid == ptid)
288 1.1 christos /* Resume all threads. Traditionally ptrace() only supports
289 1.1 christos single-threaded processes, so simply resume the inferior. */
290 1.1 christos ptid = ptid_t (inferior_ptid.pid ());
291 1.1 christos
292 1.1 christos if (catch_syscall_enabled () > 0)
293 1.1 christos request = PT_SYSCALL;
294 1.1 christos else
295 1.1 christos request = PT_CONTINUE;
296 1.1 christos
297 1.9 christos if (step)
298 1.9 christos {
299 1.9 christos /* If this system does not support PT_STEP, a higher level
300 1.9 christos function will have called the appropriate functions to transmute the
301 1.1 christos step request into a continue request (by setting breakpoints on
302 1.9 christos all possible successor instructions), so we don't have to
303 1.1 christos worry about that here. */
304 1.1 christos request = PT_STEP;
305 1.1 christos }
306 1.1 christos
307 1.1 christos /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
308 1.9 christos where it was. If GDB wanted it to start some other way, we have
309 1.1 christos already written a new program counter value to the child. */
310 1.1 christos errno = 0;
311 1.1 christos gdb_ptrace (request, ptid, (PTRACE_TYPE_ARG3)1, gdb_signal_to_host (signal));
312 1.1 christos if (errno != 0)
313 1.1 christos perror_with_name (("ptrace"));
314 1.1 christos }
315 1.1 christos
316 1.1 christos /* Wait for the child specified by PTID to do something. Return the
317 1.8 christos process ID of the child, or MINUS_ONE_PTID in case of error; store
318 1.8 christos the status in *OURSTATUS. */
319 1.8 christos
320 1.1 christos ptid_t
321 1.1 christos inf_ptrace_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
322 1.1 christos int options)
323 1.1 christos {
324 1.1 christos pid_t pid;
325 1.1 christos int status, save_errno;
326 1.1 christos
327 1.1 christos do
328 1.1 christos {
329 1.1 christos set_sigint_trap ();
330 1.8 christos
331 1.1 christos do
332 1.1 christos {
333 1.1 christos pid = waitpid (ptid.pid (), &status, 0);
334 1.1 christos save_errno = errno;
335 1.1 christos }
336 1.1 christos while (pid == -1 && errno == EINTR);
337 1.1 christos
338 1.1 christos clear_sigint_trap ();
339 1.1 christos
340 1.1 christos if (pid == -1)
341 1.1 christos {
342 1.1 christos fprintf_unfiltered (gdb_stderr,
343 1.1 christos _("Child process unexpectedly missing: %s.\n"),
344 1.1 christos safe_strerror (save_errno));
345 1.1 christos
346 1.1 christos /* Claim it exited with unknown signal. */
347 1.1 christos ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
348 1.1 christos ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
349 1.1 christos return inferior_ptid;
350 1.9 christos }
351 1.1 christos
352 1.1 christos /* Ignore terminated detached child processes. */
353 1.1 christos if (!WIFSTOPPED (status) && find_inferior_pid (this, pid) == nullptr)
354 1.1 christos pid = -1;
355 1.1 christos }
356 1.8 christos while (pid == -1);
357 1.1 christos
358 1.1 christos store_waitstatus (ourstatus, status);
359 1.7 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.9 christos be non-null. Return the number of transferred bytes. */
366 1.7 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.9 christos if (readbuf != NULL || chunk < sizeof (PTRACE_TYPE_RET))
397 1.9 christos {
398 1.7 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.9 christos {
408 1.7 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.9 christos /* Using the appropriate one (I or D) is necessary for
415 1.9 christos Gould NP1, at least. */
416 1.7 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.3 christos return n;
426 1.1 christos }
427 1.8 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.1 christos const char *annex, gdb_byte *readbuf,
433 1.9 christos const gdb_byte *writebuf,
434 1.1 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.9 christos piod.piod_len = len;
458 1.3 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.1 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.3 christos using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
468 1.1 christos to indicate failure. */
469 1.1 christos if (errno != EINVAL)
470 1.9 christos return TARGET_XFER_EOF;
471 1.7 christos }
472 1.7 christos #endif
473 1.1 christos *xfered_len = inf_ptrace_peek_poke (ptid, readbuf, writebuf,
474 1.1 christos offset, len);
475 1.3 christos return *xfered_len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
476 1.1 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.1 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 auxilliary vector. Other
484 1.1 christos BSD's may follow if they feel the need to support PIE. */
485 1.1 christos {
486 1.3 christos struct ptrace_io_desc piod;
487 1.1 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.9 christos piod.piod_len = len;
494 1.3 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.1 christos *xfered_len = piod.piod_len;
500 1.1 christos return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
501 1.3 christos }
502 1.1 christos }
503 1.1 christos #endif
504 1.3 christos return TARGET_XFER_E_IO;
505 1.1 christos
506 1.1 christos case TARGET_OBJECT_WCOOKIE:
507 1.3 christos return TARGET_XFER_E_IO;
508 1.1 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.8 christos
514 1.8 christos /* Return non-zero if the thread specified by PTID is alive. */
515 1.1 christos
516 1.1 christos bool
517 1.8 christos inf_ptrace_target::thread_alive (ptid_t ptid)
518 1.1 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.8 christos
523 1.8 christos /* Print status information about what we're accessing. */
524 1.1 christos
525 1.1 christos void
526 1.1 christos inf_ptrace_target::files_info ()
527 1.1 christos {
528 1.1 christos struct inferior *inf = current_inferior ();
529 1.9 christos
530 1.1 christos printf_filtered (_("\tUsing the running image of %s %s.\n"),
531 1.1 christos inf->attach_flag ? "attached" : "child",
532 1.9 christos target_pid_to_str (inferior_ptid).c_str ());
533 1.8 christos }
534 1.1 christos
535 1.1 christos std::string
536 1.1 christos inf_ptrace_target::pid_to_str (ptid_t ptid)
537 {
538 return normal_pid_to_str (ptid);
539 }
540