1 /*
2  * Copyright (C) 2022 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 <unistd.h>
18 
19 #include <thread>
20 
21 #include <android-base/threads.h>
22 #include <gtest/gtest.h>
23 #include <utils/CallStack.h>
24 
CurrentCaller(android::String8 & backtrace)25 __attribute__((__noinline__)) extern "C" void CurrentCaller(android::String8& backtrace) {
26     android::CallStack cs;
27     cs.update();
28     backtrace = cs.toString();
29 }
30 
TEST(CallStackTest,current_backtrace)31 TEST(CallStackTest, current_backtrace) {
32     android::String8 backtrace;
33     CurrentCaller(backtrace);
34 
35     ASSERT_NE(-1, backtrace.find("(CurrentCaller")) << "Full backtrace:\n" << backtrace;
36 }
37 
ThreadBusyWait(std::atomic<pid_t> * tid,volatile bool * done)38 __attribute__((__noinline__)) extern "C" void ThreadBusyWait(std::atomic<pid_t>* tid,
39                                                              volatile bool* done) {
40     *tid = android::base::GetThreadId();
41     while (!*done) {
42     }
43 }
44 
TEST(CallStackTest,thread_backtrace)45 TEST(CallStackTest, thread_backtrace) {
46     // Use a volatile to avoid any problems unwinding since sometimes
47     // accessing a std::atomic does not include unwind data at every
48     // instruction and leads to failed unwinds.
49     volatile bool done = false;
50     std::atomic<pid_t> tid = -1;
51     std::thread thread([&tid, &done]() { ThreadBusyWait(&tid, &done); });
52 
53     while (tid == -1) {
54     }
55 
56     android::CallStack cs;
57     cs.update(0, tid);
58 
59     done = true;
60     thread.join();
61 
62     ASSERT_NE(-1, cs.toString().find("(ThreadBusyWait")) << "Full backtrace:\n" << cs.toString();
63 }
64