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