| 1532 | |
| 1533 | |
| 1534 | void DebuggerController::UpdateStackVariables() |
| 1535 | { |
| 1536 | if (!Settings::Instance()->Get<bool>("debugger.stackVariableAnnotations")) |
| 1537 | return; |
| 1538 | |
| 1539 | if (!m_liveView) |
| 1540 | return; |
| 1541 | std::vector<DebugThread> threads = GetAllThreads(); |
| 1542 | uint64_t frameAdjustment = 0; |
| 1543 | if (!m_liveView->GetDefaultArchitecture()) |
| 1544 | return; |
| 1545 | |
| 1546 | std::string archName = m_liveView->GetDefaultArchitecture()->GetName(); |
| 1547 | if ((archName == "x86") || (archName == "x86_64")) |
| 1548 | frameAdjustment = 8; |
| 1549 | |
| 1550 | m_oldAddresses = m_addressesWithVariable; |
| 1551 | m_addressesWithVariable.clear(); |
| 1552 | auto oldAddressWithComment = m_addressesWithComment; |
| 1553 | m_addressesWithComment.clear(); |
| 1554 | |
| 1555 | const DebugThread thread = GetActiveThread(); |
| 1556 | std::vector<DebugFrame> frames = GetFramesOfThread(thread.m_tid); |
| 1557 | if (frames.size() >= 2) |
| 1558 | { |
| 1559 | for (size_t i = 0; i < frames.size() - 1; i++) |
| 1560 | { |
| 1561 | const DebugFrame& frame = frames[i]; |
| 1562 | const DebugFrame& prevFrame = frames[i + 1]; |
| 1563 | // If there is no function at a stacktrace function start, add one |
| 1564 | auto functions = m_liveView->GetAnalysisFunctionsForAddress(frame.m_functionStart); |
| 1565 | if (functions.empty()) |
| 1566 | continue; |
| 1567 | |
| 1568 | FunctionRef func = functions[0]; |
| 1569 | |
| 1570 | auto vars = func->GetVariables(); |
| 1571 | // BN's variable storage offset is calculated against the entry status of the function, i.e., |
| 1572 | // before the current stack frame is created. Here we take the stack pointer of the previous stack frame, |
| 1573 | // and subtract the size of return address from it |
| 1574 | uint64_t framePointer = prevFrame.m_sp - frameAdjustment; |
| 1575 | for (const auto& [var, varNameAndType] : vars) |
| 1576 | { |
| 1577 | if (var.type != StackVariableSourceType) |
| 1578 | continue; |
| 1579 | |
| 1580 | uint64_t varAddress = framePointer + var.storage; |
| 1581 | ProcessOneVariable(varAddress, varNameAndType.type, varNameAndType.name); |
| 1582 | DefineVariablesRecursive(varAddress, varNameAndType.type); |
| 1583 | } |
| 1584 | } |
| 1585 | |
| 1586 | for (const DebugFrame& frame : frames) |
| 1587 | { |
| 1588 | // Annotate the stack pointer and the frame pointer, using the current stack frame |
| 1589 | m_liveView->SetCommentForAddress(frame.m_sp, fmt::format("Stack #{}\n====================", frame.m_index)); |
| 1590 | m_liveView->SetCommentForAddress(frame.m_fp, fmt::format("Frame #{}", frame.m_index)); |
| 1591 | m_addressesWithComment.insert(frame.m_sp); |