1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <jni.h>
18 #include <signal.h>
19 #include <stdlib.h>
20
21 #include "android/log.h"
22
23 #define COVERAGE_FLUSH_SIGNAL (__SIGRTMIN + 5)
24 const char *TAG = "CoverageDumper";
25
26 // Retrieve the method registered for SIG COVERAGE_FLUSH_SIGNAL(37) and
27 // execute it. This method can only be executed once in the lifetime of a
28 // process and MUST BE executed before the process exits. Successive executions
29 // will result in noops (No operations).
30 //
31 // More context:
32 // https://cs.android.com/android/platform/superproject/main/+/main:system/extras/toolchain-extras/profile-clang-extras.cpp;l=52
33 // Everytime a piece of code (eg: shared_library gets loaded, a process starts),
34 // `init_profile_extras` gets executed, that method chains coverge dump methods.
35 //
36 // What we do here is that we pick the head of the chain and execute it.
37 JNIEXPORT void
Java_com_android_modules_utils_testing_NativeCoverageHackInstrumentationListener_dumpCoverage(JNIEnv * env)38 Java_com_android_modules_utils_testing_NativeCoverageHackInstrumentationListener_dumpCoverage(
39 JNIEnv *env) {
40 sighandler_t ret = signal(COVERAGE_FLUSH_SIGNAL, SIG_IGN);
41 if (ret != SIG_ERR && ret != SIG_IGN && ret != SIG_DFL) {
42 __android_log_print(ANDROID_LOG_INFO, TAG, "Coverage dumped.");
43 // The signum is unused.
44 (ret)(/* signum */ COVERAGE_FLUSH_SIGNAL);
45 } else {
46 // Clang did not register its signal handler which means that the code
47 // was not compiled under coverage variant.
48 __android_log_print(ANDROID_LOG_INFO, TAG,
49 "No coverage signal registered! No-op");
50 }
51 }