]> gcc.gnu.org Git - gcc.git/blame - libjava/name-finder.cc
* extend.texi: Update for CPP.
[gcc.git] / libjava / name-finder.cc
CommitLineData
283a159f
AH
1// name-finder.cc - Convert addresses to names
2
3/* Copyright (C) 2000 Red Hat Inc
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11/**
12 * @author Andrew Haley <aph@cygnus.com>
13 * @date Jan 6 2000
14 */
15
16/* _Jv_name_finder is a class wrapper around a mechanism that can
17 convert address of methods to their names and the names of files in
18 which they appear.
19
20 Right now, the only implementation of this involves running a copy
21 of addr2line, but at some point it is worth building this
22 functionality into libgcj, if only for embedded systems. */
23
24
25#ifndef _GNU_SOURCE
26#define _GNU_SOURCE 1
27#endif
28
29#include <config.h>
30
31#include <string.h>
32
33#include <gcj/cni.h>
34#include <jvm.h>
35#include <java/lang/Object.h>
36#include <java-threads.h>
37#include <java/lang/Throwable.h>
38#include <java/io/PrintStream.h>
39#include <java/io/PrintWriter.h>
40
41#include <sys/types.h>
42
43#include <stdlib.h>
44#include <stdio.h>
45
46#ifdef HAVE_UNISTD_H
47#include <unistd.h>
48#endif
49
50#ifdef HAVE_DLFCN_H
51#include <dlfcn.h>
52#endif
53
54#include <name-finder.h>
55
56/* Create a new name finder which will perform address lookups on an
57 executable. */
58
59_Jv_name_finder::_Jv_name_finder (char *executable)
60{
61#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
62 error = 0;
63
64 char *argv[6];
65 {
66 int arg = 0;
6c80c45e
TT
67#ifdef __ia64__
68 argv[arg++] = "addr2name.awk";
69#else
283a159f
AH
70 argv[arg++] = "addr2line";
71 argv[arg++] = "-C";
72 argv[arg++] = "-f";
73 argv[arg++] = "-e";
6c80c45e 74#endif
283a159f
AH
75 argv[arg++] = executable;
76 argv[arg] = NULL;
77 }
78
79 error |= pipe (f_pipe) < 0;
80 error |= pipe (b_pipe) < 0;
efc70584 81
283a159f
AH
82 if (error)
83 return;
84
85 pid = fork ();
86 if (pid == 0)
87 {
88 close (f_pipe[1]);
89 close (b_pipe[0]);
90 dup2 (f_pipe[0], fileno (stdin));
91 dup2 (b_pipe[1], fileno (stdout));
92 execvp (argv[0], argv);
93 _exit (127);
94 }
efc70584 95
283a159f
AH
96 close (f_pipe [0]);
97 close (b_pipe [1]);
efc70584 98
283a159f
AH
99 if (pid < 0)
100 {
101 error |= 1;
102 return;
103 }
efc70584 104
283a159f
AH
105 b_pipe_fd = fdopen (b_pipe[0], "r");
106 error |= !b_pipe_fd;
107#endif
108}
109
110/* Convert a pointer to hex. */
111
112void
113_Jv_name_finder::toHex (void *p)
114{
115 unsigned long long n = (unsigned long long)p;
116 int digits = sizeof (void *) * 2;
117
118 strcpy (hex, "0x");
119 for (int i = digits - 1; i >= 0; i--)
120 {
121 int digit = n % 16;
122
123 n /= 16;
124 hex[i+2] = digit > 9 ? 'a' + digit - 10 : '0' + digit;
125 }
126 hex [digits+2] = 0;
127}
128
129/* Given a pointer to a function or method, try to convert it into a
130 name and the appropriate line and source file. The caller passes
131 the code pointer in p.
132
133 Returns false if the lookup fails. Even if this happens, the field
134 he will have been correctly filled in with the pointer. */
135
136bool
137_Jv_name_finder::lookup (void *p)
138{
6a3bad7d 139 extern char **_Jv_argv;
283a159f
AH
140 toHex (p);
141
b9f243c2 142#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
283a159f
AH
143 {
144 Dl_info dl_info;
145
146 if (dladdr (p, &dl_info))
147 {
148 strncpy (file_name, dl_info.dli_fname, sizeof file_name);
149 strncpy (method_name, dl_info.dli_sname, sizeof method_name);
6a3bad7d
BM
150
151 /* Don't trust dladdr() if the address is from the main program. */
abb32cf5 152 if (_Jv_argv == NULL || strcmp (file_name, _Jv_argv[0]) != 0)
6a3bad7d 153 return true;
283a159f
AH
154 }
155 }
156#endif
157
158#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
159 if (error)
160 return false;
161
162 error |= write (f_pipe[1], hex, strlen (hex)) < 0;
163 if (error)
164 return false;
165 error |= write (f_pipe[1], "\n", 1) < 0;
166 if (error)
167 return false;
168
169 error |= (fgets (method_name, sizeof method_name, b_pipe_fd) == NULL);
170 if (error)
171 return false;
172 error |= (fgets (file_name, sizeof file_name, b_pipe_fd) == NULL);
173 if (error)
174 return false;
175
176 char *newline = strchr (method_name, '\n');
177 if (newline)
178 *newline = 0;
179 newline = strchr (file_name, '\n');
180 if (newline)
181 *newline = 0;
182
183 return true;
184
185#else
186 return false;
187#endif /* defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP) */
188}
This page took 0.110535 seconds and 5 git commands to generate.