mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-18 16:15:00 +08:00
natThrowable.cc (printRawStackTrace): removed.
* java/lang/natThrowable.cc (printRawStackTrace): removed. (getStackTrace0): new method. * java/lang/Throwable.java (CPlusPlusDemangler): removed. (printStackTrace(PrintWriter)): replace with pure java implementation. (printRawStackTrace): removed. (getStackTrace0): new method. * java/lang/StackTraceElement.java (toString): add extra whitespace. * gcj/javaprims.h: regenerate class list. * include/name-finder.h (lookup): new returns StackTraceElement*. (method_name, file_name): fields removed. (pid2, f2_pipe, b2_pipe, b2_pipe_fd): new fields. (~_Jv_name_finder): close new descriptors. * name-finder.cc(_Jv_name_finder): setup c++filt helper process. (createStackTraceElement): new method. (lookup): returns StackTraceElement*, uses createStackTraceElement(). From-SVN: r55424
This commit is contained in:
parent
26af4041b7
commit
dc7b1dda60
@ -1,3 +1,21 @@
|
||||
2002-07-12 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* java/lang/natThrowable.cc (printRawStackTrace): removed.
|
||||
(getStackTrace0): new method.
|
||||
* java/lang/Throwable.java (CPlusPlusDemangler): removed.
|
||||
(printStackTrace(PrintWriter)): replace with pure java implementation.
|
||||
(printRawStackTrace): removed.
|
||||
(getStackTrace0): new method.
|
||||
* java/lang/StackTraceElement.java (toString): add extra whitespace.
|
||||
* gcj/javaprims.h: regenerate class list.
|
||||
* include/name-finder.h (lookup): new returns StackTraceElement*.
|
||||
(method_name, file_name): fields removed.
|
||||
(pid2, f2_pipe, b2_pipe, b2_pipe_fd): new fields.
|
||||
(~_Jv_name_finder): close new descriptors.
|
||||
* name-finder.cc(_Jv_name_finder): setup c++filt helper process.
|
||||
(createStackTraceElement): new method.
|
||||
(lookup): returns StackTraceElement*, uses createStackTraceElement().
|
||||
|
||||
2002-07-10 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* configure: Rebuilt.
|
||||
|
@ -134,7 +134,6 @@ extern "Java"
|
||||
class AssertionError;
|
||||
class Boolean;
|
||||
class Byte;
|
||||
class CPlusPlusDemangler;
|
||||
class CharSequence;
|
||||
class Character;
|
||||
class Character$Subset;
|
||||
|
@ -29,6 +29,8 @@ details. */
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <java/lang/StackTraceElement.h>
|
||||
|
||||
/* _Jv_name_finder is a class wrapper around a mechanism that can
|
||||
convert addresses of methods to their names and the names of files
|
||||
in which they appear. */
|
||||
@ -47,12 +49,26 @@ public:
|
||||
if (b_pipe_fd != NULL)
|
||||
fclose (b_pipe_fd);
|
||||
|
||||
myclose (f2_pipe[0]);
|
||||
myclose (f2_pipe[1]);
|
||||
myclose (b2_pipe[0]);
|
||||
myclose (b2_pipe[1]);
|
||||
if (b2_pipe_fd != NULL)
|
||||
fclose (b2_pipe_fd);
|
||||
|
||||
if (pid >= 0)
|
||||
{
|
||||
int wstat;
|
||||
// We don't care about errors here.
|
||||
waitpid (pid, &wstat, 0);
|
||||
}
|
||||
|
||||
if (pid2 >= 0)
|
||||
{
|
||||
int wstat;
|
||||
// We don't care about errors here.
|
||||
waitpid (pid2, &wstat, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -60,25 +76,21 @@ public:
|
||||
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
|
||||
hex will have been correctly filled in with the pointer.
|
||||
Returns NULL if the lookup fails. Even if this happens, the field
|
||||
hex will have been correctly filled in with the pointer. */
|
||||
|
||||
The other fields are method_name and file_name, which lookup will
|
||||
attempt to fill appropriately. If the lookup has failed, these
|
||||
fields contain garbage.*/
|
||||
bool lookup (void *p);
|
||||
java::lang::StackTraceElement* lookup (void *p);
|
||||
|
||||
char method_name[1024];
|
||||
char file_name[1024];
|
||||
char hex[sizeof (void *) * 2 + 5];
|
||||
|
||||
private:
|
||||
void toHex (void *p);
|
||||
java::lang::StackTraceElement* createStackTraceElement(char *s, char *f);
|
||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK)
|
||||
pid_t pid;
|
||||
int f_pipe[2], b_pipe[2];
|
||||
FILE *b_pipe_fd;
|
||||
int error;
|
||||
pid_t pid, pid2;
|
||||
int f_pipe[2], b_pipe[2], f2_pipe[2], b2_pipe[2];
|
||||
FILE *b_pipe_fd, *b2_pipe_fd;
|
||||
int demangling_error, lookup_error;
|
||||
|
||||
// Close a descriptor only if it has not been closed.
|
||||
void myclose (int fd)
|
||||
|
@ -191,7 +191,7 @@ public class StackTraceElement implements Serializable
|
||||
}
|
||||
if (methodName != null)
|
||||
sb.append(methodName);
|
||||
sb.append('(');
|
||||
sb.append(" (");
|
||||
if (fileName != null)
|
||||
sb.append(fileName);
|
||||
else
|
||||
|
@ -57,76 +57,6 @@ import java.io.OutputStream;
|
||||
* bytecode not implemented. JDK 1.1.
|
||||
*/
|
||||
|
||||
/* A CPlusPlusDemangler sits on top of a PrintWriter. All input is
|
||||
* passed through the "c++filt" program (part of GNU binutils) which
|
||||
* demangles internal symbols to their C++ source form.
|
||||
*
|
||||
* Closing a CPlusPlusDemangler doesn't close the underlying
|
||||
* PrintWriter; it does, however close underlying process and flush
|
||||
* all its buffers, so it's possible to guarantee that after a
|
||||
* CPlusPlusDemangler has been closed no more will ever be written to
|
||||
* the underlying PrintWriter.
|
||||
*
|
||||
* FIXME: This implictly converts data from the input stream, which is
|
||||
* a stream of characters, to a stream of bytes. We need a way of
|
||||
* handling Unicode characters in demangled identifiers. */
|
||||
|
||||
class CPlusPlusDemangler extends OutputStream
|
||||
{
|
||||
java.io.OutputStream procOut;
|
||||
java.io.InputStream procIn;
|
||||
java.lang.Process proc;
|
||||
PrintWriter p;
|
||||
|
||||
/* The number of bytes written to the underlying PrintWriter. This
|
||||
provides a crude but fairly portable way to determine whether or
|
||||
not the attempt to exec c++filt worked. */
|
||||
public int written = 0;
|
||||
|
||||
CPlusPlusDemangler (PrintWriter writer) throws IOException
|
||||
{
|
||||
p = writer;
|
||||
proc = Runtime.getRuntime ().exec ("c++filt -s java");
|
||||
procOut = proc.getOutputStream ();
|
||||
procIn = proc.getInputStream ();
|
||||
}
|
||||
|
||||
public void write (int b) throws IOException
|
||||
{
|
||||
procOut.write (b);
|
||||
while (procIn.available () != 0)
|
||||
{
|
||||
int c = procIn.read ();
|
||||
if (c == -1)
|
||||
break;
|
||||
else
|
||||
{
|
||||
p.write (c);
|
||||
written++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close () throws IOException
|
||||
{
|
||||
procOut.close ();
|
||||
int c;
|
||||
while ((c = procIn.read ()) != -1)
|
||||
{
|
||||
p.write (c);
|
||||
written++;
|
||||
}
|
||||
p.flush ();
|
||||
try
|
||||
{
|
||||
proc.waitFor ();
|
||||
}
|
||||
catch (InterruptedException _)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throwable is the superclass of all exceptions that can be raised.
|
||||
*
|
||||
@ -219,8 +149,7 @@ public class Throwable implements Serializable
|
||||
* no null entries
|
||||
* @since 1.4
|
||||
*/
|
||||
// XXX Don't initialize this, once fillInStackTrace() does it.
|
||||
private StackTraceElement[] stackTrace = {};
|
||||
private StackTraceElement[] stackTrace;
|
||||
|
||||
/**
|
||||
* Instantiate this Throwable with an empty message. The cause remains
|
||||
@ -449,26 +378,102 @@ public class Throwable implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a stack trace to the specified PrintWriter. See
|
||||
* {@link #printStackTrace()} for the sample format.
|
||||
* <p>Prints the exception, the detailed message and the stack trace
|
||||
* associated with this Throwable to the given <code>PrintWriter</code>.
|
||||
* The actual output written is implemention specific. Use the result of
|
||||
* <code>getStackTrace()</code> when more precise information is needed.
|
||||
*
|
||||
* <p>This implementation first prints a line with the result of this
|
||||
* object's <code>toString()</code> method.
|
||||
* <br>
|
||||
* Then for all elements given by <code>getStackTrace</code> it prints
|
||||
* a line containing three spaces, the string "at " and the result of calling
|
||||
* the <code>toString()</code> method on the <code>StackTraceElement</code>
|
||||
* object. If <code>getStackTrace()</code> returns an empty array it prints
|
||||
* a line containing three spaces and the string
|
||||
* "<<No stacktrace available>>".
|
||||
* <br>
|
||||
* Then if <code>getCause()</code> doesn't return null it adds a line
|
||||
* starting with "Caused by: " and the result of calling
|
||||
* <code>toString()</code> on the cause.
|
||||
* <br>
|
||||
* Then for every cause (of a cause, etc) the stacktrace is printed the
|
||||
* same as for the top level <code>Throwable</code> except that as soon
|
||||
* as all the remaining stack frames of the cause are the same as the
|
||||
* the last stack frames of the throwable that the cause is wrapped in
|
||||
* then a line starting with three spaces and the string "... X more" is
|
||||
* printed, where X is the number of remaining stackframes.
|
||||
*
|
||||
* @param w the PrintWriter to write the trace to
|
||||
* @since 1.1
|
||||
*/
|
||||
public void printStackTrace (PrintWriter wr)
|
||||
public void printStackTrace (PrintWriter pw)
|
||||
{
|
||||
try
|
||||
// First line
|
||||
pw.println(toString());
|
||||
|
||||
// The stacktrace
|
||||
StackTraceElement[] stack = getStackTrace();
|
||||
if (stack == null || stack.length == 0)
|
||||
{
|
||||
CPlusPlusDemangler cPlusPlusFilter = new CPlusPlusDemangler (wr);
|
||||
PrintWriter writer = new PrintWriter (cPlusPlusFilter);
|
||||
printRawStackTrace (writer);
|
||||
writer.close ();
|
||||
if (cPlusPlusFilter.written == 0) // The demangler has failed...
|
||||
printRawStackTrace (wr);
|
||||
pw.println(" <<No stacktrace available>>");
|
||||
return;
|
||||
}
|
||||
catch (Exception e1)
|
||||
else
|
||||
{
|
||||
printRawStackTrace (wr);
|
||||
for (int i = 0; i < stack.length; i++)
|
||||
pw.println(" at " + stack[i]);
|
||||
}
|
||||
|
||||
// The cause(s)
|
||||
Throwable cause = getCause();
|
||||
while (cause != null)
|
||||
{
|
||||
// Cause first line
|
||||
pw.println("Caused by: " + cause);
|
||||
|
||||
// Cause stacktrace
|
||||
StackTraceElement[] parentStack = stack;
|
||||
stack = cause.getStackTrace();
|
||||
if (stack == null || stack.length == 0)
|
||||
{
|
||||
pw.println(" <<No stacktrace available>>");
|
||||
}
|
||||
else if (parentStack == null || parentStack.length == 0)
|
||||
{
|
||||
for (int i = 0; i < stack.length; i++)
|
||||
pw.println(" at " + stack[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean equal = false; // Is rest of stack equal to parent frame?
|
||||
for (int i = 0; i < stack.length && ! equal; i++)
|
||||
{
|
||||
// Check if we already printed the rest of the stack
|
||||
// since it was the tail of the parent stack
|
||||
int remaining = stack.length - i;
|
||||
int element = i;
|
||||
int parentElement = parentStack.length - remaining;
|
||||
equal = parentElement >= 0
|
||||
&& parentElement < parentStack.length; // be optimistic
|
||||
while (equal && element < stack.length)
|
||||
{
|
||||
if (stack[element].equals(parentStack[parentElement]))
|
||||
{
|
||||
element++;
|
||||
parentElement++;
|
||||
}
|
||||
else
|
||||
equal = false;
|
||||
}
|
||||
// Print stacktrace element or indicate the rest is equal
|
||||
if (! equal)
|
||||
pw.println(" at " + stack[i]);
|
||||
else
|
||||
pw.println(" ..." + remaining + " more");
|
||||
}
|
||||
}
|
||||
cause = cause.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,6 +498,9 @@ public class Throwable implements Serializable
|
||||
*/
|
||||
public StackTraceElement[] getStackTrace()
|
||||
{
|
||||
if (stackTrace == null)
|
||||
stackTrace = getStackTrace0();
|
||||
|
||||
return stackTrace;
|
||||
}
|
||||
|
||||
@ -513,8 +521,8 @@ public class Throwable implements Serializable
|
||||
this.stackTrace = stackTrace;
|
||||
}
|
||||
|
||||
private native final void printRawStackTrace (PrintWriter wr);
|
||||
|
||||
private native final StackTraceElement[] getStackTrace0 ();
|
||||
|
||||
// Setting this flag to false prevents fillInStackTrace() from running.
|
||||
static boolean trace_enabled = true;
|
||||
private transient byte stackTraceBytes[];
|
||||
|
@ -22,6 +22,7 @@ details. */
|
||||
#include <java/lang/Object.h>
|
||||
#include <java-threads.h>
|
||||
#include <java/lang/Throwable.h>
|
||||
#include <java/lang/StackTraceElement.h>
|
||||
#include <java/io/PrintStream.h>
|
||||
#include <java/io/PrintWriter.h>
|
||||
#include <java/io/IOException.h>
|
||||
@ -67,38 +68,32 @@ java::lang::Throwable::fillInStackTrace (void)
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
java::lang::Throwable::printRawStackTrace (java::io::PrintWriter *wr)
|
||||
JArray<java::lang::StackTraceElement*> *
|
||||
java::lang::Throwable::getStackTrace0 ()
|
||||
{
|
||||
wr->println (toString ());
|
||||
#ifdef HAVE_BACKTRACE
|
||||
if (!stackTraceBytes)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
int depth = stackTraceBytes->length / sizeof (void *);
|
||||
void *p[depth];
|
||||
// This memcpy is esential; it ensures that the array of void* is
|
||||
// correctly aligned.
|
||||
memcpy (p, elements (stackTraceBytes), sizeof p);
|
||||
|
||||
JArray<java::lang::StackTraceElement*> *result;
|
||||
java::lang::StackTraceElement** el;
|
||||
result = reinterpret_cast <JArray<java::lang::StackTraceElement *>*>
|
||||
(JvNewObjectArray (depth, &java::lang::StackTraceElement::class$, NULL));
|
||||
el = elements (result);
|
||||
|
||||
_Jv_name_finder finder (_Jv_ThisExecutable ());
|
||||
|
||||
for (int i = 0; i < depth; i++)
|
||||
{
|
||||
bool found = finder.lookup (p[i]);
|
||||
wr->print (JvNewStringLatin1 (" at "));
|
||||
wr->print (JvNewStringLatin1 (finder.hex));
|
||||
if (found)
|
||||
{
|
||||
wr->print (JvNewStringLatin1 (": "));
|
||||
wr->print (JvNewStringLatin1 (finder.method_name));
|
||||
if (finder.file_name[0])
|
||||
{
|
||||
wr->print (JvNewStringLatin1 (" ("));
|
||||
wr->print (JvNewStringLatin1 (finder.file_name));
|
||||
wr->print (JvNewStringLatin1 (")"));
|
||||
}
|
||||
}
|
||||
wr->println ();
|
||||
}
|
||||
el[i] = finder.lookup (p[i]);
|
||||
|
||||
return result;
|
||||
#else
|
||||
return NULL;
|
||||
#endif /* HAVE_BACKTRACE */
|
||||
wr->flush ();
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ details. */
|
||||
_Jv_name_finder::_Jv_name_finder (char *executable)
|
||||
{
|
||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
|
||||
error = 0;
|
||||
demangling_error = lookup_error = 0;
|
||||
|
||||
// Initialize file descriptors so that shutdown works properly.
|
||||
f_pipe[0] = -1;
|
||||
@ -68,14 +68,21 @@ _Jv_name_finder::_Jv_name_finder (char *executable)
|
||||
b_pipe[1] = -1;
|
||||
b_pipe_fd = NULL;
|
||||
|
||||
char *argv[6];
|
||||
f2_pipe[0] = -1;
|
||||
f2_pipe[1] = -1;
|
||||
b2_pipe[0] = -1;
|
||||
b2_pipe[1] = -1;
|
||||
b2_pipe_fd = NULL;
|
||||
|
||||
// addr2line helper process.
|
||||
|
||||
char *argv[5];
|
||||
{
|
||||
int arg = 0;
|
||||
#ifdef __ia64__
|
||||
argv[arg++] = "addr2name.awk";
|
||||
#else
|
||||
argv[arg++] = "addr2line";
|
||||
argv[arg++] = "-C";
|
||||
argv[arg++] = "-f";
|
||||
argv[arg++] = "-e";
|
||||
#endif
|
||||
@ -83,10 +90,10 @@ _Jv_name_finder::_Jv_name_finder (char *executable)
|
||||
argv[arg] = NULL;
|
||||
}
|
||||
|
||||
error |= pipe (f_pipe) < 0;
|
||||
error |= pipe (b_pipe) < 0;
|
||||
lookup_error |= pipe (f_pipe) < 0;
|
||||
lookup_error |= pipe (b_pipe) < 0;
|
||||
|
||||
if (error)
|
||||
if (lookup_error)
|
||||
return;
|
||||
|
||||
pid = fork ();
|
||||
@ -109,18 +116,65 @@ _Jv_name_finder::_Jv_name_finder (char *executable)
|
||||
|
||||
if (pid < 0)
|
||||
{
|
||||
error |= 1;
|
||||
lookup_error |= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
b_pipe_fd = fdopen (b_pipe[0], "r");
|
||||
error |= !b_pipe_fd;
|
||||
lookup_error |= !b_pipe_fd;
|
||||
|
||||
if (! error)
|
||||
if (! lookup_error)
|
||||
{
|
||||
// Don't try to close the fd twice.
|
||||
b_pipe[0] = -1;
|
||||
}
|
||||
|
||||
// c++filt helper process.
|
||||
|
||||
char *argv2[4];
|
||||
argv2[0] = "c++filt";
|
||||
argv2[1] = "-s";
|
||||
argv2[2] = "java";
|
||||
argv2[3] = NULL;
|
||||
|
||||
demangling_error |= pipe (f2_pipe) < 0;
|
||||
demangling_error |= pipe (b2_pipe) < 0;
|
||||
|
||||
if (demangling_error)
|
||||
return;
|
||||
|
||||
pid2 = fork ();
|
||||
if (pid2 == 0)
|
||||
{
|
||||
close (f2_pipe[1]);
|
||||
close (b2_pipe[0]);
|
||||
dup2 (f2_pipe[0], fileno (stdin));
|
||||
dup2 (b2_pipe[1], fileno (stdout));
|
||||
execvp (argv2[0], argv2);
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
// Close child end of pipes. Set local descriptors to -1 so we
|
||||
// don't try to close the fd again.
|
||||
close (f2_pipe [0]);
|
||||
f2_pipe[0] = -1;
|
||||
close (b2_pipe [1]);
|
||||
b2_pipe[1] = -1;
|
||||
|
||||
if (pid2 < 0)
|
||||
{
|
||||
demangling_error |= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
b2_pipe_fd = fdopen (b2_pipe[0], "r");
|
||||
demangling_error |= !b2_pipe_fd;
|
||||
|
||||
if (! demangling_error)
|
||||
{
|
||||
// Don't try to close the fd twice.
|
||||
b2_pipe[0] = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -144,6 +198,94 @@ _Jv_name_finder::toHex (void *p)
|
||||
hex [digits+2] = 0;
|
||||
}
|
||||
|
||||
/* Creates a StackTraceElement given a string and a filename.
|
||||
Splits the given string into the class and method part.
|
||||
The string s will be a demangled to a fully qualified java method string.
|
||||
The string f will be decomposed into a file name and a possible line number.
|
||||
The given strings will be altered. */
|
||||
|
||||
java::lang::StackTraceElement*
|
||||
_Jv_name_finder::createStackTraceElement(char *s, char *f)
|
||||
{
|
||||
char *c;
|
||||
char *class_name = NULL;
|
||||
char *method_name = NULL;
|
||||
|
||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
|
||||
if (demangling_error)
|
||||
goto fail;
|
||||
|
||||
demangling_error |= write (f2_pipe[1], s, strlen (s)) < 0;
|
||||
if (demangling_error)
|
||||
goto fail;
|
||||
demangling_error |= write (f2_pipe[1], "\n", 1) < 0;
|
||||
if (demangling_error)
|
||||
goto fail;
|
||||
|
||||
char name[1024];
|
||||
demangling_error |= (fgets (name, sizeof name, b2_pipe_fd) == NULL);
|
||||
if (demangling_error)
|
||||
goto fail;
|
||||
|
||||
c = strchr (name, '\n');
|
||||
if (c)
|
||||
*c = 0;
|
||||
s = name;
|
||||
#endif
|
||||
|
||||
c = strchr (s, '(');
|
||||
if (c)
|
||||
{
|
||||
while(c-->s)
|
||||
if (*c == '.')
|
||||
break;
|
||||
|
||||
if (*c == '.')
|
||||
{
|
||||
*c = 0;
|
||||
class_name = s;
|
||||
method_name = c+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
class_name = NULL;
|
||||
method_name = s;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
class_name = NULL;
|
||||
method_name = s;
|
||||
}
|
||||
|
||||
// Get line number
|
||||
int line_number;
|
||||
c = strrchr (f, ':');
|
||||
if (c)
|
||||
{
|
||||
if (c[1] != 0)
|
||||
line_number = atoi(c+1);
|
||||
else
|
||||
line_number = -1;
|
||||
*c = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_number = -1;
|
||||
c = strchr (f, '\n');
|
||||
if (c)
|
||||
*c = 0;
|
||||
}
|
||||
|
||||
fail:
|
||||
return new java::lang::StackTraceElement(
|
||||
f ? JvNewStringLatin1 (f) : NULL,
|
||||
line_number,
|
||||
class_name ? JvNewStringLatin1 (class_name) : NULL,
|
||||
JvNewStringLatin1 (method_name ? method_name : s),
|
||||
false);
|
||||
}
|
||||
|
||||
/* 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.
|
||||
@ -151,12 +293,17 @@ _Jv_name_finder::toHex (void *p)
|
||||
Returns false if the lookup fails. Even if this happens, the field
|
||||
he will have been correctly filled in with the pointer. */
|
||||
|
||||
bool
|
||||
java::lang::StackTraceElement*
|
||||
_Jv_name_finder::lookup (void *p)
|
||||
{
|
||||
extern char **_Jv_argv;
|
||||
toHex (p);
|
||||
|
||||
char name[1024];
|
||||
char file_name[1024];
|
||||
|
||||
file_name[0] = 0;
|
||||
|
||||
#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
|
||||
{
|
||||
Dl_info dl_info;
|
||||
@ -166,45 +313,44 @@ _Jv_name_finder::lookup (void *p)
|
||||
if (dl_info.dli_fname)
|
||||
strncpy (file_name, dl_info.dli_fname, sizeof file_name);
|
||||
if (dl_info.dli_sname)
|
||||
strncpy (method_name, dl_info.dli_sname, sizeof method_name);
|
||||
strncpy (name, dl_info.dli_sname, sizeof name);
|
||||
|
||||
/* Don't trust dladdr() if the address is from the main program. */
|
||||
if (dl_info.dli_fname != NULL
|
||||
&& dl_info.dli_sname != NULL
|
||||
&& (_Jv_argv == NULL || strcmp (file_name, _Jv_argv[0]) != 0))
|
||||
return true;
|
||||
return createStackTraceElement (name, file_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy (name, hex, strlen (hex) + 1);
|
||||
|
||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
|
||||
if (error)
|
||||
return false;
|
||||
if (lookup_error)
|
||||
goto fail;
|
||||
|
||||
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;
|
||||
lookup_error |= write (f_pipe[1], hex, strlen (hex)) < 0;
|
||||
if (lookup_error)
|
||||
goto fail;
|
||||
lookup_error |= write (f_pipe[1], "\n", 1) < 0;
|
||||
if (lookup_error)
|
||||
goto fail;
|
||||
|
||||
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;
|
||||
lookup_error |= (fgets (name, sizeof name, b_pipe_fd) == NULL);
|
||||
if (lookup_error)
|
||||
goto fail;
|
||||
lookup_error |= (fgets (file_name, sizeof file_name, b_pipe_fd) == NULL);
|
||||
if (lookup_error)
|
||||
goto fail;
|
||||
|
||||
char *newline = strchr (method_name, '\n');
|
||||
if (newline)
|
||||
*newline = 0;
|
||||
newline = strchr (file_name, '\n');
|
||||
if (newline)
|
||||
*newline = 0;
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
return false;
|
||||
{
|
||||
char *newline = strchr (name, '\n');
|
||||
if (newline)
|
||||
*newline = 0;
|
||||
}
|
||||
#endif /* defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP) */
|
||||
|
||||
fail:
|
||||
return (createStackTraceElement (name, file_name));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user