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, "", "controller configuration file path (see config.proto)");
45 DEFINE_string(default_commands_file, "", "deprecated");
46 DEFINE_bool(enable_log_color, false, "enable log colors");
47 DEFINE_bool(enable_hci_sniffer, false, "enable hci sniffer");
48 DEFINE_bool(enable_baseband_sniffer, false, "enable baseband sniffer");
49 DEFINE_bool(enable_pcap_filter, false, "enable PCAP filter");
50 DEFINE_bool(disable_address_reuse, false, "prevent rootcanal from reusing device addresses");
51 DEFINE_uint32(test_port, 6401, "test tcp port");
52 DEFINE_uint32(hci_port, 6402, "hci server tcp port");
53 DEFINE_uint32(link_port, 6403, "link server tcp port");
54 DEFINE_uint32(link_ble_port, 6404, "le link server tcp port");
55
__asan_default_options()56 extern "C" const char* __asan_default_options() { return "detect_container_overflow=0"; }
57
crash_callback(const void * crash_context,size_t crash_context_size,void *)58 bool crash_callback(const void* crash_context, size_t crash_context_size, void* /* context */) {
59 std::optional<pid_t> tid;
60 if (crash_context_size >= sizeof(google_breakpad::ExceptionHandler::CrashContext)) {
61 auto* ctx = static_cast<const google_breakpad::ExceptionHandler::CrashContext*>(crash_context);
62 tid = ctx->tid;
63 int signal_number = ctx->siginfo.si_signo;
64 ERROR("Process crashed, signal: {}[{}], tid: {}", strsignal(signal_number), signal_number,
65 ctx->tid);
66 } else {
67 ERROR("Process crashed, signal: unknown, tid: unknown");
68 }
69 unwindstack::AndroidLocalUnwinder unwinder;
70 unwindstack::AndroidUnwinderData data;
71 if (!unwinder.Unwind(tid, data)) {
72 ERROR("Unwind failed");
73 return false;
74 }
75 ERROR("Backtrace:");
76 for (const auto& frame : data.frames) {
77 ERROR("{}", unwinder.FormatFrame(frame));
78 }
79 return true;
80 }
81
main(int argc,char ** argv)82 int main(int argc, char** argv) {
83 google_breakpad::MinidumpDescriptor descriptor(
84 google_breakpad::MinidumpDescriptor::kMicrodumpOnConsole);
85 google_breakpad::ExceptionHandler eh(descriptor, nullptr, nullptr, nullptr, true, -1);
86 eh.set_crash_handler(crash_callback);
87
88 gflags::ParseCommandLineFlags(&argc, &argv, true);
89 rootcanal::log::SetLogColorEnable(FLAGS_enable_log_color);
90
91 INFO("starting rootcanal");
92
93 if (FLAGS_test_port > UINT16_MAX) {
94 ERROR("test_port out of range: {}", FLAGS_test_port);
95 return -1;
96 }
97
98 if (FLAGS_hci_port > UINT16_MAX) {
99 ERROR("hci_port out of range: {}", FLAGS_hci_port);
100 return -1;
101 }
102
103 if (FLAGS_link_port > UINT16_MAX) {
104 ERROR("link_port out of range: {}", FLAGS_link_port);
105 return -1;
106 }
107
108 if (FLAGS_link_ble_port > UINT16_MAX) {
109 ERROR("link_ble_port out of range: {}", FLAGS_link_ble_port);
110 return -1;
111 }
112
113 std::string configuration_str;
114 if (!FLAGS_configuration.empty()) {
115 configuration_str = FLAGS_configuration;
116 } else if (!FLAGS_configuration_file.empty()) {
117 std::ifstream file(FLAGS_configuration_file);
118 std::stringstream buffer;
119 buffer << file.rdbuf();
120 configuration_str.assign(buffer.str());
121 }
122
123 TestEnvironment root_canal(
124 [](AsyncManager* am, int port) {
125 return std::make_shared<PosixAsyncSocketServer>(port, am);
126 },
127 [](AsyncManager* am) { return std::make_shared<PosixAsyncSocketConnector>(am); },
128 static_cast<int>(FLAGS_test_port), static_cast<int>(FLAGS_hci_port),
129 static_cast<int>(FLAGS_link_port), static_cast<int>(FLAGS_link_ble_port),
130 configuration_str, FLAGS_enable_hci_sniffer, FLAGS_enable_baseband_sniffer,
131 FLAGS_enable_pcap_filter, FLAGS_disable_address_reuse);
132
133 std::promise<void> barrier;
134 std::future<void> barrier_future = barrier.get_future();
135 root_canal.initialize(std::move(barrier));
136 barrier_future.wait();
137 root_canal.close();
138 return 0;
139 }
140