annotate agent/src/os/bsd/ps_proc.c @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 1a04de1aaedb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
1 /*
8058
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
4 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
7 * published by the Free Software Foundation.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
8 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
13 * accompanied this code).
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
14 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
18 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
21 * questions.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
22 *
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
23 */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
24
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
25 #include <limits.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
26 #include <stdio.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
27 #include <stdlib.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
28 #include <string.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
29 #include <errno.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
30 #include <sys/types.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
31 #include <sys/wait.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
32 #include <sys/ptrace.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
33 #include <sys/param.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
34 #include <sys/user.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
35 #include <elf.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
36 #include <sys/elf_common.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
37 #include <sys/link_elf.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
38 #include <libutil.h>
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
39 #include "libproc_impl.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
40 #include "elfmacros.h"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
41
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
42 // This file has the libproc implementation specific to live process
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
43 // For core files, refer to ps_core.c
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
44
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
45 static inline uintptr_t align(uintptr_t ptr, size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
46 return (ptr & ~(size - 1));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
47 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
48
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
49 // ---------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
50 // ptrace functions
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
51 // ---------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
52
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
53 // read "size" bytes of data from "addr" within the target process.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
54 // unlike the standard ptrace() function, process_read_data() can handle
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
55 // unaligned address - alignment check, if required, should be done
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
56 // before calling process_read_data.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
57
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
58 static bool process_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
59 int rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
60 size_t i, words;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
61 uintptr_t end_addr = addr + size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
62 uintptr_t aligned_addr = align(addr, sizeof(int));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
63
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
64 if (aligned_addr != addr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
65 char *ptr = (char *)&rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
66 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
67 rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
68 if (errno) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
69 print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
70 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
71 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
72 for (; aligned_addr != addr; aligned_addr++, ptr++);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
73 for (; ((intptr_t)aligned_addr % sizeof(int)) && aligned_addr < end_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
74 aligned_addr++)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
75 *(buf++) = *(ptr++);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
76 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
77
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
78 words = (end_addr - aligned_addr) / sizeof(int);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
79
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
80 // assert((intptr_t)aligned_addr % sizeof(int) == 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
81 for (i = 0; i < words; i++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
82 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
83 rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
84 if (errno) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
85 print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
86 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
87 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
88 *(int *)buf = rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
89 buf += sizeof(int);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
90 aligned_addr += sizeof(int);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
91 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
92
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
93 if (aligned_addr != end_addr) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
94 char *ptr = (char *)&rslt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
95 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
96 rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
97 if (errno) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
98 print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
99 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
100 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
101 for (; aligned_addr != end_addr; aligned_addr++)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
102 *(buf++) = *(ptr++);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
103 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
104 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
105 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
106
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
107 // null implementation for write
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
108 static bool process_write_data(struct ps_prochandle* ph,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
109 uintptr_t addr, const char *buf , size_t size) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
110 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
111 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
112
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
113 // "user" should be a pointer to a reg
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
114 static bool process_get_lwp_regs(struct ps_prochandle* ph, pid_t pid, struct reg *user) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
115 // we have already attached to all thread 'pid's, just use ptrace call
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
116 // to get regset now. Note that we don't cache regset upfront for processes.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
117 if (ptrace(PT_GETREGS, pid, (caddr_t) user, 0) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
118 print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp %d\n", pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
119 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
120 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
121 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
122 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
123
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
124 // fill in ptrace_lwpinfo for lid
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
125 static bool process_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
126 errno = 0;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
127 ptrace(PT_LWPINFO, lwp_id, linfo, sizeof(struct ptrace_lwpinfo));
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
128
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
129 return (errno == 0)? true: false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
130 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
131
8058
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
132 static bool ptrace_continue(pid_t pid, int signal) {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
133 // pass the signal to the process so we don't swallow it
13002
1a04de1aaedb 8026950: Nits in agent ps_proc.c file breaks compilation of open hotspot
dsamersoff
parents: 8058
diff changeset
134 if (ptrace(PT_CONTINUE, pid, NULL, signal) < 0) {
8058
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
135 print_debug("ptrace(PTRACE_CONT, ..) failed for %d\n", pid);
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
136 return false;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
137 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
138 return true;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
139 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
140
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
141 // waits until the ATTACH has stopped the process
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
142 // by signal SIGSTOP
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
143 static bool ptrace_waitpid(pid_t pid) {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
144 int ret;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
145 int status;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
146 do {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
147 // Wait for debuggee to stop.
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
148 ret = waitpid(pid, &status, 0);
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
149 if (ret >= 0) {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
150 if (WIFSTOPPED(status)) {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
151 // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
152 // will still be pending and delivered when the process is DETACHED and the process
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
153 // will go to sleep.
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
154 if (WSTOPSIG(status) == SIGSTOP) {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
155 // Debuggee stopped by SIGSTOP.
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
156 return true;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
157 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
158 if (!ptrace_continue(pid, WSTOPSIG(status))) {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
159 print_error("Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
160 return false;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
161 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
162 } else {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
163 print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
164 return false;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
165 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
166 } else {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
167 switch (errno) {
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
168 case EINTR:
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
169 continue;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
170 break;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
171 case ECHILD:
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
172 print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
173 break;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
174 case EINVAL:
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
175 print_debug("waitpid() failed. Invalid options argument.\n");
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
176 break;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
177 default:
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
178 print_debug("waitpid() failed. Unexpected error %d\n",errno);
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
179 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
180 return false;
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
181 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
182 } while(true);
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
183 }
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
184
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
185 // attach to a process/thread specified by "pid"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
186 static bool ptrace_attach(pid_t pid) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
187 if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
188 print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
189 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
190 } else {
8058
2394a89e89f4 8008088: SA can hang the VM
rbackman
parents: 3960
diff changeset
191 return ptrace_waitpid(pid);
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
192 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
193 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
194
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
195 // -------------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
196 // functions for obtaining library information
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
197 // -------------------------------------------------------
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
198
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
199 // callback for read_thread_info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
200 static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
201 return add_thread_info(ph, pthread_id, lwp_id) != NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
202 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
203
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
204 #if defined(__FreeBSD__) && __FreeBSD_version < 701000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
205 /*
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
206 * TEXT_START_ADDR from binutils/ld/emulparams/<arch_spec>.sh
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
207 * Not the most robust but good enough.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
208 */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
209
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
210 #if defined(amd64) || defined(x86_64)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
211 #define TEXT_START_ADDR 0x400000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
212 #elif defined(i386)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
213 #define TEXT_START_ADDR 0x8048000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
214 #else
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
215 #error TEXT_START_ADDR not defined
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
216 #endif
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
217
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
218 #define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
219
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
220 uintptr_t linkmap_addr(struct ps_prochandle *ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
221 uintptr_t ehdr_addr, phdr_addr, dyn_addr, dmap_addr, lmap_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
222 ELF_EHDR ehdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
223 ELF_PHDR *phdrs, *phdr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
224 ELF_DYN *dyns, *dyn;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
225 struct r_debug dmap;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
226 unsigned long hdrs_size;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
227 unsigned int i;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
228
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
229 /* read ELF_EHDR at TEXT_START_ADDR and validate */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
230
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
231 ehdr_addr = (uintptr_t)TEXT_START_ADDR;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
232
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
233 if (process_read_data(ph, ehdr_addr, (char *)&ehdr, sizeof(ehdr)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
234 print_debug("process_read_data failed for ehdr_addr %p\n", ehdr_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
235 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
236 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
237
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
238 if (!IS_ELF(ehdr) ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
239 ehdr.e_ident[EI_CLASS] != ELF_TARG_CLASS ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
240 ehdr.e_ident[EI_DATA] != ELF_TARG_DATA ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
241 ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
242 ehdr.e_phentsize != sizeof(ELF_PHDR) ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
243 ehdr.e_version != ELF_TARG_VER ||
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
244 ehdr.e_machine != ELF_TARG_MACH) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
245 print_debug("not an ELF_EHDR at %p\n", ehdr_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
246 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
247 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
248
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
249 /* allocate space for all ELF_PHDR's and read */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
250
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
251 phdr_addr = ehdr_addr + ehdr.e_phoff;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
252 hdrs_size = ehdr.e_phnum * sizeof(ELF_PHDR);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
253
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
254 if ((phdrs = malloc(hdrs_size)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
255 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
256
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
257 if (process_read_data(ph, phdr_addr, (char *)phdrs, hdrs_size) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
258 print_debug("process_read_data failed for phdr_addr %p\n", phdr_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
259 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
260 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
261
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
262 /* find PT_DYNAMIC section */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
263
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
264 for (i = 0, phdr = phdrs; i < ehdr.e_phnum; i++, phdr++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
265 if (phdr->p_type == PT_DYNAMIC)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
266 break;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
267 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
268
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
269 if (i >= ehdr.e_phnum) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
270 print_debug("PT_DYNAMIC section not found!\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
271 free(phdrs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
272 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
273 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
274
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
275 /* allocate space and read in ELF_DYN headers */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
276
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
277 dyn_addr = phdr->p_vaddr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
278 hdrs_size = phdr->p_memsz;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
279 free(phdrs);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
280
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
281 if ((dyns = malloc(hdrs_size)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
282 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
283
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
284 if (process_read_data(ph, dyn_addr, (char *)dyns, hdrs_size) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
285 print_debug("process_read_data failed for dyn_addr %p\n", dyn_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
286 free(dyns);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
287 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
288 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
289
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
290 /* find DT_DEBUG */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
291
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
292 dyn = dyns;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
293 while (dyn->d_tag != DT_DEBUG && dyn->d_tag != DT_NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
294 dyn++;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
295 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
296
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
297 if (dyn->d_tag != DT_DEBUG) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
298 print_debug("failed to find DT_DEBUG\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
299 free(dyns);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
300 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
301 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
302
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
303 /* read struct r_debug into dmap */
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
304
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
305 dmap_addr = (uintptr_t)dyn->d_un.d_ptr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
306 free(dyns);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
307
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
308 if (process_read_data(ph, dmap_addr, (char *)&dmap, sizeof(dmap)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
309 print_debug("process_read_data failed for dmap_addr %p\n", dmap_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
310 return (0);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
311 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
312
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
313 lmap_addr = (uintptr_t)dmap.r_map;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
314
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
315 return (lmap_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
316 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
317 #endif // __FreeBSD__ && __FreeBSD_version < 701000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
318
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
319 static bool read_lib_info(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
320 #if defined(__FreeBSD__) && __FreeBSD_version >= 701000
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
321 struct kinfo_vmentry *freep, *kve;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
322 int i, cnt;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
323
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
324 freep = kinfo_getvmmap(ph->pid, &cnt);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
325 if (freep == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
326 print_debug("can't get vm map for pid\n", ph->pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
327 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
328 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
329
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
330 for (i = 0; i < cnt; i++) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
331 kve = &freep[i];
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
332 if ((kve->kve_flags & KVME_FLAG_COW) &&
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
333 kve->kve_path != NULL &&
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
334 strlen(kve->kve_path) > 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
335
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
336 if (find_lib(ph, kve->kve_path) == false) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
337 lib_info* lib;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
338 if ((lib = add_lib_info(ph, kve->kve_path,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
339 (uintptr_t) kve->kve_start)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
340 continue; // ignore, add_lib_info prints error
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
341
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
342 // we don't need to keep the library open, symtab is already
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
343 // built. Only for core dump we need to keep the fd open.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
344 close(lib->fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
345 lib->fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
346 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
347 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
348 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
349
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
350 free(freep);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
351
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
352 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
353 #else
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
354 char *l_name;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
355 struct link_map *lmap;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
356 uintptr_t lmap_addr;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
357
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
358 if ((l_name = malloc(BUF_SIZE)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
359 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
360
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
361 if ((lmap = malloc(sizeof(*lmap))) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
362 free(l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
363 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
364 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
365
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
366 lmap_addr = linkmap_addr(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
367
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
368 if (lmap_addr == 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
369 free(l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
370 free(lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
371 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
372 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
373
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
374 do {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
375 if (process_read_data(ph, lmap_addr, (char *)lmap, sizeof(*lmap)) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
376 print_debug("process_read_data failed for lmap_addr %p\n", lmap_addr);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
377 free (l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
378 free (lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
379 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
380 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
381
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
382 if (process_read_data(ph, (uintptr_t)lmap->l_name, l_name,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
383 BUF_SIZE) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
384 print_debug("process_read_data failed for lmap->l_name %p\n",
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
385 lmap->l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
386 free (l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
387 free (lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
388 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
389 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
390
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
391 if (find_lib(ph, l_name) == false) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
392 lib_info* lib;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
393 if ((lib = add_lib_info(ph, l_name,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
394 (uintptr_t) lmap->l_addr)) == NULL)
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
395 continue; // ignore, add_lib_info prints error
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
396
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
397 // we don't need to keep the library open, symtab is already
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
398 // built. Only for core dump we need to keep the fd open.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
399 close(lib->fd);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
400 lib->fd = -1;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
401 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
402 lmap_addr = (uintptr_t)lmap->l_next;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
403 } while (lmap->l_next != NULL);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
404
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
405 free (l_name);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
406 free (lmap);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
407
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
408 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
409 #endif
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
410 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
411
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
412 // detach a given pid
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
413 static bool ptrace_detach(pid_t pid) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
414 if (pid && ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
415 print_debug("ptrace(PTRACE_DETACH, ..) failed for %d\n", pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
416 return false;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
417 } else {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
418 return true;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
419 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
420 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
421
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
422 static void process_cleanup(struct ps_prochandle* ph) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
423 ptrace_detach(ph->pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
424 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
425
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
426 static ps_prochandle_ops process_ops = {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
427 .release= process_cleanup,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
428 .p_pread= process_read_data,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
429 .p_pwrite= process_write_data,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
430 .get_lwp_regs= process_get_lwp_regs,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
431 .get_lwp_info= process_get_lwp_info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
432 };
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
433
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
434 // attach to the process. One and only one exposed stuff
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
435 struct ps_prochandle* Pgrab(pid_t pid) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
436 struct ps_prochandle* ph = NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
437
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
438 if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
439 print_debug("can't allocate memory for ps_prochandle\n");
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
440 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
441 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
442
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
443 if (ptrace_attach(pid) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
444 free(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
445 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
446 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
447
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
448 // initialize ps_prochandle
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
449 ph->pid = pid;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
450
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
451 // initialize vtable
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
452 ph->ops = &process_ops;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
453
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
454 // read library info and symbol tables, must do this before attaching threads,
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
455 // as the symbols in the pthread library will be used to figure out
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
456 // the list of threads within the same process.
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
457 if (read_lib_info(ph) != true) {
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
458 ptrace_detach(pid);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
459 free(ph);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
460 return NULL;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
461 }
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
462
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
463 // read thread info
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
464 read_thread_info(ph, add_new_thread);
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
465
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
466 return ph;
f08d439fab8c 7089790: integrate bsd-port changes
never
parents:
diff changeset
467 }