xref: /aosp_15_r20/system/core/debuggerd/libdebuggerd/test/tombstone_proto_to_text_test.cpp (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1 /*
2  * Copyright (C) 2021 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 <gtest/gtest.h>
18 #include <sys/prctl.h>
19 
20 #include <string>
21 
22 #include <android-base/test_utils.h>
23 
24 #include "libdebuggerd/tombstone.h"
25 #include "libdebuggerd/tombstone_proto_to_text.h"
26 #include "tombstone.pb.h"
27 
28 using CallbackType = std::function<void(const std::string& line, bool should_log)>;
29 
30 class TombstoneProtoToTextTest : public ::testing::Test {
31  public:
SetUp()32   void SetUp() {
33     tombstone_.reset(new Tombstone);
34 
35     tombstone_->set_arch(Architecture::ARM64);
36     tombstone_->set_build_fingerprint("Test fingerprint");
37     tombstone_->set_timestamp("1970-01-01 00:00:00");
38     tombstone_->set_pid(100);
39     tombstone_->set_tid(100);
40     tombstone_->set_uid(0);
41     tombstone_->set_selinux_label("none");
42 
43     Signal signal;
44     signal.set_number(SIGSEGV);
45     signal.set_name("SIGSEGV");
46     signal.set_code(0);
47     signal.set_code_name("none");
48 
49     *tombstone_->mutable_signal_info() = signal;
50 
51     Thread thread;
52     thread.set_id(100);
53     thread.set_name("main");
54     thread.set_tagged_addr_ctrl(0);
55     thread.set_pac_enabled_keys(0);
56 
57     auto& threads = *tombstone_->mutable_threads();
58     threads[100] = thread;
59     main_thread_ = &threads[100];
60   }
61 
ProtoToString()62   void ProtoToString() {
63     text_ = "";
64     EXPECT_TRUE(tombstone_proto_to_text(
65         *tombstone_,
66         [this](const std::string& line, bool should_log) {
67           if (should_log) {
68             text_ += "LOG ";
69           }
70           text_ += line + '\n';
71         },
72         [&](const BacktraceFrame& frame) {
73           text_ += "SYMBOLIZE " + frame.build_id() + " " + std::to_string(frame.pc()) + "\n";
74         }));
75   }
76 
77   Thread* main_thread_;
78   std::string text_;
79   std::unique_ptr<Tombstone> tombstone_;
80 };
81 
TEST_F(TombstoneProtoToTextTest,tagged_addr_ctrl)82 TEST_F(TombstoneProtoToTextTest, tagged_addr_ctrl) {
83   main_thread_->set_tagged_addr_ctrl(0);
84   ProtoToString();
85   EXPECT_MATCH(text_, "LOG tagged_addr_ctrl: 0000000000000000\\n");
86 
87   main_thread_->set_tagged_addr_ctrl(PR_TAGGED_ADDR_ENABLE);
88   ProtoToString();
89   EXPECT_MATCH(text_, "LOG tagged_addr_ctrl: 0000000000000001 \\(PR_TAGGED_ADDR_ENABLE\\)\\n");
90 
91   main_thread_->set_tagged_addr_ctrl(PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC |
92                                      (0xfffe << PR_MTE_TAG_SHIFT));
93   ProtoToString();
94   EXPECT_MATCH(text_,
95                "LOG tagged_addr_ctrl: 000000000007fff3 \\(PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, "
96                "mask 0xfffe\\)\\n");
97 
98   main_thread_->set_tagged_addr_ctrl(0xf0000000 | PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC |
99                                      PR_MTE_TCF_ASYNC | (0xfffe << PR_MTE_TAG_SHIFT));
100   ProtoToString();
101   EXPECT_MATCH(text_,
102                "LOG tagged_addr_ctrl: 00000000f007fff7 \\(PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, "
103                "PR_MTE_TCF_ASYNC, mask 0xfffe, unknown 0xf0000000\\)\\n");
104 }
105 
TEST_F(TombstoneProtoToTextTest,pac_enabled_keys)106 TEST_F(TombstoneProtoToTextTest, pac_enabled_keys) {
107   main_thread_->set_pac_enabled_keys(0);
108   ProtoToString();
109   EXPECT_MATCH(text_, "LOG pac_enabled_keys: 0000000000000000\\n");
110 
111   main_thread_->set_pac_enabled_keys(PR_PAC_APIAKEY);
112   ProtoToString();
113   EXPECT_MATCH(text_, "LOG pac_enabled_keys: 0000000000000001 \\(PR_PAC_APIAKEY\\)\\n");
114 
115   main_thread_->set_pac_enabled_keys(PR_PAC_APIAKEY | PR_PAC_APDBKEY);
116   ProtoToString();
117   EXPECT_MATCH(text_,
118                "LOG pac_enabled_keys: 0000000000000009 \\(PR_PAC_APIAKEY, PR_PAC_APDBKEY\\)\\n");
119 
120   main_thread_->set_pac_enabled_keys(PR_PAC_APIAKEY | PR_PAC_APDBKEY | 0x1000);
121   ProtoToString();
122   EXPECT_MATCH(text_,
123                "LOG pac_enabled_keys: 0000000000001009 \\(PR_PAC_APIAKEY, PR_PAC_APDBKEY, unknown "
124                "0x1000\\)\\n");
125 }
126 
TEST_F(TombstoneProtoToTextTest,crash_detail_string)127 TEST_F(TombstoneProtoToTextTest, crash_detail_string) {
128   auto* crash_detail = tombstone_->add_crash_details();
129   crash_detail->set_name("CRASH_DETAIL_NAME");
130   crash_detail->set_data("crash_detail_value");
131   ProtoToString();
132   EXPECT_MATCH(text_, "(CRASH_DETAIL_NAME: 'crash_detail_value')");
133 }
134 
TEST_F(TombstoneProtoToTextTest,crash_detail_bytes)135 TEST_F(TombstoneProtoToTextTest, crash_detail_bytes) {
136   auto* crash_detail = tombstone_->add_crash_details();
137   crash_detail->set_name("CRASH_DETAIL_NAME");
138   crash_detail->set_data("helloworld\1\255\3");
139   ProtoToString();
140   EXPECT_MATCH(text_, R"(CRASH_DETAIL_NAME: 'helloworld\\1\\255\\3')");
141 }
142 
TEST_F(TombstoneProtoToTextTest,stack_record)143 TEST_F(TombstoneProtoToTextTest, stack_record) {
144   auto* cause = tombstone_->add_causes();
145   cause->set_human_readable("stack tag-mismatch on thread 123");
146   auto* stack = tombstone_->mutable_stack_history_buffer();
147   stack->set_tid(123);
148   {
149     auto* shb_entry = stack->add_entries();
150     shb_entry->set_fp(0x1);
151     shb_entry->set_tag(0xb);
152     auto* addr = shb_entry->mutable_addr();
153     addr->set_rel_pc(0x567);
154     addr->set_file_name("foo.so");
155     addr->set_build_id("ABC123");
156   }
157   {
158     auto* shb_entry = stack->add_entries();
159     shb_entry->set_fp(0x2);
160     shb_entry->set_tag(0xc);
161     auto* addr = shb_entry->mutable_addr();
162     addr->set_rel_pc(0x678);
163     addr->set_file_name("bar.so");
164   }
165   ProtoToString();
166   EXPECT_MATCH(text_, "stack tag-mismatch on thread 123");
167   EXPECT_MATCH(text_, "stack_record fp:0x1 tag:0xb pc:foo\\.so\\+0x567 \\(BuildId: ABC123\\)");
168   EXPECT_MATCH(text_, "stack_record fp:0x2 tag:0xc pc:bar\\.so\\+0x678");
169 }
170 
TEST_F(TombstoneProtoToTextTest,symbolize)171 TEST_F(TombstoneProtoToTextTest, symbolize) {
172   BacktraceFrame* frame = main_thread_->add_current_backtrace();
173   frame->set_pc(12345);
174   frame->set_build_id("0123456789abcdef");
175   ProtoToString();
176   EXPECT_MATCH(text_, "\\(BuildId: 0123456789abcdef\\)\\nSYMBOLIZE 0123456789abcdef 12345\\n");
177 }
178