blob: 55a9b991cae095df1fffe467d3ac48488f0558cb [file] [log] [blame]
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -07001/*
2 * Copyright (C) 2019 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 <errno.h>
18#include <pthread.h>
19#include <signal.h>
Pirama Arumuga Nainar4cedcc62019-05-29 14:18:18 -070020#include <stdlib.h>
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070021#include <string.h>
Pirama Arumuga Nainar4cedcc62019-05-29 14:18:18 -070022#include <libgen.h> // For POSIX basename().
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070023
24// Use _system_properties.h to use __system_property_wait_any()
25#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
26#include <sys/_system_properties.h>
27
28#include "profile-extras.h"
29
30extern "C" {
31
Pirama Arumuga Nainar97f274e2021-01-15 15:27:59 -080032void __gcov_dump(void);
33void __gcov_reset(void);
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070034
Ray Essickb5d273d2020-01-09 11:51:27 -080035// storing SIG_ERR helps us detect (unlikely) looping.
36static sighandler_t chained_gcov_signal_handler = SIG_ERR;
37
38static void gcov_signal_handler(int signum) {
Pirama Arumuga Nainar97f274e2021-01-15 15:27:59 -080039 __gcov_dump();
40 __gcov_reset();
Ray Essickb5d273d2020-01-09 11:51:27 -080041 if (chained_gcov_signal_handler != SIG_ERR &&
42 chained_gcov_signal_handler != SIG_IGN &&
43 chained_gcov_signal_handler != SIG_DFL) {
44 (chained_gcov_signal_handler)(signum);
45 }
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070046}
47
Pirama Arumuga Nainare76c23d2019-06-03 10:56:35 -070048__attribute__((weak)) int init_profile_extras_once = 0;
49
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070050// Initialize libprofile-extras:
Oliver Nguyena0d4f062019-12-09 16:36:08 -080051// - Install a signal handler that triggers __gcov_flush on <COVERAGE_FLUSH_SIGNAL>.
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070052//
53// We want this initiazlier to run during load time.
54//
55// Just marking init_profile_extras() with __attribute__((constructor)) isn't
56// enough since the linker drops it from its output since no other symbol from
57// this static library is referenced.
58//
59// We force the linker to include init_profile_extras() by passing
60// '-uinit_profile_extras' to the linker (in build/soong).
61__attribute__((constructor)) int init_profile_extras(void) {
Pirama Arumuga Nainare76c23d2019-06-03 10:56:35 -070062 if (init_profile_extras_once)
63 return 0;
64 init_profile_extras_once = 1;
65
Ray Essickb5d273d2020-01-09 11:51:27 -080066 // is this instance already registered?
67 if (chained_gcov_signal_handler != SIG_ERR) {
68 return -1;
69 }
Oliver Nguyena0d4f062019-12-09 16:36:08 -080070 sighandler_t ret1 = signal(COVERAGE_FLUSH_SIGNAL, gcov_signal_handler);
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070071 if (ret1 == SIG_ERR) {
72 return -1;
73 }
Ray Essickb5d273d2020-01-09 11:51:27 -080074 chained_gcov_signal_handler = ret1;
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070075
Pirama Arumuga Nainar0d252222018-05-22 15:40:49 -070076 return 0;
77}
78}