@@ -342,6 +342,9 @@ llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp,
342
342
object.try_emplace (" source" , CreateSource (*request_path));
343
343
344
344
if (bp_addr.IsValid ()) {
345
+ std::string formatted_addr =
346
+ " 0x" + llvm::utohexstr (bp_addr.GetLoadAddress (g_vsc.target ));
347
+ object.try_emplace (" instructionReference" , formatted_addr);
345
348
auto line_entry = bp_addr.GetLineEntry ();
346
349
const auto line = line_entry.GetLine ();
347
350
if (line != UINT32_MAX)
@@ -600,8 +603,8 @@ llvm::json::Value CreateSource(lldb::SBLineEntry &line_entry) {
600
603
if (name)
601
604
EmplaceSafeString (object, " name" , name);
602
605
char path[PATH_MAX] = " " ;
603
- file.GetPath (path, sizeof (path));
604
- if (path[ 0 ] ) {
606
+ if ( file.GetPath (path, sizeof (path)) &&
607
+ lldb::SBFileSpec::ResolvePath (path, path, PATH_MAX) ) {
605
608
EmplaceSafeString (object, " path" , std::string (path));
606
609
}
607
610
}
@@ -616,97 +619,14 @@ llvm::json::Value CreateSource(llvm::StringRef source_path) {
616
619
return llvm::json::Value (std::move (source));
617
620
}
618
621
619
- llvm::json::Value CreateSource (lldb::SBFrame &frame, int64_t &disasm_line) {
620
- disasm_line = 0 ;
622
+ std::optional<llvm::json::Value> CreateSource (lldb::SBFrame &frame) {
621
623
auto line_entry = frame.GetLineEntry ();
622
624
// A line entry of 0 indicates the line is compiler generated i.e. no source
623
- // file so don't return early with the line entry .
625
+ // file is associated with the frame .
624
626
if (line_entry.GetFileSpec ().IsValid () && line_entry.GetLine () != 0 )
625
627
return CreateSource (line_entry);
626
628
627
- llvm::json::Object object;
628
- const auto pc = frame.GetPC ();
629
-
630
- lldb::SBInstructionList insts;
631
- lldb::SBFunction function = frame.GetFunction ();
632
- lldb::addr_t low_pc = LLDB_INVALID_ADDRESS;
633
- if (function.IsValid ()) {
634
- low_pc = function.GetStartAddress ().GetLoadAddress (g_vsc.target );
635
- auto addr_srcref = g_vsc.addr_to_source_ref .find (low_pc);
636
- if (addr_srcref != g_vsc.addr_to_source_ref .end ()) {
637
- // We have this disassembly cached already, return the existing
638
- // sourceReference
639
- object.try_emplace (" sourceReference" , addr_srcref->second );
640
- disasm_line = g_vsc.GetLineForPC (addr_srcref->second , pc);
641
- } else {
642
- insts = function.GetInstructions (g_vsc.target );
643
- }
644
- } else {
645
- lldb::SBSymbol symbol = frame.GetSymbol ();
646
- if (symbol.IsValid ()) {
647
- low_pc = symbol.GetStartAddress ().GetLoadAddress (g_vsc.target );
648
- auto addr_srcref = g_vsc.addr_to_source_ref .find (low_pc);
649
- if (addr_srcref != g_vsc.addr_to_source_ref .end ()) {
650
- // We have this disassembly cached already, return the existing
651
- // sourceReference
652
- object.try_emplace (" sourceReference" , addr_srcref->second );
653
- disasm_line = g_vsc.GetLineForPC (addr_srcref->second , pc);
654
- } else {
655
- insts = symbol.GetInstructions (g_vsc.target );
656
- }
657
- }
658
- }
659
- const auto num_insts = insts.GetSize ();
660
- if (low_pc != LLDB_INVALID_ADDRESS && num_insts > 0 ) {
661
- if (line_entry.GetLine () == 0 ) {
662
- EmplaceSafeString (object, " name" , " <compiler-generated>" );
663
- } else {
664
- EmplaceSafeString (object, " name" , frame.GetDisplayFunctionName ());
665
- }
666
- SourceReference source;
667
- llvm::raw_string_ostream src_strm (source.content );
668
- std::string line;
669
- for (size_t i = 0 ; i < num_insts; ++i) {
670
- lldb::SBInstruction inst = insts.GetInstructionAtIndex (i);
671
- const auto inst_addr = inst.GetAddress ().GetLoadAddress (g_vsc.target );
672
- const char *m = inst.GetMnemonic (g_vsc.target );
673
- const char *o = inst.GetOperands (g_vsc.target );
674
- const char *c = inst.GetComment (g_vsc.target );
675
- if (pc == inst_addr)
676
- disasm_line = i + 1 ;
677
- const auto inst_offset = inst_addr - low_pc;
678
- int spaces = 0 ;
679
- if (inst_offset < 10 )
680
- spaces = 3 ;
681
- else if (inst_offset < 100 )
682
- spaces = 2 ;
683
- else if (inst_offset < 1000 )
684
- spaces = 1 ;
685
- line.clear ();
686
- llvm::raw_string_ostream line_strm (line);
687
- line_strm << llvm::formatv (" {0:X+}: <{1}> {2} {3,12} {4}" , inst_addr,
688
- inst_offset, llvm::fmt_repeat (' ' , spaces), m,
689
- o);
690
-
691
- // If there is a comment append it starting at column 60 or after one
692
- // space past the last char
693
- const uint32_t comment_row = std::max (line_strm.str ().size (), (size_t )60 );
694
- if (c && c[0 ]) {
695
- if (line.size () < comment_row)
696
- line_strm.indent (comment_row - line_strm.str ().size ());
697
- line_strm << " # " << c;
698
- }
699
- src_strm << line_strm.str () << " \n " ;
700
- source.addr_to_line [inst_addr] = i + 1 ;
701
- }
702
- // Flush the source stream
703
- src_strm.str ();
704
- auto sourceReference = VSCode::GetNextSourceReference ();
705
- g_vsc.source_map [sourceReference] = std::move (source);
706
- g_vsc.addr_to_source_ref [low_pc] = sourceReference;
707
- object.try_emplace (" sourceReference" , sourceReference);
708
- }
709
- return llvm::json::Value (std::move (object));
629
+ return {};
710
630
}
711
631
712
632
// "StackFrame": {
@@ -748,6 +668,12 @@ llvm::json::Value CreateSource(lldb::SBFrame &frame, int64_t &disasm_line) {
748
668
// "description": "An optional end column of the range covered by the
749
669
// stack frame."
750
670
// },
671
+ // "instructionPointerReference": {
672
+ // "type": "string",
673
+ // "description": "A memory reference for the current instruction
674
+ // pointer
675
+ // in this frame."
676
+ // },
751
677
// "moduleId": {
752
678
// "type": ["integer", "string"],
753
679
// "description": "The module associated with this frame, if any."
@@ -770,30 +696,37 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
770
696
int64_t frame_id = MakeVSCodeFrameID (frame);
771
697
object.try_emplace (" id" , frame_id);
772
698
773
- std::string frame_name;
774
- const char *func_name = frame.GetFunctionName ();
775
- if (func_name)
776
- frame_name = func_name;
777
- else
699
+ std::string frame_name = frame.GetDisplayFunctionName ();
700
+ if (frame_name.empty ())
778
701
frame_name = " <unknown>" ;
779
702
bool is_optimized = frame.GetFunction ().GetIsOptimized ();
780
703
if (is_optimized)
781
704
frame_name += " [opt]" ;
782
705
EmplaceSafeString (object, " name" , frame_name);
783
706
784
- int64_t disasm_line = 0 ;
785
- object.try_emplace (" source" , CreateSource (frame, disasm_line));
707
+ auto source = CreateSource (frame);
786
708
787
- auto line_entry = frame.GetLineEntry ();
788
- if (disasm_line > 0 ) {
789
- object.try_emplace (" line" , disasm_line);
790
- } else {
709
+ if (source) {
710
+ object.try_emplace (" source" , *source);
711
+ auto line_entry = frame.GetLineEntry ();
791
712
auto line = line_entry.GetLine ();
792
- if (line == UINT32_MAX)
793
- line = 0 ;
794
- object.try_emplace (" line" , line);
713
+ if (line && line != LLDB_INVALID_LINE_NUMBER)
714
+ object.try_emplace (" line" , line);
715
+ auto column = line_entry.GetColumn ();
716
+ if (column && column != LLDB_INVALID_COLUMN_NUMBER)
717
+ object.try_emplace (" column" , column);
718
+ } else {
719
+ object.try_emplace (" line" , 0 );
720
+ object.try_emplace (" column" , 0 );
721
+ object.try_emplace (" presentationHint" , " subtle" );
722
+ }
723
+
724
+ const auto pc = frame.GetPC ();
725
+ if (pc != LLDB_INVALID_ADDRESS) {
726
+ std::string formatted_addr = " 0x" + llvm::utohexstr (pc);
727
+ object.try_emplace (" instructionPointerReference" , formatted_addr);
795
728
}
796
- object. try_emplace ( " column " , line_entry. GetColumn ());
729
+
797
730
return llvm::json::Value (std::move (object));
798
731
}
799
732
0 commit comments