add optional avian.error.log system property

This property may be used to specify a file name to use for printing
stack traces for unhandled exceptions.  The default is stderr.
This commit is contained in:
Joel Dice 2011-03-15 17:27:17 -06:00
parent 51c8d7511a
commit e5ecb5b549
2 changed files with 26 additions and 9 deletions

View File

@ -2258,6 +2258,7 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
referenceLock(0), referenceLock(0),
shutdownLock(0), shutdownLock(0),
libraries(0), libraries(0),
errorLog(0),
types(0), types(0),
roots(0), roots(0),
finalizers(0), finalizers(0),
@ -3888,19 +3889,19 @@ printTrace(Thread* t, object exception)
for (object e = exception; e; e = throwableCause(t, e)) { for (object e = exception; e; e = throwableCause(t, e)) {
if (e != exception) { if (e != exception) {
fprintf(stderr, "caused by: "); fprintf(errorLog(t), "caused by: ");
} }
fprintf(stderr, "%s", &byteArrayBody fprintf(errorLog(t), "%s", &byteArrayBody
(t, className(t, objectClass(t, e)), 0)); (t, className(t, objectClass(t, e)), 0));
if (throwableMessage(t, e)) { if (throwableMessage(t, e)) {
object m = throwableMessage(t, e); object m = throwableMessage(t, e);
THREAD_RUNTIME_ARRAY(t, char, message, stringLength(t, m) + 1); THREAD_RUNTIME_ARRAY(t, char, message, stringLength(t, m) + 1);
stringChars(t, m, RUNTIME_ARRAY_BODY(message)); stringChars(t, m, RUNTIME_ARRAY_BODY(message));
fprintf(stderr, ": %s\n", RUNTIME_ARRAY_BODY(message)); fprintf(errorLog(t), ": %s\n", RUNTIME_ARRAY_BODY(message));
} else { } else {
fprintf(stderr, "\n"); fprintf(errorLog(t), "\n");
} }
object trace = throwableTrace(t, e); object trace = throwableTrace(t, e);
@ -3914,17 +3915,17 @@ printTrace(Thread* t, object exception)
int line = t->m->processor->lineNumber int line = t->m->processor->lineNumber
(t, traceElementMethod(t, e), traceElementIp(t, e)); (t, traceElementMethod(t, e), traceElementIp(t, e));
fprintf(stderr, " at %s.%s ", class_, method); fprintf(errorLog(t), " at %s.%s ", class_, method);
switch (line) { switch (line) {
case NativeLine: case NativeLine:
fprintf(stderr, "(native)\n"); fprintf(errorLog(t), "(native)\n");
break; break;
case UnknownLine: case UnknownLine:
fprintf(stderr, "(unknown line)\n"); fprintf(errorLog(t), "(unknown line)\n");
break; break;
default: default:
fprintf(stderr, "(line %d)\n", line); fprintf(errorLog(t), "(line %d)\n", line);
} }
} }
} }
@ -3934,7 +3935,7 @@ printTrace(Thread* t, object exception)
} }
} }
fflush(stderr); fflush(errorLog(t));
} }
object object

View File

@ -1298,6 +1298,7 @@ class Machine {
System::Monitor* referenceLock; System::Monitor* referenceLock;
System::Monitor* shutdownLock; System::Monitor* shutdownLock;
System::Library* libraries; System::Library* libraries;
FILE* errorLog;
object types; object types;
object roots; object roots;
object finalizers; object finalizers;
@ -3577,6 +3578,21 @@ methodClone(Thread* t, object method)
methodCode(t, method)); methodCode(t, method));
} }
inline FILE*
errorLog(Thread* t)
{
if (t->m->errorLog == 0) {
const char* path = findProperty(t, "avian.error.log");
if (path) {
t->m->errorLog = vm::fopen(path, "wb");
} else {
t->m->errorLog = stderr;
}
}
return t->m->errorLog;
}
} // namespace vm } // namespace vm
void void