1/** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <unistd.h> 17#include <csignal> 18#include <sys/prctl.h> 19#include <gtest/gtest.h> 20 21#if !defined(TIMEOUT_SIGNAL) 22#error "TIMEOUT_SIGNAL is not defined" 23#endif 24#if !defined(GDB_PATH) 25#error "GDB_PATH is not defined" 26#else 27#define XSTR(x) STR(x) 28#define STR(x) #x 29#define GDB_PATH_STR XSTR(GDB_PATH) 30#endif 31 32namespace panda { 33void HandleTimeout(int sig) 34{ 35 if (sig != TIMEOUT_SIGNAL) { 36 return; 37 } 38 39 // Allow to attach gdb. 40 // Do it before fork because the child can attach gdb before 41 // the parent allows it. 42 prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); 43 pid_t pid = fork(); 44 if (pid != 0) { 45 // Parent 46 raise(SIGSTOP); // wait for child's gdb invocation to pick us up 47 } else { 48 // Child 49 std::stringstream out; 50 out << getppid(); 51 std::string ppid_str = out.str(); 52 execlp(GDB_PATH_STR, "-q", "--batch", 53 "-p", ppid_str.c_str(), 54 "-ex", "info threads", 55 "-ex", "thread apply all bt", 56 "-ex", "kill", nullptr); 57 } 58} 59 60int main(int argc, char *argv[]) 61{ 62 signal(TIMEOUT_SIGNAL, HandleTimeout); 63 testing::InitGoogleTest(&argc, argv); 64 return RUN_ALL_TESTS(); 65} 66} // namespace panda 67