BacktraceModel.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "BacktraceModel.h"
  27. #include "Debugger.h"
  28. #include <LibDebug/StackFrameUtils.h>
  29. namespace HackStudio {
  30. NonnullRefPtr<BacktraceModel> BacktraceModel::create(const Debug::DebugSession& debug_session, const PtraceRegisters& regs)
  31. {
  32. return adopt(*new BacktraceModel(create_backtrace(debug_session, regs)));
  33. }
  34. GUI::Variant BacktraceModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
  35. {
  36. if (role == GUI::ModelRole::Display) {
  37. auto& frame = m_frames.at(index.row());
  38. return frame.function_name;
  39. }
  40. return {};
  41. }
  42. GUI::ModelIndex BacktraceModel::index(int row, int column, const GUI::ModelIndex&) const
  43. {
  44. if (row < 0 || row >= static_cast<int>(m_frames.size()))
  45. return {};
  46. return create_index(row, column, &m_frames.at(row));
  47. }
  48. Vector<BacktraceModel::FrameInfo> BacktraceModel::create_backtrace(const Debug::DebugSession& debug_session, const PtraceRegisters& regs)
  49. {
  50. u32 current_ebp = regs.ebp;
  51. u32 current_instruction = regs.eip;
  52. Vector<BacktraceModel::FrameInfo> frames;
  53. do {
  54. String name = debug_session.debug_info().name_of_containing_function(current_instruction);
  55. if (name.is_null()) {
  56. dbg() << "BacktraceModel: couldn't find containing function for address: " << (void*)current_instruction;
  57. name = "<missing>";
  58. }
  59. frames.append({ name, current_instruction, current_ebp });
  60. auto frame_info = Debug::StackFrameUtils::get_info(*Debugger::the().session(), current_ebp);
  61. ASSERT(frame_info.has_value());
  62. current_instruction = frame_info.value().return_address;
  63. current_ebp = frame_info.value().next_ebp;
  64. } while (current_ebp && current_instruction);
  65. return frames;
  66. }
  67. }