return true;
}
+bool Backtrace::UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
+ const backtrace_stackinfo_t& stack,
+ std::vector<backtrace_frame_data_t>* frames,
+ BacktraceUnwindError* error) {
+ UnwindStackOfflineMap* offline_map = reinterpret_cast<UnwindStackOfflineMap*>(back_map);
+ // Create the process memory from the stack data since this will almost
+ // always be different each unwind.
+ if (!offline_map->CreateProcessMemory(stack)) {
+ if (error != nullptr) {
+ error->error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED;
+ }
+ return false;
+ }
+ return Backtrace::Unwind(regs, back_map, frames, 0U, nullptr, error);
+}
+
UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map)
: BacktraceCurrent(pid, tid, map) {}
Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid,
const std::vector<backtrace_map_t>& maps,
const backtrace_stackinfo_t& stack) {
- BacktraceMap* map = BacktraceMap::CreateOffline(pid, maps, stack);
- if (map == nullptr) {
+ std::unique_ptr<UnwindStackOfflineMap> map(
+ reinterpret_cast<UnwindStackOfflineMap*>(BacktraceMap::CreateOffline(pid, maps)));
+ if (map.get() == nullptr || !map->CreateProcessMemory(stack)) {
return nullptr;
}
-
- return new UnwindStackOffline(arch, pid, tid, map, false);
+ return new UnwindStackOffline(arch, pid, tid, map.release(), false);
}
Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid, BacktraceMap* map) {
return false;
}
-bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps,
- const backtrace_stackinfo_t& stack) {
- if (stack.start >= stack.end) {
- return false;
- }
-
+bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps) {
for (const backtrace_map_t& map : backtrace_maps) {
maps_.push_back(map);
}
for (const backtrace_map_t& map : maps_) {
maps->Add(map.start, map.end, map.offset, map.flags, map.name, map.load_bias);
}
+ return true;
+}
+
+bool UnwindStackOfflineMap::CreateProcessMemory(const backtrace_stackinfo_t& stack) {
+ if (stack.start >= stack.end) {
+ return false;
+ }
// Create the process memory from the stack data.
uint64_t size = stack.end - stack.start;
std::shared_ptr<unwindstack::Memory> shared_memory(memory);
process_memory_.reset(new unwindstack::MemoryRange(shared_memory, 0, size, stack.start));
-
return true;
}
//-------------------------------------------------------------------------
// BacktraceMap create offline function.
//-------------------------------------------------------------------------
-BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
- const backtrace_stackinfo_t& stack) {
+BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps) {
UnwindStackOfflineMap* map = new UnwindStackOfflineMap(pid);
- if (!map->Build(maps, stack)) {
+ if (!map->Build(maps)) {
delete map;
return nullptr;
}
bool Build() override;
- bool Build(const std::vector<backtrace_map_t>& maps, const backtrace_stackinfo_t& stack);
+ bool Build(const std::vector<backtrace_map_t>& maps);
+
+ bool CreateProcessMemory(const backtrace_stackinfo_t& stack);
};
#endif // _LIBBACKTRACE_UNWINDSTACK_MAP_H
std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames,
std::vector<std::string>* skip_names, BacktraceUnwindError* error = nullptr);
+ static bool UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
+ const backtrace_stackinfo_t& stack_info,
+ std::vector<backtrace_frame_data_t>* frames,
+ BacktraceUnwindError* error = nullptr);
+
// Get the function name and offset into the function given the pc.
// If the string is empty, then no valid function name was found,
// or the pc is not in any valid map.
// is unsupported.
static BacktraceMap* Create(pid_t pid, bool uncached = false);
- static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
- const backtrace_stackinfo_t& stack);
+ static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps);
virtual ~BacktraceMap();