Better error reporting when loading dex files
Collect all partial error messages and return them as cause
exceptions for the top-level exception returned.
Change-Id: I9661b8aed2a571dc88bf0f06d447108eeaed1409
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 15a5779..6af16f4 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -104,6 +104,7 @@
uint32_t dex_location_checksum;
uint32_t* dex_location_checksum_pointer = &dex_location_checksum;
+ std::vector<std::string> error_msgs;
std::string error_msg;
if (!DexFile::GetChecksum(sourceName.c_str(), dex_location_checksum_pointer, &error_msg)) {
dex_location_checksum_pointer = NULL;
@@ -113,9 +114,8 @@
const DexFile* dex_file;
if (outputName.c_str() == nullptr) {
// FindOrCreateOatFileForDexLocation can tolerate a missing dex_location_checksum
- error_msg.clear();
dex_file = linker->FindDexFileInOatFileFromDexLocation(sourceName.c_str(),
- dex_location_checksum_pointer, &error_msg);
+ dex_location_checksum_pointer, &error_msgs);
} else {
// FindOrCreateOatFileForDexLocation requires the dex_location_checksum
if (dex_location_checksum_pointer == NULL) {
@@ -125,12 +125,19 @@
return 0;
}
dex_file = linker->FindOrCreateOatFileForDexLocation(sourceName.c_str(), dex_location_checksum,
- outputName.c_str(), &error_msg);
+ outputName.c_str(), &error_msgs);
}
if (dex_file == nullptr) {
ScopedObjectAccess soa(env);
- CHECK(!error_msg.empty());
- ThrowIOException("%s", error_msg.c_str());
+ CHECK(!error_msgs.empty());
+ // The most important message is at the end. So set up nesting by going forward, which will
+ // wrap the existing exception as a cause for the following one.
+ auto it = error_msgs.begin();
+ auto itEnd = error_msgs.end();
+ for ( ; it != itEnd; ++it) {
+ ThrowWrappedIOException("%s", it->c_str());
+ }
+
return 0;
}
return static_cast<jlong>(reinterpret_cast<uintptr_t>(dex_file));