| 581 | } |
| 582 | |
| 583 | private void HandleStackTraceRequest(DAPRequest request, DAPStackFramesRequest msg) |
| 584 | { |
| 585 | var state = GetThread(msg.threadId); |
| 586 | |
| 587 | if (!state.Stopped) |
| 588 | { |
| 589 | throw new RequestFailedException("Cannot get stack when thread is not stopped"); |
| 590 | } |
| 591 | |
| 592 | int startFrame = msg.startFrame == null ? 0 : (int)msg.startFrame; |
| 593 | int levels = (msg.levels == null || msg.levels == 0) ? state.Stack.Count : (int)msg.levels; |
| 594 | int lastFrame = Math.Min(startFrame + levels, state.Stack.Count); |
| 595 | |
| 596 | // Count total sendable frames |
| 597 | int numFrames = 0; |
| 598 | foreach (var frame in state.Stack) |
| 599 | { |
| 600 | if (!Config.omitCppFrames || frame.Path != null) |
| 601 | { |
| 602 | numFrames++; |
| 603 | } |
| 604 | } |
| 605 | |
| 606 | var frames = new List<DAPStackFrame>(); |
| 607 | for (var i = startFrame; i < lastFrame; i++) |
| 608 | { |
| 609 | var frame = state.Stack[i]; |
| 610 | if (Config.omitCppFrames && frame.Path == null) |
| 611 | { |
| 612 | continue; |
| 613 | } |
| 614 | |
| 615 | var dapFrame = new DAPStackFrame(); |
| 616 | dapFrame.id = (msg.threadId << 16) | i; |
| 617 | // TODO DAPStackFrameFormat for name formatting |
| 618 | dapFrame.name = frame.Function; |
| 619 | if (frame.Path != null || frame.Source != null) |
| 620 | { |
| 621 | dapFrame.source = new DAPSource |
| 622 | { |
| 623 | name = frame.Source, |
| 624 | path = frame.Path?.Replace("/", "\\") ?? frame.Source |
| 625 | }; |
| 626 | dapFrame.line = frame.Line; |
| 627 | dapFrame.column = (frame.Line > 0) ? 1 : 0; |
| 628 | } |
| 629 | |
| 630 | // TODO presentationHint |
| 631 | frames.Add(dapFrame); |
| 632 | } |
| 633 | |
| 634 | var reply = new DAPStackFramesResponse |
| 635 | { |
| 636 | stackFrames = frames, |
| 637 | totalFrames = numFrames |
| 638 | }; |
| 639 | Stream.SendReply(request, reply); |
| 640 | } |