aboutsummaryrefslogtreecommitdiff
path: root/libjava/name-finder.cc
diff options
context:
space:
mode:
authorAndrew Haley <aph@cygnus.com>2000-01-17 15:45:24 +0000
committerAndrew Haley <aph@gcc.gnu.org>2000-01-17 15:45:24 +0000
commit283a159fe38e477d93b189d43888f1e42043c0af (patch)
treee7424bbdd7c568c2f6f24481d328b24bade92628 /libjava/name-finder.cc
parent1353681247458baa6a3df8375b786df8ace7664c (diff)
downloadgcc-283a159fe38e477d93b189d43888f1e42043c0af.zip
gcc-283a159fe38e477d93b189d43888f1e42043c0af.tar.gz
gcc-283a159fe38e477d93b189d43888f1e42043c0af.tar.bz2
natThrowable.cc: New file.
2000-01-14 Andrew Haley <aph@cygnus.com> * java/lang/natThrowable.cc: New file. * java/lang/Throwable.java (fillInStackTrace): Make native. (printStackTrace): Call native method to do this. (Throwable): Call fillInStackTrace. (stackTrace): New variable. * include/jvm.h: Add _Jv_ThisExecutable functions. * prims.cc: (_Jv_execName): New variable. (catch_segv): Call fillInStackTrace. (catch_fpe): Ditto. (_Jv_ThisExecutable): New functions. (JvRunMain): Set the name of this executable. * Makefile.am: Add java/lang/natThrowable.cc. Add name-finder.cc. * Makefile.in: Rebuilt. * acconfig.h: Add HAVE_PROC_SELF_EXE. * configure.in: Force link with __frame_state_for in FORCELIBGCCSPEC. Add new checks for backtrace. * include/config.h.in: Rebuilt. * name-finder.cc: New file. * include/name-finder.h: New file. From-SVN: r31460
Diffstat (limited to 'libjava/name-finder.cc')
-rw-r--r--libjava/name-finder.cc180
1 files changed, 180 insertions, 0 deletions
diff --git a/libjava/name-finder.cc b/libjava/name-finder.cc
new file mode 100644
index 0000000..ba8a5ae
--- /dev/null
+++ b/libjava/name-finder.cc
@@ -0,0 +1,180 @@
+// name-finder.cc - Convert addresses to names
+
+/* Copyright (C) 2000 Red Hat Inc
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date Jan 6 2000
+ */
+
+/* _Jv_name_finder is a class wrapper around a mechanism that can
+ convert address of methods to their names and the names of files in
+ which they appear.
+
+ Right now, the only implementation of this involves running a copy
+ of addr2line, but at some point it is worth building this
+ functionality into libgcj, if only for embedded systems. */
+
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#include <config.h>
+
+#include <string.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java/lang/Throwable.h>
+#include <java/io/PrintStream.h>
+#include <java/io/PrintWriter.h>
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <name-finder.h>
+
+/* Create a new name finder which will perform address lookups on an
+ executable. */
+
+_Jv_name_finder::_Jv_name_finder (char *executable)
+{
+#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
+ error = 0;
+
+ char *argv[6];
+ {
+ int arg = 0;
+ argv[arg++] = "addr2line";
+ argv[arg++] = "-C";
+ argv[arg++] = "-f";
+ argv[arg++] = "-e";
+ argv[arg++] = executable;
+ argv[arg] = NULL;
+ }
+
+ error |= pipe (f_pipe) < 0;
+ error |= pipe (b_pipe) < 0;
+
+ if (error)
+ return;
+
+ pid = fork ();
+ if (pid == 0)
+ {
+ close (f_pipe[1]);
+ close (b_pipe[0]);
+ dup2 (f_pipe[0], fileno (stdin));
+ dup2 (b_pipe[1], fileno (stdout));
+ execvp (argv[0], argv);
+ _exit (127);
+ }
+
+ close (f_pipe [0]);
+ close (b_pipe [1]);
+
+ if (pid < 0)
+ {
+ error |= 1;
+ return;
+ }
+
+ b_pipe_fd = fdopen (b_pipe[0], "r");
+ error |= !b_pipe_fd;
+#endif
+}
+
+/* Convert a pointer to hex. */
+
+void
+_Jv_name_finder::toHex (void *p)
+{
+ unsigned long long n = (unsigned long long)p;
+ int digits = sizeof (void *) * 2;
+
+ strcpy (hex, "0x");
+ for (int i = digits - 1; i >= 0; i--)
+ {
+ int digit = n % 16;
+
+ n /= 16;
+ hex[i+2] = digit > 9 ? 'a' + digit - 10 : '0' + digit;
+ }
+ hex [digits+2] = 0;
+}
+
+/* Given a pointer to a function or method, try to convert it into a
+ name and the appropriate line and source file. The caller passes
+ the code pointer in p.
+
+ Returns false if the lookup fails. Even if this happens, the field
+ he will have been correctly filled in with the pointer. */
+
+bool
+_Jv_name_finder::lookup (void *p)
+{
+ toHex (p);
+
+#ifdef HAVE_DLFCN_H
+ {
+ Dl_info dl_info;
+
+ if (dladdr (p, &dl_info))
+ {
+ strncpy (file_name, dl_info.dli_fname, sizeof file_name);
+ strncpy (method_name, dl_info.dli_sname, sizeof method_name);
+ return true;
+ }
+ }
+#endif
+
+#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
+ if (error)
+ return false;
+
+ error |= write (f_pipe[1], hex, strlen (hex)) < 0;
+ if (error)
+ return false;
+ error |= write (f_pipe[1], "\n", 1) < 0;
+ if (error)
+ return false;
+
+ error |= (fgets (method_name, sizeof method_name, b_pipe_fd) == NULL);
+ if (error)
+ return false;
+ error |= (fgets (file_name, sizeof file_name, b_pipe_fd) == NULL);
+ if (error)
+ return false;
+
+ char *newline = strchr (method_name, '\n');
+ if (newline)
+ *newline = 0;
+ newline = strchr (file_name, '\n');
+ if (newline)
+ *newline = 0;
+
+ return true;
+
+#else
+ return false;
+#endif /* defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP) */
+}