1 //
2 // Copyright 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 // clang-format off
18 // This needs to be included before Backtrace.h to avoid a redefinition
19 // of DISALLOW_COPY_AND_ASSIGN
20 #include "log.h"
21 // clang-format on
22 
23 #include <client/linux/handler/exception_handler.h>
24 #include <gflags/gflags.h>
25 #include <unwindstack/AndroidUnwinder.h>
26 
27 #include <fstream>
28 #include <future>
29 #include <optional>
30 
31 #include "model/setup/async_manager.h"
32 #include "net/posix/posix_async_socket_connector.h"
33 #include "net/posix/posix_async_socket_server.h"
34 #include "test_environment.h"
35 
36 using ::android::net::PosixAsyncSocketConnector;
37 using ::android::net::PosixAsyncSocketServer;
38 using rootcanal::AsyncManager;
39 using rootcanal::TestEnvironment;
40 using namespace rootcanal;
41 
42 DEFINE_string(controller_properties_file, "", "deprecated");
43 DEFINE_string(configuration, "", "controller configuration (see config.proto)");
44 DEFINE_string(configuration_file, "",
45               "controller configuration file path (see config.proto)");
46 DEFINE_string(default_commands_file, "", "deprecated");
47 DEFINE_bool(enable_log_color, false, "enable log colors");
48 DEFINE_bool(enable_hci_sniffer, false, "enable hci sniffer");
49 DEFINE_bool(enable_baseband_sniffer, false, "enable baseband sniffer");
50 DEFINE_bool(enable_pcap_filter, false, "enable PCAP filter");
51 DEFINE_bool(disable_address_reuse, false,
52             "prevent rootcanal from reusing device addresses");
53 DEFINE_uint32(test_port, 6401, "test tcp port");
54 DEFINE_uint32(hci_port, 6402, "hci server tcp port");
55 DEFINE_uint32(link_port, 6403, "link server tcp port");
56 DEFINE_uint32(link_ble_port, 6404, "le link server tcp port");
57 
__asan_default_options()58 extern "C" const char* __asan_default_options() {
59   return "detect_container_overflow=0";
60 }
61 
crash_callback(const void * crash_context,size_t crash_context_size,void *)62 bool crash_callback(const void* crash_context, size_t crash_context_size,
63                     void* /* context */) {
64   std::optional<pid_t> tid;
65   if (crash_context_size >=
66       sizeof(google_breakpad::ExceptionHandler::CrashContext)) {
67     auto* ctx =
68         static_cast<const google_breakpad::ExceptionHandler::CrashContext*>(
69             crash_context);
70     tid = ctx->tid;
71     int signal_number = ctx->siginfo.si_signo;
72     ERROR("Process crashed, signal: {}[{}], tid: {}", strsignal(signal_number),
73           signal_number, ctx->tid);
74   } else {
75     ERROR("Process crashed, signal: unknown, tid: unknown");
76   }
77   unwindstack::AndroidLocalUnwinder unwinder;
78   unwindstack::AndroidUnwinderData data;
79   if (!unwinder.Unwind(tid, data)) {
80     ERROR("Unwind failed");
81     return false;
82   }
83   ERROR("Backtrace:");
84   for (const auto& frame : data.frames) {
85     ERROR("{}", unwinder.FormatFrame(frame));
86   }
87   return true;
88 }
89 
main(int argc,char ** argv)90 int main(int argc, char** argv) {
91   google_breakpad::MinidumpDescriptor descriptor(
92       google_breakpad::MinidumpDescriptor::kMicrodumpOnConsole);
93   google_breakpad::ExceptionHandler eh(descriptor, nullptr, nullptr, nullptr,
94                                        true, -1);
95   eh.set_crash_handler(crash_callback);
96 
97   gflags::ParseCommandLineFlags(&argc, &argv, true);
98   rootcanal::log::SetLogColorEnable(FLAGS_enable_log_color);
99 
100   INFO("starting rootcanal");
101 
102   if (FLAGS_test_port > UINT16_MAX) {
103     ERROR("test_port out of range: {}", FLAGS_test_port);
104     return -1;
105   }
106 
107   if (FLAGS_hci_port > UINT16_MAX) {
108     ERROR("hci_port out of range: {}", FLAGS_hci_port);
109     return -1;
110   }
111 
112   if (FLAGS_link_port > UINT16_MAX) {
113     ERROR("link_port out of range: {}", FLAGS_link_port);
114     return -1;
115   }
116 
117   if (FLAGS_link_ble_port > UINT16_MAX) {
118     ERROR("link_ble_port out of range: {}", FLAGS_link_ble_port);
119     return -1;
120   }
121 
122   std::string configuration_str;
123   if (!FLAGS_configuration.empty()) {
124     configuration_str = FLAGS_configuration;
125   } else if (!FLAGS_configuration_file.empty()) {
126     std::ifstream file(FLAGS_configuration_file);
127     std::stringstream buffer;
128     buffer << file.rdbuf();
129     configuration_str.assign(buffer.str());
130   }
131 
132   TestEnvironment root_canal(
133       [](AsyncManager* am, int port) {
134         return std::make_shared<PosixAsyncSocketServer>(port, am);
135       },
136       [](AsyncManager* am) {
137         return std::make_shared<PosixAsyncSocketConnector>(am);
138       },
139       static_cast<int>(FLAGS_test_port), static_cast<int>(FLAGS_hci_port),
140       static_cast<int>(FLAGS_link_port), static_cast<int>(FLAGS_link_ble_port),
141       configuration_str, FLAGS_enable_hci_sniffer,
142       FLAGS_enable_baseband_sniffer, FLAGS_enable_pcap_filter,
143       FLAGS_disable_address_reuse);
144 
145   std::promise<void> barrier;
146   std::future<void> barrier_future = barrier.get_future();
147   root_canal.initialize(std::move(barrier));
148   barrier_future.wait();
149   root_canal.close();
150   return 0;
151 }
152