2012-01-19 34 views
6

Có thể tự động trả về từ một hàm bằng cách sử dụng Breakpoint/Tracepoint không?
Tôi không muốn kéo điểm thực thi hoặc đặt nó bằng CTRL + SHIFT + F10 mỗi khi điểm ngắt được nhấn.
Tôi đã thử "in" các "thông báo" sau đây khi nhấn, nhưng các lần thực hiện tiếp tục mà không thay đổi.Trả về từ một hàm bằng cách sử dụng điểm ngắt

{return;} 
{return null;} 

Lưu ý rằng tôi cần phải trả lại từ hàm mà không thực sự thay đổi mã.

Để làm rõ Tracepoint là gì: "Tracepoint là điểm ngắt với hành động tùy chỉnh được liên kết với nó. Khi một tracepoint được nhấn, trình gỡ lỗi thực hiện hành động tracepoint được chỉ định thay vì, hoặc ngoài việc phá vỡ thực thi chương trình . " Từ MSDN.

Nếu bạn không biết ý tôi là gì với "in thư", bạn có thể muốn đọc this AltDevBlogADay post về Tracepoints. Tốt lắm.

Trả lời

3

Được rồi, sau một chút đào xung quanh bạn có thể làm điều này - nhưng nó sẽ không hoạt động trong mọi trường hợp.

Cẩn thận, điều này sử dụng macro và không thể được đảm bảo để làm việc với đại biểu nội tuyến; hoặc với các phương thức thực sự cần trả lại một cái gì đó. Nó tự động hóa quá trình được mô tả bởi @juergen d và @Erno khi một điểm ngắt được nhấn; bằng cách sử dụng heuristics rất đơn giản để tìm nơi kết thúc của hàm hiện tại.

Trước tiên, bạn cần phải thêm macro này vào môi trường macro của mình (mở bằng ALT + F11 trong VS). Mã này có lẽ là không tốt như nó có thể là như tôi vừa vội vã nó ra :)

Sub ExitStack() 
    'get the last-hit breakpoint 
    Dim breakPoint As EnvDTE.Breakpoint 
    breakPoint = DTE.Debugger.BreakpointLastHit() 
    'if the currently open file is the same as where the breakpoint is set 
    '(could search and open it, but the debugger *should* already have done that) 
    If (DTE.ActiveDocument.FullName = breakPoint.File) Then 

     Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection 
     Dim editPoint As EnvDTE.EditPoint 
     'move the cursor to where the breakpoint is actually defined 
     selection.MoveToLineAndOffset(breakPoint.FileLine, breakPoint.FileColumn) 

     Dim codeElement As EnvDTE.CodeElement 
     codeElement = DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElementFromPoint(selection.ActivePoint, vsCMElement.vsCMElementFunction) 
     'if a function is found, move the cursor to the last character of it 
     If Not (codeElement Is Nothing) Then 
      Dim lastLine As EnvDTE.TextPoint 

      lastLine = codeElement.GetEndPoint() 
      selection.MoveToPoint(lastLine) 
      selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText) 
      'execute the SetNextStatement command. 
      'Has to be done via ExecuteCommand 
      DTE.ExecuteCommand("Debug.SetNextStatement") 
     End If 
    End If 
End Sub 

Với điều đó tại chỗ, bây giờ bạn có thể đặt breakpoint của bạn - click chuột phải vào nó và nhấn tùy chọn trình đơn When hit... (điều này chỉ hoạt động trong VS2010 tôi tin). ScottGu mô tả điều này trong this bài đăng trên blog.

Từ hộp thoại, tìm ExitStack macro mà bạn vừa dán vào.

Run mã với trình gỡ lỗi kèm theo và khi breakpoint là hit phần còn lại của mã của chức năng nên được bỏ qua. Điều này nên tuân thủ các thủ thuật trình gỡ rối khác - như điều kiện, v.v.

Lưu ý - Tôi đã sử dụng this SO để giải quyết vấn đề tôi đang gặp phải; ban đầu tôi đã gọi phương thức SetNextStatement của trình gỡ rối trực tiếp và nó không hoạt động

Tôi không biết các phương thức sẽ trả về sẽ hoạt động như thế nào - theo lý thuyết chúng phải trả lại bất kỳ giá trị trả về nào tại thời điểm đó, nhưng trong một số trường hợp thực tế là điều này chỉ đơn giản là sẽ không hoạt động!

Tương tự nếu điểm ngắt nằm trong khối try/catch thì nó sẽ không hoạt động - vì try/catch phải được thoát ra trước khi bạn có thể đặt câu lệnh tiếp theo ở đâu đó bên ngoài nó.

+0

Khá tuyệt. Tôi vẫn hy vọng một người nào đó có câu trả lời không vĩ mô, có giá trị, nhưng đây là câu trả lời hay nhất cho đến nay. –

+0

@Protectorone không có một - trừ khi bạn viết trình gỡ rối của riêng bạn. Nếu phương thức trả về biến cục bộ, bạn có thể sử dụng đồng hồ (hoặc thậm chí sử dụng macro khác) để đặt địa phương trước khi sử dụng biến này để trả về. –

7

Trong Visual Studio, bạn chỉ cần kéo mũi tên, cho biết dòng mã hiện tại trong khi gỡ lỗi, đến cuối hàm.

+4

+1, hoặc nhấp chuột phải một câu lệnh return trong hàm, hoặc nẹp xoăn và chọn 'thiết lập tuyên bố tiếp theo'. Mặc dù có giá trị chỉ ra rằng nó chỉ hoạt động khi chỉ mã ở một nơi khác trong ngăn xếp hiện tại; và tôi nghĩ rằng các khối try/catch không thể có hiệu lực. –

+0

Tôi muốn nó tự động. Tôi không muốn kéo điểm thực thi mỗi khi điểm ngắt truy cập. –

+0

Sau đó xem xét lệnh 'goto' như sau:' if (your_breakpoint_condition) goto end_marker; ' –

3

Hai lựa chọn:

  1. Nếu bạn muốn các chức năng để hoàn thành thi công và phá vỡ sau khi trở về người gọi. Bấm "Step Out" (Shift-F11)
  2. Nếu bạn muốn bỏ qua việc thực hiện một số dòng, hãy kéo điểm đánh dấu màu vàng đến dòng tiếp theo bạn muốn thực hiện. Hãy nhớ rằng, việc kéo điểm đánh dấu đến một vị trí có thể gây ra một lệnh thực thi mà không bao giờ có thể xảy ra khi chạy mà không can thiệp để kết quả có thể hoàn toàn sai.
1

Có, bạn có thể thực hiện việc này trực tiếp bằng cách sử dụng tracepoint.

  1. Tìm địa chỉ của câu lệnh trả về ở cuối hàm bằng cách bẻ khóa một lần và sau đó nhìn vào thanh ghi EIP trong cửa sổ Đăng ký hoặc thêm Đồng hồ cho "@eip".
  2. Thêm điểm truy cập vào dòng bạn muốn chuyển. Hãy nhớ rằng nhảy sẽ xảy ra trước khi bất cứ điều gì trên dòng được thực thi. Nội dung của tracepoint phải là {@eip = address} sử dụng địa chỉ từ bước 1.
  3. Lợi nhuận!

Xem thêm https://stackoverflow.com/a/14695736/301729

+0

Giả sử hàm _has_ một câu lệnh trả về… –

+0

@Protectorone Thực ra bạn thậm chí không cần một câu lệnh trả về. Bạn sẽ có thể phá vỡ trên đóng ngoặc nhọn cuối cùng và sử dụng địa chỉ đó. –

Các vấn đề liên quan