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