• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 <netinet/in.h>
18 #include <sys/socket.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 
22 #include <csignal>
23 #include <cstring>
24 #include <memory>
25 #include <string>
26 #include <thread>
27 
28 #include "stack_manager.h"
29 
30 // clang-format off
31 #include <client/linux/handler/exception_handler.h>
32 #include <backtrace/Backtrace.h>
33 #include <backtrace/backtrace_constants.h>
34 // clang-format on
35 
36 #include "common/init_flags.h"
37 #include "facade/grpc_root_server.h"
38 #include "hal/hci_hal_host.h"
39 #include "hal/snoop_logger.h"
40 #include "os/log.h"
41 #include "os/parameter_provider.h"
42 #include "os/system_properties.h"
43 
44 using ::bluetooth::ModuleList;
45 using ::bluetooth::StackManager;
46 using ::bluetooth::hal::HciHalHostRootcanalConfig;
47 using ::bluetooth::os::Thread;
48 
__asan_default_options()49 extern "C" const char* __asan_default_options() {
50   return "detect_container_overflow=0";
51 }
52 
53 namespace {
54 ::bluetooth::facade::GrpcRootServer grpc_root_server;
55 
56 struct sigaction old_act = {};
interrupt_handler(int signal_number)57 void interrupt_handler(int signal_number) {
58   LOG_INFO("Stopping gRPC root server due to signal: %s[%d]", strsignal(signal_number), signal_number);
59   grpc_root_server.StopServer();
60   if (old_act.sa_handler != nullptr) {
61     LOG_INFO("Calling saved signal handler");
62     old_act.sa_handler(signal_number);
63   }
64 }
65 struct sigaction new_act = {.sa_handler = interrupt_handler};
66 
crash_callback(const void * crash_context,size_t crash_context_size,void * context)67 bool crash_callback(const void* crash_context, size_t crash_context_size, void* context) {
68   pid_t tid = BACKTRACE_CURRENT_THREAD;
69   if (crash_context_size >= sizeof(google_breakpad::ExceptionHandler::CrashContext)) {
70     auto* ctx = static_cast<const google_breakpad::ExceptionHandler::CrashContext*>(crash_context);
71     tid = ctx->tid;
72     int signal_number = ctx->siginfo.si_signo;
73     LOG_ERROR("Process crashed, signal: %s[%d], tid: %d", strsignal(signal_number), signal_number, ctx->tid);
74   } else {
75     LOG_ERROR("Process crashed, signal: unknown, tid: unknown");
76   }
77   std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));
78   if (backtrace == nullptr) {
79     LOG_ERROR("Failed to create backtrace object");
80     return false;
81   }
82   if (!backtrace->Unwind(0)) {
83     LOG_ERROR("backtrace->Unwind failed");
84     return false;
85   }
86   LOG_ERROR("Backtrace:");
87   for (size_t i = 0; i < backtrace->NumFrames(); i++) {
88     LOG_ERROR("%s", backtrace->FormatFrameData(i).c_str());
89   }
90   return true;
91 }
92 
93 }  // namespace
94 
95 // The entry point for the binary with libbluetooth + facades
main(int argc,const char ** argv)96 int main(int argc, const char** argv) {
97   google_breakpad::MinidumpDescriptor descriptor(google_breakpad::MinidumpDescriptor::kMicrodumpOnConsole);
98   google_breakpad::ExceptionHandler eh(descriptor, nullptr, nullptr, nullptr, true, -1);
99   eh.set_crash_handler(crash_callback);
100 
101   int root_server_port = 8897;
102   int grpc_port = 8899;
103   int signal_port = 8895;
104 
105   bluetooth::common::InitFlags::SetAllForTesting();
106 
107   const std::string arg_grpc_root_server_port = "--root-server-port=";
108   const std::string arg_grpc_server_port = "--grpc-port=";
109   const std::string arg_rootcanal_port = "--rootcanal-port=";
110   const std::string arg_signal_port = "--signal-port=";
111   const std::string arg_btsnoop_path = "--btsnoop=";
112   const std::string arg_btsnooz_path = "--btsnooz=";
113   const std::string arg_btconfig_path = "--btconfig=";
114   for (int i = 1; i < argc; i++) {
115     std::string arg = argv[i];
116     if (arg.find(arg_grpc_root_server_port) == 0) {
117       auto port_number = arg.substr(arg_grpc_root_server_port.size());
118       root_server_port = std::stoi(port_number);
119     }
120     if (arg.find(arg_grpc_server_port) == 0) {
121       auto port_number = arg.substr(arg_grpc_server_port.size());
122       grpc_port = std::stoi(port_number);
123     }
124     if (arg.find(arg_rootcanal_port) == 0) {
125       auto port_number = arg.substr(arg_rootcanal_port.size());
126       HciHalHostRootcanalConfig::Get()->SetPort(std::stoi(port_number));
127     }
128     if (arg.find(arg_btsnoop_path) == 0) {
129       auto btsnoop_path = arg.substr(arg_btsnoop_path.size());
130       ::bluetooth::os::ParameterProvider::OverrideSnoopLogFilePath(btsnoop_path);
131       CHECK(::bluetooth::os::SetSystemProperty(
132           ::bluetooth::hal::SnoopLogger::kBtSnoopLogModeProperty, ::bluetooth::hal::SnoopLogger::kBtSnoopLogModeFull));
133     }
134     if (arg.find(arg_btsnooz_path) == 0) {
135       auto btsnooz_path = arg.substr(arg_btsnooz_path.size());
136       ::bluetooth::os::ParameterProvider::OverrideSnoozLogFilePath(btsnooz_path);
137     }
138     if (arg.find(arg_btconfig_path) == 0) {
139       auto btconfig_path = arg.substr(arg_btconfig_path.size());
140       ::bluetooth::os::ParameterProvider::OverrideConfigFilePath(btconfig_path);
141     }
142     if (arg.find(arg_signal_port) == 0) {
143       auto port_number = arg.substr(arg_signal_port.size());
144       signal_port = std::stoi(port_number);
145     }
146   }
147 
148   sigaction(SIGINT, &new_act, &old_act);
149   grpc_root_server.StartServer("0.0.0.0", root_server_port, grpc_port);
150   int tester_signal_socket = socket(AF_INET, SOCK_STREAM, 0);
151   struct sockaddr_in addr;
152   memset(&addr, 0, sizeof(addr));
153   addr.sin_family = AF_INET;
154   addr.sin_port = htons(signal_port);
155   addr.sin_addr.s_addr = htonl(INADDR_ANY);
156   connect(tester_signal_socket, (sockaddr*)&addr, sizeof(addr));
157   close(tester_signal_socket);
158   auto wait_thread = std::thread([] { grpc_root_server.RunGrpcLoop(); });
159   wait_thread.join();
160 
161   return 0;
162 }
163