1 /*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifdef INCLUDE_SA_ATTACH
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <signal.h>
31 #include <errno.h>
32 #include <elf.h>
33 #include <sys/types.h>
34 #include <sys/wait.h>
35 #include <sys/ptrace.h>
36 #include <sys/uio.h>
37 #include "libproc_impl.h"
38
39 #if defined(x86_64) && !defined(amd64)
40 #define amd64 1
41 #endif
42
43 #ifndef __WALL
44 #define __WALL 0x40000000 // Copied from /usr/include/linux/wait.h
45 #endif
46
203 break;
204 case ECHILD:
205 print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
206 break;
207 case EINVAL:
208 print_debug("waitpid() failed. Invalid options argument.\n");
209 break;
210 default:
211 print_debug("waitpid() failed. Unexpected error %d\n",errno);
212 break;
213 }
214 return false;
215 }
216 }
217 }
218
219 // attach to a process/thread specified by "pid"
220 static bool ptrace_attach(pid_t pid, char* err_buf, size_t err_buf_len) {
221 if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
222 char buf[200];
223 char* msg = strerror_r(errno, buf, sizeof(buf));
224 snprintf(err_buf, err_buf_len, "ptrace(PTRACE_ATTACH, ..) failed for %d: %s", pid, msg);
225 print_debug("%s\n", err_buf);
226 return false;
227 } else {
228 return ptrace_waitpid(pid);
229 }
230 }
231
232 // -------------------------------------------------------
233 // functions for obtaining library information
234 // -------------------------------------------------------
235
236 /*
237 * splits a string _str_ into substrings with delimiter _delim_ by replacing old * delimiters with _new_delim_ (ideally, '\0'). the address of each substring
238 * is stored in array _ptrs_ as the return value. the maximum capacity of _ptrs_ * array is specified by parameter _n_.
239 * RETURN VALUE: total number of substrings (always <= _n_)
240 * NOTE: string _str_ is modified if _delim_!=_new_delim_
241 */
242 static int split_n_str(char * str, int n, char ** ptrs, char delim, char new_delim)
243 {
244 int i;
245 for(i = 0; i < n; i++) ptrs[i] = NULL;
391 }
392
393 // initialize ps_prochandle
394 ph->pid = pid;
395
396 // initialize vtable
397 ph->ops = &process_ops;
398
399 // read library info and symbol tables, must do this before attaching threads,
400 // as the symbols in the pthread library will be used to figure out
401 // the list of threads within the same process.
402 read_lib_info(ph);
403
404 // read thread info
405 read_thread_info(ph, add_new_thread);
406
407 // attach to the threads
408 thr = ph->threads;
409 while (thr) {
410 // don't attach to the main thread again
411 if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) {
412 // even if one attach fails, we get return NULL
413 Prelease(ph);
414 return NULL;
415 }
416 thr = thr->next;
417 }
418 return ph;
419 }
420
421 #endif // INCLUDE_SA_ATTACH
|
1 /*
2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <signal.h>
29 #include <errno.h>
30 #include <elf.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <sys/ptrace.h>
34 #include <sys/uio.h>
35 #include "libproc_impl.h"
36
37 #if defined(x86_64) && !defined(amd64)
38 #define amd64 1
39 #endif
40
41 #ifndef __WALL
42 #define __WALL 0x40000000 // Copied from /usr/include/linux/wait.h
43 #endif
44
201 break;
202 case ECHILD:
203 print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
204 break;
205 case EINVAL:
206 print_debug("waitpid() failed. Invalid options argument.\n");
207 break;
208 default:
209 print_debug("waitpid() failed. Unexpected error %d\n",errno);
210 break;
211 }
212 return false;
213 }
214 }
215 }
216
217 // attach to a process/thread specified by "pid"
218 static bool ptrace_attach(pid_t pid, char* err_buf, size_t err_buf_len) {
219 if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
220 char buf[200];
221 if (strerror_r(errno, buf, sizeof(buf) == 0)) {
222 snprintf(err_buf, err_buf_len,
223 "ptrace(PTRACE_ATTACH, ..) failed for %d: %s", pid, buf);
224 print_debug("%s\n", err_buf);
225 }
226 return false;
227 } else {
228 return ptrace_waitpid(pid);
229 }
230 }
231
232 // -------------------------------------------------------
233 // functions for obtaining library information
234 // -------------------------------------------------------
235
236 /*
237 * splits a string _str_ into substrings with delimiter _delim_ by replacing old * delimiters with _new_delim_ (ideally, '\0'). the address of each substring
238 * is stored in array _ptrs_ as the return value. the maximum capacity of _ptrs_ * array is specified by parameter _n_.
239 * RETURN VALUE: total number of substrings (always <= _n_)
240 * NOTE: string _str_ is modified if _delim_!=_new_delim_
241 */
242 static int split_n_str(char * str, int n, char ** ptrs, char delim, char new_delim)
243 {
244 int i;
245 for(i = 0; i < n; i++) ptrs[i] = NULL;
391 }
392
393 // initialize ps_prochandle
394 ph->pid = pid;
395
396 // initialize vtable
397 ph->ops = &process_ops;
398
399 // read library info and symbol tables, must do this before attaching threads,
400 // as the symbols in the pthread library will be used to figure out
401 // the list of threads within the same process.
402 read_lib_info(ph);
403
404 // read thread info
405 read_thread_info(ph, add_new_thread);
406
407 // attach to the threads
408 thr = ph->threads;
409 while (thr) {
410 // don't attach to the main thread again
411 if (pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) {
412 // even if one attach fails, we get return NULL
413 Prelease(ph);
414 return NULL;
415 }
416 thr = thr->next;
417 }
418 return ph;
419 }
|