1 /*
2  * Copyright (C) 2017 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 <fcntl.h>
18 #include <getopt.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 
22 #include "perfetto/base/logging.h"
23 #include "perfetto/base/unix_task_runner.h"
24 #include "perfetto/traced/traced.h"
25 
26 #include "src/ftrace_reader/ftrace_procfs.h"
27 #include "src/traced/probes/probes_producer.h"
28 #include "src/tracing/ipc/default_socket.h"
29 
30 namespace perfetto {
31 
32 int __attribute__((visibility("default"))) ProbesMain(int argc, char** argv) {
33   static struct option long_options[] = {
34       {"cleanup-after-crash", no_argument, nullptr, 'd'},
35       {nullptr, 0, nullptr, 0}};
36   int option_index;
37   int c;
38   while ((c = getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
39     switch (c) {
40       case 'd':
41         HardResetFtraceState();
42         return 0;
43       default:
44         PERFETTO_ELOG("Usage: %s [--cleanup-after-crash]", argv[0]);
45         return 1;
46     }
47   }
48 
49   // Set the watchdog to kill the process if we average more than 32MB of
50   // memory or 75% CPU over a 30 second window.
51   base::Watchdog* watchdog = base::Watchdog::GetInstance();
52   watchdog->SetCpuLimit(75, 30 * 1000);
53   watchdog->SetMemoryLimit(32 * 1024 * 1024, 30 * 1000);
54   watchdog->Start();
55 
56   PERFETTO_LOG("Starting %s service", argv[0]);
57 
58   // This environment variable is set by Android's init to a fd to /dev/kmsg
59   // opened for writing (see perfetto.rc). We cannot open the file directly
60   // due to permissions.
61   const char* env = getenv("ANDROID_FILE__dev_kmsg");
62   if (env) {
63     FtraceProcfs::g_kmesg_fd = atoi(env);
64     // The file descriptor passed by init doesn't have the FD_CLOEXEC bit set.
65     // Set it so we don't leak this fd while invoking atrace.
66     int res = fcntl(FtraceProcfs::g_kmesg_fd, F_SETFD, FD_CLOEXEC);
67     PERFETTO_DCHECK(res == 0);
68   }
69 
70   base::UnixTaskRunner task_runner;
71   ProbesProducer producer;
72   producer.ConnectWithRetries(GetProducerSocket(), &task_runner);
73   task_runner.Run();
74   return 0;
75 }
76 
77 }  // namespace perfetto
78