6

I have a Visual Studio extension that hooks into debugging events. When the debugger stops at a line of code, my IDebugEventCallback2 callback gets called, and I can find out the filename and line number where the debugger has stopped via IDebugThread2::EnumFrameInfo.

I'd like to know the range of source code lines that the current function spans.

I'm hoping it's possible to derive the information I need from the debugger interfaces - the debugger must know the line range of functions. If that's not possible, I'm open to any other methods. In an ideal world the solution would work without the project system - many people, myself included, use Visual Studio as a stand-alone debugger without using the project system. (Also, I can't rely on Roslyn - it needs to work in existing versions of Visual Studio.)

Edit: Carlos's method of using FileCodeModel works well, as long as the file is part of a project. I'd still love to know whether there's a method that doesn't require the project system.

RichieHindle
  • 244,085
  • 44
  • 340
  • 385

1 Answers1

0

Given a FRAMEINFO retrieved with IEnumDebugFrameInfo2.Next, you can use the following code to get the file name, the first line of code of the current frame and the current line of code:

IDebugStackFrame2 stackFrame = frmInfo.m_pFrame;
if (stackFrame != null)
{
   TEXT_POSITION[] begin = new TEXT_POSITION[1];
   TEXT_POSITION[] end = new TEXT_POSITION[1];
   IDebugDocumentContext2 debugDocumentContext2;
   stackFrame.GetDocumentContext(out debugDocumentContext2);
   if (debugDocumentContext2 != null)
   {
      string fileName;
      debugDocumentContext2.GetName((uint)enum_GETNAME_TYPE.GN_FILENAME, out fileName);
      debugDocumentContext2.GetSourceRange(begin, end);
   }
}

FWIW, the IDebugDocumentContext2 interface has a Seek method that allows you to advance lines or statements of code in the stack frame. I guess you can advance until failure to get the end line of code of the stack frame.

To get info about code elements and start/end points using the project system (and without Roslyn) you have to use the automation model (EnvDTE.ProjectItem.FileCodeModel). Given a EnvDTE.ProjectItem and a line of code, you can use for example: HOWTO: Get the code element at the cursor from a Visual Studio .NET macro or add-in

Carlos Quintero
  • 4,115
  • 1
  • 8
  • 17
  • Thanks, but that doesn't quite work for me. `GetSourceRange()` returns the range of the current statement, not the whole frame, and `Seek()` returns 0x80004001 "Not implemented" from the C++ debugger. (Not my downvote, BTW.) (And thanks for the pointer to your excellent CodeModel article, which I'd already looked at. :-) ) – RichieHindle Jun 19 '15 at 07:58