* early on in VM initialization. There's nothing better to do
* than just log the message as an error and abort.
*/
- LOGE("Fatal error: %s", msg);
+ ALOGE("Fatal error: %s", msg);
dvmAbort();
}
/* make sure the exception is initialized */
if (!dvmIsClassInitialized(excepClass) && !dvmInitClass(excepClass)) {
- LOGE("ERROR: unable to initialize exception class '%s'",
+ ALOGE("ERROR: unable to initialize exception class '%s'",
excepClass->descriptor);
if (strcmp(excepClass->descriptor, "Ljava/lang/InternalError;") == 0)
dvmAbort();
*/
if (dvmCheckException(self))
goto bail;
- LOGE("FATAL: unable to allocate exception '%s' '%s'",
+ ALOGE("FATAL: unable to allocate exception '%s' '%s'",
excepClass->descriptor, msg != NULL ? msg : "(no msg)");
dvmAbort();
}
else {
msgStr = dvmCreateStringFromCstr(msg);
if (msgStr == NULL) {
- LOGW("Could not allocate message string \"%s\" while "
+ ALOGW("Could not allocate message string \"%s\" while "
"throwing internal exception (%s)",
msg, excepClass->descriptor);
goto bail;
if (cause != NULL) {
if (!dvmInstanceof(cause->clazz, gDvm.exThrowable)) {
- LOGE("Tried to init exception with cause '%s'",
+ ALOGE("Tried to init exception with cause '%s'",
cause->clazz->descriptor);
dvmAbort();
}
* constructor, e.g. it doesn't provide one that takes a string
* when a message has been provided.
*/
- LOGW("WARNING: exception class '%s' missing constructor "
+ ALOGW("WARNING: exception class '%s' missing constructor "
"(msg='%s' kind=%d)",
excepClass->descriptor, msg, initKind);
assert(strcmp(excepClass->descriptor,
* return an error and let our caller deal with it.
*/
if (self->exception != NULL) {
- LOGW("Exception thrown (%s) while throwing internal exception (%s)",
+ ALOGW("Exception thrown (%s) while throwing internal exception (%s)",
self->exception->clazz->descriptor, exception->clazz->descriptor);
goto bail;
}
/* initCause() threw an exception; return an error and
* let the caller deal with it.
*/
- LOGW("Exception thrown (%s) during initCause() "
+ ALOGW("Exception thrown (%s) during initCause() "
"of internal exception (%s)",
self->exception->clazz->descriptor,
exception->clazz->descriptor);
goto bail;
}
} else {
- LOGW("WARNING: couldn't find initCause in '%s'",
+ ALOGW("WARNING: couldn't find initCause in '%s'",
excepClass->descriptor);
}
}
Object* dvmGetExceptionCause(const Object* exception)
{
if (!dvmInstanceof(exception->clazz, gDvm.exThrowable)) {
- LOGE("Tried to get cause from object of type '%s'",
+ ALOGE("Tried to get cause from object of type '%s'",
exception->clazz->descriptor);
dvmAbort();
}
JValue unused;
dvmCallMethod(self, printMethod, exception, &unused);
} else {
- LOGW("WARNING: could not find printStackTrace in %s",
+ ALOGW("WARNING: could not find printStackTrace in %s",
exception->clazz->descriptor);
}
if (self->exception != NULL) {
- LOGW("NOTE: exception thrown while printing stack trace: %s",
+ ALOGW("NOTE: exception thrown while printing stack trace: %s",
self->exception->clazz->descriptor);
}
* up a warning, then move on to the next entry.
* Keep the exception status clear.
*/
- LOGW("Could not resolve class ref'ed in exception "
+ ALOGW("Could not resolve class ref'ed in exception "
"catch list (class index %d, exception %s)",
handler->typeIdx,
(self->exception != NULL) ?
}
}
- //LOGD("ADDR MATCH, check %s instanceof %s",
+ //ALOGD("ADDR MATCH, check %s instanceof %s",
// excepClass->descriptor, pEntry->excepClass->descriptor);
if (dvmInstanceof(excepClass, throwable)) {
break;
if (!dvmInstanceof(method->clazz, gDvm.exThrowable))
break;
- //LOGD("EXCEP: ignoring %s.%s",
+ //ALOGD("EXCEP: ignoring %s.%s",
// method->clazz->descriptor, method->name);
fp = saveArea->prevFrame;
}
assert(fp != saveArea->prevFrame);
fp = saveArea->prevFrame;
}
- //LOGD("EXCEP: stack depth is %d", stackDepth);
+ //ALOGD("EXCEP: stack depth is %d", stackDepth);
if (!stackDepth)
goto bail;
const Method* method = saveArea->method;
if (!dvmIsBreakFrame((u4*)fp)) {
- //LOGD("EXCEP keeping %s.%s", method->clazz->descriptor,
+ //ALOGD("EXCEP keeping %s.%s", method->clazz->descriptor,
// method->name);
*intPtr++ = (int) method;
std::string dotName(dvmHumanReadableDescriptor(meth->clazz->descriptor));
if (dvmIsNativeMethod(meth)) {
- LOGI("\tat %s.%s(Native Method)", dotName.c_str(), meth->name);
+ ALOGI("\tat %s.%s(Native Method)", dotName.c_str(), meth->name);
} else {
- LOGI("\tat %s.%s(%s:%d)",
+ ALOGI("\tat %s.%s(%s:%d)",
dotName.c_str(), meth->name, dvmGetMethodSourceFile(meth),
dvmLineNumFromPC(meth, pc));
}
dvmChangeStatus(self, oldStatus);
} else {
- LOGW("WARNING: could not find getMessage in %s",
+ ALOGW("WARNING: could not find getMessage in %s",
exception->clazz->descriptor);
}
if (dvmGetException(self) != NULL) {
- LOGW("NOTE: exception thrown while retrieving exception message: %s",
+ ALOGW("NOTE: exception thrown while retrieving exception message: %s",
dvmGetException(self)->clazz->descriptor);
/* will be overwritten below */
}
dvmReleaseTrackedAlloc((Object*) messageStr, dvmThreadSelf());
messageStr = NULL;
- LOGI("%s: %s", className.c_str(), cp);
+ ALOGI("%s: %s", className.c_str(), cp);
free(cp);
} else {
- LOGI("%s:", className.c_str());
+ ALOGI("%s:", className.c_str());
}
/*
const ArrayObject* stackData = (const ArrayObject*) dvmGetFieldObject(exception,
gDvm.offJavaLangThrowable_stackState);
if (stackData == NULL) {
- LOGI(" (raw stack trace not found)");
+ ALOGI(" (raw stack trace not found)");
return;
}
Object* cause;
if (exception == NULL) {
- LOGW("tried to log a null exception?");
+ ALOGW("tried to log a null exception?");
return;
}
if (cause == NULL) {
break;
}
- LOGI("Caused by:");
+ ALOGI("Caused by:");
exception = cause;
}
}
void dvmThrowExceptionInInitializerError()
{
/*
- * TODO: Do we want to wrap it if the original is an Error rather than
- * an Exception?
- *
* TODO: Should this just use dvmWrapException()?
*/
- if (gDvm.exExceptionInInitializerError == NULL) {
+ if (gDvm.exExceptionInInitializerError == NULL || gDvm.exError == NULL) {
/*
* ExceptionInInitializerError isn't itself initialized. This
* can happen very early during VM startup if there is a
* anything fancier, we just abort here with a blatant
* message.
*/
- LOGE("Fatal error during early class initialization:");
+ ALOGE("Fatal error during early class initialization:");
dvmLogExceptionStackTrace();
dvmAbort();
}
Thread* self = dvmThreadSelf();
Object* exception = dvmGetException(self);
+ // We only wrap non-Error exceptions; an Error can just be used as-is.
+ if (dvmInstanceof(exception->clazz, gDvm.exError)) {
+ return;
+ }
+
dvmAddTrackedAlloc(exception, self);
dvmClearException(self);
dvmThrowException(gDvm.exUnsatisfiedLinkError, msg);
}
+void dvmThrowUnsatisfiedLinkError(const char* msg, const Method* method) {
+ char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
+ char* className = dvmDescriptorToDot(method->clazz->descriptor);
+ dvmThrowExceptionFmt(gDvm.exUnsatisfiedLinkError, "%s: %s.%s:%s",
+ msg, className, method->name, desc);
+ free(className);
+ free(desc);
+}
+
void dvmThrowUnsupportedOperationException(const char* msg) {
dvmThrowException(gDvm.exUnsupportedOperationException, msg);
}