// Don't list methods that do not match a particular query. if (gOptions.methodToFind != nullptr &&
(strcmp(gOptions.classToFind, className.get()) != 0 ||
strcmp(gOptions.methodToFind, methodName) != 0)) { return;
}
// If the filename is empty, then set it to something printable. if (fileName == nullptr || fileName[0] == 0) {
fileName = "(none)";
}
// We just want to catch the number of the first line in the method, which *should* correspond to // the first entry from the table. int first_line = -1;
accessor.DecodeDebugPositionInfo([&](const DexFile::PositionInfo& entry) {
first_line = entry.line_; returntrue; // Early exit since we only want the first line.
});
/* *Processesasinglefile(eitherdirect.dexorindirect.zip/.jar/.apk).
*/ staticint processFile(constchar* fileName) { // If the file is not a .dex file, the function tries .zip/.jar/.apk files, // all of which are Zip archives with "classes.dex" inside. static constexpr bool kVerifyChecksum = true;
std::string content; // TODO: add an api to android::base to read a std::vector<uint8_t>. if (!android::base::ReadFileToString(fileName, &content)) {
LOG(ERROR) << "ReadFileToString failed"; return -1;
}
std::vector<std::unique_ptr<const DexFile>> dex_files;
DexFileLoaderErrorCode error_code;
std::string error_msg;
DexFileLoader dex_file_loader( reinterpret_cast<const uint8_t*>(content.data()), content.size(), fileName); if (!dex_file_loader.Open( /*verify=*/true, kVerifyChecksum, &error_code, &error_msg, &dex_files)) {
LOG(ERROR) << error_msg; return -1;
}
// Success. Iterate over all dex files found in given file.
fprintf(gOutFile, "#%s\n", fileName); for (size_t i = 0; i < dex_files.size(); i++) { // Iterate over all classes in one dex file. const DexFile* pDexFile = dex_files[i].get(); const u4 classDefsSize = pDexFile->GetHeader().class_defs_size_; for (u4 idx = 0; idx < classDefsSize; idx++) {
dumpClass(pDexFile, idx);
}
} return0;
}
// Parse all arguments. while (true) { constint ic = getopt(argc, argv, "o:m:"); if (ic < 0) { break; // done
} switch (ic) { case'o': // output file
gOptions.outputFileName = optarg; break; case'm': // If -m p.c.m is given, then find all instances of the // fully-qualified method name. This isn't really what // dexlist is for, but it's easy to do it here.
{
gOptions.argCopy = strdup(optarg); char* meth = strrchr(gOptions.argCopy, '.'); if (meth == nullptr) {
LOG(ERROR) << "Expected: package.Class.method";
wantUsage = true;
} else {
*meth = '\0';
gOptions.classToFind = gOptions.argCopy;
gOptions.methodToFind = meth + 1;
}
} break; default:
wantUsage = true; break;
} // switch
} // while
// Detect early problems. if (optind == argc) {
LOG(ERROR) << "No file specified";
wantUsage = true;
} if (wantUsage) {
usage();
free(gOptions.argCopy); return2;
}
// Open alternative output file. if (gOptions.outputFileName) {
gOutFile = fopen(gOptions.outputFileName, "we"); if (!gOutFile) {
PLOG(ERROR) << "Can't open " << gOptions.outputFileName;
free(gOptions.argCopy); return1;
}
}
// Process all files supplied on command line. If one of them fails we // continue on, only returning a failure at the end. int result = 0; while (optind < argc) {
result |= processFile(argv[optind++]);
} // while
free(gOptions.argCopy); return result != 0 ? 1 : 0;
}
} // namespace art
int main(int argc, char** argv) { // Output all logging to stderr.
android::base::SetLogger(android::base::StderrLogger);
art::MemMap::Init();
return art::dexlistDriver(argc, argv);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.