Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d857b662 authored by Yu-Ting Tseng's avatar Yu-Ting Tseng
Browse files

Support target process in dynamic instrumentation

Make DynamicInstrumentationManagerService talk to an app process to
obtain method offsets when the target process is an app. This is done
via calling a new AIDL method
IApplicationThread.getExecutableMethodFileOffsets. The implementation
(ActivityThread) runs in an app process and calls ART VMDebug in-process
to get the offsets.

The offset results are now provided asynchronously both from app to
system_server, and from system_server to uprobestats. This way
system_server would not block on an app process.

Bug: 372925025
Flag: com.android.art.flags.executable_method_file_offsets
Change-Id: Ie58a21d12530000b858aa292a406755a158b4c4a
Test: atest ExecutableMethodFileOffsetsTest
parent 62ebefc2
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ import android.os.PowerExemptionManager.ReasonCode;
import android.os.PowerExemptionManager.TempAllowListType;
import android.os.TransactionTooLargeException;
import android.os.WorkSource;
import android.os.instrumentation.IOffsetCallback;
import android.os.instrumentation.MethodDescriptor;
import android.util.ArraySet;
import android.util.Pair;

@@ -1338,6 +1340,14 @@ public abstract class ActivityManagerInternal {
    public abstract void killApplicationSync(String pkgName, int appId, int userId,
            String reason, int exitInfoReason);

    /**
     * Queries the offset data for a given method on a process.
     * @hide
     */
    public abstract void getExecutableMethodFileOffsets(@NonNull String processName,
            int pid, int uid, @NonNull MethodDescriptor methodDescriptor,
            @NonNull IOffsetCallback callback);

    /**
     * Add a creator token for all embedded intents (stored as extra) of the given intent.
     *
+27 −0
Original line number Diff line number Diff line
@@ -165,6 +165,10 @@ import android.os.TelephonyServiceManager;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.instrumentation.ExecutableMethodFileOffsets;
import android.os.instrumentation.IOffsetCallback;
import android.os.instrumentation.MethodDescriptor;
import android.os.instrumentation.MethodDescriptorParser;
import android.permission.IPermissionManager;
import android.provider.BlockedNumberContract;
import android.provider.CalendarContract;
@@ -2225,6 +2229,29 @@ public final class ActivityThread extends ClientTransactionHandler
            args.arg6 = uiTranslationSpec;
            sendMessage(H.UPDATE_UI_TRANSLATION_STATE, args);
        }

        @Override
        public void getExecutableMethodFileOffsets(
                @NonNull MethodDescriptor methodDescriptor,
                @NonNull IOffsetCallback resultCallback) {
            Method method = MethodDescriptorParser.parseMethodDescriptor(
                    getClass().getClassLoader(), methodDescriptor);
            VMDebug.ExecutableMethodFileOffsets location =
                    VMDebug.getExecutableMethodFileOffsets(method);
            try {
                if (location == null) {
                    resultCallback.onResult(null);
                    return;
                }
                ExecutableMethodFileOffsets ret = new ExecutableMethodFileOffsets();
                ret.containerPath = location.getContainerPath();
                ret.containerOffset = location.getContainerOffset();
                ret.methodOffset = location.getMethodOffset();
                resultCallback.onResult(ret);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    private @NonNull SafeCancellationTransport createSafeCancellationTransport(
+4 −0
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.SharedMemory;
import android.os.instrumentation.IOffsetCallback;
import android.os.instrumentation.MethodDescriptor;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationSpec;
@@ -183,4 +185,6 @@ oneway interface IApplicationThread {
    void scheduleTimeoutService(IBinder token, int startId);
    void scheduleTimeoutServiceForType(IBinder token, int startId, int fgsType);
    void schedulePing(in RemoteCallback pong);
    void getExecutableMethodFileOffsets(in MethodDescriptor methodDescriptor,
            in IOffsetCallback resultCallback);
}
+4 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package android.os.instrumentation;

import android.os.instrumentation.ExecutableMethodFileOffsets;
import android.os.instrumentation.IOffsetCallback;
import android.os.instrumentation.MethodDescriptor;
import android.os.instrumentation.TargetProcess;

@@ -28,6 +28,7 @@ import android.os.instrumentation.TargetProcess;
interface IDynamicInstrumentationManager {
    /** Provides ART metadata about the described compiled method within the target process */
    @PermissionManuallyEnforced
    @nullable ExecutableMethodFileOffsets getExecutableMethodFileOffsets(
            in TargetProcess targetProcess, in MethodDescriptor methodDescriptor);
    void getExecutableMethodFileOffsets(
            in TargetProcess targetProcess, in MethodDescriptor methodDescriptor,
            in IOffsetCallback callback);
}
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os.instrumentation;

import android.os.instrumentation.ExecutableMethodFileOffsets;

/**
 * System private API for providing dynamic instrumentation offset results.
 *
 * {@hide}
 */
oneway interface IOffsetCallback {
    void onResult(in @nullable ExecutableMethodFileOffsets offsets);
}
Loading