Ich habe es geschafft, meine Frage zu beantworten. Für das, was ich aus dem Quellcode verstehen könnte, ist es 3 mögliche Eintrittspunkte für die Java-Anrufe:
- ArtMethod :: Invoke (Kunst/runtime/Spiegel/art_method.cc)
- Execute (Kunst/Laufzeit /interpreter/interpreter.cc)
- DoCall (Kunst/runtime/Interpret/interpreter_common.cc)
ArtMethod :: Invoke scheint für die Reflexion verwendet werden soll und für das Verfahren direkt mit einem Zeiger auf die OAT Aufruf Codeabschnitt. (Wiederum keine Dokumentation, es kann ungenau sein).
Führen Sie am Ende Calling DoCall im Allgemeinen.
Es gibt einige Optimierungen von ART, die das Studium von Java-Aufrufen erschweren, wie Methodeninlining und direktes Offset-Adress-Calling.
Der erste Schritt ist die Sperrung dieser Optimierungen:
In device/Marken-Name/Typ/device.mk (in meinem Fall device/LGE/Hammer/device.mk für ein Nexus-5):
Fügen Sie die Option "nur interpretieren" zu dex2oat hinzu. Mit dieser Option kompiliert ART nur den Boot-Klassenpfad, sodass die Anwendungen nicht in OAT kompiliert werden.
PRODUCT_PROPERTY_OVERRIDES := \
dalvik.vm.dex2oat-filter=interpret-only
Der zweite Schritt ist in der Technik inlining/Compiler/DEX/frontend.cc zu deaktivieren:
Uncomment "kSuppressMethodInlining".
/* Default optimizer/debug setting for the compiler. */
static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations
(1 << kLoadStoreElimination) |
// (1 << kLoadHoisting) |
// (1 << kSuppressLoads) |
// (1 << kNullCheckElimination) |
// (1 << kClassInitCheckElimination) |
(1 << kGlobalValueNumbering) |
// (1 << kPromoteRegs) |
// (1 << kTrackLiveTemps) |
// (1 << kSafeOptimizations) |
// (1 << kBBOpt) |
// (1 << kMatch) |
// (1 << kPromoteCompilerTemps) |
// (1 << kSuppressExceptionEdges) |
(1 << kSuppressMethodInlining) |
0;
Der letzte Schritt ist die direkte Code-Offset-Aufruf in der Kunst/Compiler/Treiber/compiler_driver.cc zu deaktivieren:
-bool use_dex_cache = GetCompilerOptions().GetCompilePic();
+bool use_dex_cache = true;
Mit diesen Änderungen alle verschiedenen Anrufe in der DoCall Funktion fallen, wo wir können Schließlich fügen Sie unsere gezielte Protokollierungsroutine hinzu.
In art/runtime/Interpreter/interpreter_common.h, am Anfang ADD des umfasst:
#ifdef HAVE_ANDROID_OS
#include "cutils/properties.h"
#endif
In art/runtime/Interpreter/interpreter_common.cc, zu Beginn der Funktion DoCall hinzuzufügen:
#ifdef HAVE_ANDROID_OS
char targetAppVar[92];
property_get("target.app.pid", targetAppVar, "0");
int targetAppPID = atoi(targetAppVar);
if(targetAppPID != 0 && targetAppPID == getpid())
LOG(INFO) << "DoCall - " << PrettyMethod(method, true);
#endif
Zum Targeting der Anwendung verwende ich eine Eigenschaft, die die Ziel-PID festlegen. Dafür benötigen wir das lib system/core/libcutils und diese lib steht nur zur Verfügung, wenn das AOSP für ein echtes Telefon kompiliert wurde (ohne mit den aktuellen Makefiles zu verfahren).
Also die Lösung wird nicht für einen Emulator funktionieren. (
Nur Raten, nie ausprobiert
EDIT: bestätigt, "cutils/properties.h" kann nicht zum Build eines Emulators hinzugefügt werden).
Nach dem Kompilieren und Flashen des gepatchten AOSP, starten Sie eine App, ps | grep für die PID zu finden und legen Sie die Eigenschaft in root:
[email protected]:/ # ps | grep contacts
u0_a2 4278 129 1234668 47356 ffffffff 401e8318 S com.android.contacts
[email protected]:/ # setprop target.app.pid 4278
[email protected]:/ # logcat
[...]
I/art (4278): DoCall - int android.view.View.getId()
I/art (4278): DoCall - void com.android.contacts.activities.PeopleActivity$ContactsUnavailableFragmentListener.onCreateNewContactAction()
I/art (4278): DoCall - void android.content.Intent.<init>(java.lang.String, android.net.Uri)
I/art (4278): DoCall - void android.app.Activity.startActivity(android.content.Intent)
I/ActivityManager( 498): START u0 {act=android.intent.action.INSERT dat=content://com.android.contacts/contacts cmp=com.android.contacts/.activities.ContactEditorActivity} from uid 10002 on display 0
V/WindowManager( 498): addAppToken: AppWindowToken{3a82282b token=Token{dc3f87a ActivityRecord{c0aaca5 u0 com.android.contacts/.activities.ContactEditorActivity t4}}} to stack=1 task=4 at 1
I/art (4278): DoCall - void android.app.Fragment.onPause()
I/art (4278): DoCall - void com.android.contacts.common.list.ContactEntryListFragment.removePendingDirectorySearchRequests()
I/art (4278): DoCall - void android.os.Handler.removeMessages(int)
I/art (4278): DoCall - void com.android.contacts.list.ProviderStatusWatcher.stop()
I/art (4278): DoCall - boolean com.android.contacts.list.ProviderStatusWatcher.isStarted()
I/art (4278): DoCall - void android.os.Handler.removeCallbacks(java.lang.Runnable)
I/art (4278): DoCall - android.content.ContentResolver com.android.contacts.ContactsActivity.getContentResolver()
I/art (4278): DoCall - void android.content.ContentResolver.unregisterContentObserver(android.database.ContentObserver)
I/art (4278): DoCall - void android.app.Activity.onPause()
I/art (4278): DoCall - void android.view.ViewGroup.drawableStateChanged()
I/art (4278): DoCall - void com.android.contacts.ContactsActivity.<init>()
I/art (4278): DoCall - void com.android.contacts.common.activity.TransactionSafeActivity.<init>()
I/art (4278): DoCall - void android.app.Activity.<init>()
I/art (4278): DoCall - void com.android.contacts.util.DialogManager.<init>(android.app.Activity)
I/art (4278): DoCall - void java.lang.Object.<init>()
[...]
Wenn es vorbei ist:
[email protected]:/ # setprop target.app.pid 0
Voilà!
Die Überlastung ist aus Benutzersicht nicht wahrnehmbar, aber das logcat wird schnell gefüllt.
PS: Dateipfade und -namen stimmen mit der Android 5-Version (Lollipop) überein, sie unterscheiden sich wahrscheinlich von den höheren Versionen.
PS ': Wenn man die Argumente der Methoden ausdrucken möchte, rate ich dazu, art/runtime/utils.cc für die PrettyArguments-Methode zu betrachten und irgendwo im Code eine praktische Implementierung zu finden.
Vielen Dank dies zu erläutern. Ich habe eine Frage. Wenn ich den AOSP-Code wie beschrieben patchen und ein Android-Systemabbild für einen Emulator erstellen möchte, wo sollte ich die Option "nur interpretieren" hinzufügen? Ich konnte die Datei device.mk für den Emulator nicht finden. Bitte lass es mich wissen. – aMa
Was ist Ihr Zielgerät? Mein war ein Nexus 5 Hammerhead, also ist mein Pfad /device/lge/hammerhead/device.mk. –
Sry, ich habe gerade zu schnell gelesen. Ich habe nie versucht für einen Emulator und Sie werden wahrscheinlich Probleme mit libcutils für die Funktion property_get haben. Hast du es schon ohne die Änderungen an der device.mk versucht? Es sollte im schlimmsten Fall ohne es funktionieren. Ohne es ist das Schlimmste, was passieren kann, dass Sie einige der Anrufe verpassen. –