blob: 9eb9e8ff5983fb10b1e84e42503867defbc5ca7b [file] [log] [blame]
Yabin Cui03381452017-12-13 11:31:53 -08001/*
2 * Copyright (C) 2015 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#ifndef SIMPLE_PERF_OFFLINE_UNWINDER_H_
18#define SIMPLE_PERF_OFFLINE_UNWINDER_H_
19
Christopher Ferris15933b62018-02-22 19:06:42 -080020#include <memory>
Yabin Cui03381452017-12-13 11:31:53 -080021#include <vector>
22
23#include "perf_regs.h"
Yabin Cuia6a04202018-07-23 15:32:47 -070024#include "thread_tree.h"
Yabin Cui03381452017-12-13 11:31:53 -080025
26namespace simpleperf {
27struct ThreadEntry;
28
Yabin Cuie0a19802021-03-16 17:24:11 -070029enum UnwindStackErrorCode : uint8_t {
30 ERROR_NONE, // No error.
31 ERROR_MEMORY_INVALID, // Memory read failed.
32 ERROR_UNWIND_INFO, // Unable to use unwind information to unwind.
33 ERROR_UNSUPPORTED, // Encountered unsupported feature.
34 ERROR_INVALID_MAP, // Unwind in an invalid map.
35 ERROR_MAX_FRAMES_EXCEEDED, // The number of frames exceed the total allowed.
36 ERROR_REPEATED_FRAME, // The last frame has the same pc/sp as the next.
37 ERROR_INVALID_ELF, // Unwind in an invalid elf.
38 ERROR_THREAD_DOES_NOT_EXIST, // Attempt to unwind a local thread that does
39 // not exist.
40 ERROR_THREAD_TIMEOUT, // Timeout trying to unwind a local thread.
41 ERROR_SYSTEM_CALL, // System call failed while unwinding.
Christopher Ferrise617e492022-04-19 20:06:25 -070042 ERROR_BAD_ARCH, // Arch invalid (none, or mismatched).
43 ERROR_MAPS_PARSE, // Failed to parse maps data.
44 ERROR_INVALID_PARAMETER, // Invalid parameter passed to function.
45 ERROR_MAX = ERROR_INVALID_PARAMETER,
Yabin Cuie0a19802021-03-16 17:24:11 -070046};
47
Yabin Cui03381452017-12-13 11:31:53 -080048struct UnwindingResult {
49 // time used for unwinding, in ns.
50 uint64_t used_time;
Yabin Cui0272f022021-02-24 15:11:57 -080051 // unwindstack::LastErrorCode()
52 uint64_t error_code;
53 // unwindstack::LastErrorAddress()
54 uint64_t error_addr;
Yabin Cui85faad92018-01-04 17:17:55 -080055 uint64_t stack_start;
56 uint64_t stack_end;
Yabin Cui03381452017-12-13 11:31:53 -080057};
58
59class OfflineUnwinder {
60 public:
Yabin Cui91784fd2020-01-29 17:08:49 -080061 static constexpr const char* META_KEY_ARM64_PAC_MASK = "arm64_pac_mask";
62
Yabin Cui5ac7a252019-07-18 10:43:32 -070063 static std::unique_ptr<OfflineUnwinder> Create(bool collect_stat);
64 virtual ~OfflineUnwinder() {}
Yabin Cui03381452017-12-13 11:31:53 -080065
Yabin Cui5ac7a252019-07-18 10:43:32 -070066 virtual bool UnwindCallChain(const ThreadEntry& thread, const RegSet& regs, const char* stack,
67 size_t stack_size, std::vector<uint64_t>* ips,
68 std::vector<uint64_t>* sps) = 0;
Yabin Cui03381452017-12-13 11:31:53 -080069
ThiƩbaud Weksteen4848ee02020-10-23 16:06:59 +020070 const UnwindingResult& GetUnwindingResult() const { return unwinding_result_; }
Yabin Cui03381452017-12-13 11:31:53 -080071
Yabin Cui5d5c01a2018-08-27 10:30:20 -070072 bool IsCallChainBrokenForIncompleteJITDebugInfo() {
73 return is_callchain_broken_for_incomplete_jit_debug_info_;
74 }
75
Yabin Cui91784fd2020-01-29 17:08:49 -080076 static void CollectMetaInfo(std::unordered_map<std::string, std::string>* info_map);
77 virtual void LoadMetaInfo(const std::unordered_map<std::string, std::string>&) {}
78
Yabin Cui5ac7a252019-07-18 10:43:32 -070079 protected:
80 OfflineUnwinder() {}
81
Yabin Cui03381452017-12-13 11:31:53 -080082 UnwindingResult unwinding_result_;
Yabin Cui5ac7a252019-07-18 10:43:32 -070083 bool is_callchain_broken_for_incomplete_jit_debug_info_ = false;
Yabin Cui03381452017-12-13 11:31:53 -080084};
85
ThiƩbaud Weksteen4848ee02020-10-23 16:06:59 +020086} // namespace simpleperf
Yabin Cui03381452017-12-13 11:31:53 -080087
88#endif // SIMPLE_PERF_OFFLINE_UNWINDER_H_