BacktraceModel.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "BacktraceModel.h"
  7. #include "Debugger.h"
  8. #include <LibDebug/StackFrameUtils.h>
  9. namespace HackStudio {
  10. NonnullRefPtr<BacktraceModel> BacktraceModel::create(Debug::ProcessInspector const& inspector, const PtraceRegisters& regs)
  11. {
  12. return adopt_ref(*new BacktraceModel(create_backtrace(inspector, regs)));
  13. }
  14. GUI::Variant BacktraceModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
  15. {
  16. if (role == GUI::ModelRole::Display) {
  17. auto& frame = m_frames.at(index.row());
  18. return frame.function_name;
  19. }
  20. return {};
  21. }
  22. GUI::ModelIndex BacktraceModel::index(int row, int column, const GUI::ModelIndex&) const
  23. {
  24. if (row < 0 || row >= static_cast<int>(m_frames.size()))
  25. return {};
  26. return create_index(row, column, &m_frames.at(row));
  27. }
  28. Vector<BacktraceModel::FrameInfo> BacktraceModel::create_backtrace(Debug::ProcessInspector const& inspector, PtraceRegisters const& regs)
  29. {
  30. FlatPtr current_ebp = regs.bp();
  31. FlatPtr current_instruction = regs.ip();
  32. Vector<BacktraceModel::FrameInfo> frames;
  33. do {
  34. auto lib = inspector.library_at(regs.ip());
  35. if (!lib)
  36. continue;
  37. String name = lib->debug_info->name_of_containing_function(current_instruction - lib->base_address);
  38. if (name.is_null()) {
  39. dbgln("BacktraceModel: couldn't find containing function for address: {:p}", current_instruction);
  40. name = "<missing>";
  41. }
  42. frames.append({ name, current_instruction, current_ebp });
  43. auto frame_info = Debug::StackFrameUtils::get_info(inspector, current_ebp);
  44. VERIFY(frame_info.has_value());
  45. current_instruction = frame_info.value().return_address;
  46. current_ebp = frame_info.value().next_ebp;
  47. } while (current_ebp && current_instruction);
  48. return frames;
  49. }
  50. }