2009-01-16 41 views
14

Tôi thường vô tình bước vào mã mà tôi không quan tâm trong khi gỡ lỗi trong Delphi.Trong Delphi: Làm thế nào để bỏ qua các phần của mã trong khi gỡ lỗi?

Hãy bắt đầu bằng cách nói rằng tôi biết rằng bạn có thể bước qua với F8 và bạn có thể chạy đến một dòng nhất định với f4.

Ví dụ:

function TMyClass.DoStuff():Integer; 
begin 
    // do some stuff 
    bla(); 
end; 

procedure TMyClass.Foo() 
begin 
    if DoStuff()=0 then // press F7 when entering this line 
    beep; 
end; 

Ví dụ: Tôi muốn bước vào phương pháp DoStuff() bằng cách nhấn F7, nhưng thay vì đến đó, đầu tiên tôi kết thúc trong FastMM4.FastGetMem(), mà là một blob lớn của mã assembly mà rõ ràng là tôi không quan tâm vào lúc này.

Có một số cách để đi về việc này, và tôi không thích ai trong số họ:

  • Thêm một breakpoint trên "bla" (gần như vô dụng nếu bạn chỉ muốn bước vào DoStuff vào những dịp đặc biệt, như lặp lại 23498938);

  • Thay vì nhấn F7, di chuyển con trỏ sang "bla" và nhấn F4 (Hoạt động cho ví dụ đơn giản này. Trong thực tế, nó không);

  • Trong trường hợp FastMM: tạm thời tắt fastmm;

Có cách nào để gợi ý IDE rằng tôi không bao giờ quan tâm vào bước vào một khối nhất định mã, hoặc sao tôi luôn phải đặt breakpoint thêm hoặc sử dụng F4 để cố gắng tránh điều này?

Tôi hy vọng một số chỉ thị trình biên dịch ma thuật như {$ NODEBUG BEGIN/END} hoặc một cái gì đó tương tự.

Trong hầu hết các trường hợp có thể loại trừ toàn bộ đơn vị sẽ đủ chi tiết cho tôi, nhưng có thể tránh một số phương pháp hoặc thậm chí các dòng mã sẽ còn tốt hơn.

Cập nhật: Có lẽ CodeGear nên giới thiệu cái gì đó như skip-điểm (như trái ngược với break-points) :-)

Trả lời

22

Có một "công cụ chuyển đổi nodebug ma thuật". {$ D-} sẽ vô hiệu hóa việc tạo mã gỡ lỗi. Đặt nó ở trên cùng của thiết bị FastMM của bạn và bạn sẽ không kết thúc truy tìm vào nó. Và nếu bạn kết thúc trong một chức năng mà bạn không muốn ở, SHIFT-F8 sẽ giúp bạn thoát ra rất nhanh. (CẢNH BÁO: Không sử dụng SHIFT-F8 từ bên trong một thói quen mã-lắp ráp mà chơi xung quanh với ngăn xếp. Hành vi không thể đoán trước có thể dẫn đến F4 đến đáy của nó.)

+0

Tuyệt vời! Nó hoạt động chính xác theo cách tôi muốn: trình gỡ rối không bước vào nó nữa, trong khi vẫn nhận được mã hoàn thành và có thể xem và sửa đổi mã "gỡ lỗi gỡ lỗi" nếu tôi muốn. –

+0

Đối với FastMM4: báo cáo rò rỉ vẫn hoạt động, miễn là bạn không có {$ define RequireDebugInfoForLeakReporting}, không được xác định theo mặc định. –

+0

Bạn thưa bạn, theo như tôi đang quan tâm, đã giành được Internet ngày hôm nay. Làm việc rất đẹp. Rất rất cảm ơn. – Alan

2

AFAIK, các chương trình gỡ rối chỉ biết các tập tin trong Browsing Đường dẫn mà bạn có thể sửa đổi trong Tùy chọn. Vì vậy, nếu bạn loại trừ các đường dẫn của các mô-đun bạn không quan tâm đến việc gỡ lỗi sẽ cho hiệu quả của những gì bạn muốn làm.

Một lưu ý: hoàn thành mã cũng dựa trên Đường dẫn duyệt web, do đó bạn có thể gặp phải các trường hợp hoàn thành mã quá ngắn khi cần.

0

No. Tôi không tin rằng có một cách để báo cho trình gỡ lỗi không bao giờ dừng lại ở một phần mã nhất định. Không có chỉ thị ma thuật.

Điều tốt nhất bạn có thể làm khi bạn tham gia một thói quen bạn không muốn tham gia là sử dụng Shift + F8 sẽ chạy cho đến khi trở về. Sau đó thực hiện F7 hoặc F8 để thoát khỏi quy trình.


Hmmm. Bây giờ tôi thấy câu trả lời của Mason. Đã học được điều gì đó. Cảm ơn, Mason.1

4

Sử dụng một precompiled phi debug DCU của FasmMM

2

Mặc dù nó không phải là một câu trả lời trực tiếp câu hỏi của bạn, bạn có thể sửa đổi giải pháp đề nghị đầu tiên của bạn bằng cách đặt breakpoint tại bla mà chỉ được kích hoạt khi một breakpoint tại Foo được thông qua (hoặc một số điều kiện khác mà bạn chọn, chẳng hạn như số lần lặp). Sau đó, nó sẽ chỉ phá vỡ khi bạn muốn nó.

Là một sang một bên, tôi đang tìm kiếm nhiều hơn và nhiều hơn nữa mà tôi không ngừng thực hiện tại các điểm phá vỡ, nhưng thay vì bán phá giá trị biến hoặc ngăn xếp bãi vào bản ghi thư. Điều này cho phép phân tích cẩn thận hơn so với kiểm tra trực tiếp các biến, vv FWIW.

7

Nếu bạn đang nhảy vào Mã FastMM, sau đó có các hoạt động bộ nhớ xảy ra. Mã bạn đã hiển thị không có bất kỳ hoạt động bộ nhớ nào, do đó câu hỏi của bạn chưa hoàn thành. Tôi sẽ cố gắng đoán xem bạn muốn nói gì.

Khi chương trình con có các biến cục bộ của các loại trình biên dịch được quản lý (như chuỗi, giao diện hoặc mảng động), thì phần mở đầu hàm có công việc không tầm thường để thực hiện. Phần mở đầu cũng là nơi tính số tham chiếu của các thông số đầu vào được điều chỉnh. Trình gỡ lỗi đại diện cho phần mở đầu trong dòng begin của hàm. Nếu điểm thực thi hiện tại là dòng đó và bạn "bước vào" nó, bạn sẽ được đưa đến mã RTL để quản lý các loại đặc biệt. (Tôi cũng không mong đợi FastMM sẽ tham gia ở đó, nhưng có lẽ mọi thứ đã thay đổi từ những gì tôi thường làm.) Một điều dễ dàng để làm trong tình huống đó là "bước qua" đường dây begin thay vì vào đó; sử dụng F8.

Nếu bạn thực sự nhấn F7 khi nhập dòng được đánh dấu của bạn, thì bạn đang làm sai. Đó là bước vào dòng begin, không phải dòng mà tại đó DoStuff được gọi. Vì vậy, cho dù bạn được đưa đến mã FastMM không có gì để làm với việc thực hiện DoStuff. Để gỡ lỗi cuộc gọi đến DoStuff, điểm thực hiện hiện tại phải là đường có cuộc gọi trên đó.

Nếu bạn chỉ muốn gỡ lỗi DoStuff khi lặp lại 23498938, thì bạn có thể đặt một điểm ngắt điều kiện có điều kiện trong chức năng đó. Nhấp vào máng xối để tạo điểm ngắt bình thường và sau đó nhấp chuột phải vào điểm đó để hiển thị các thuộc tính của nó. Ở đó bạn có thể định nghĩa một điều kiện sẽ được đánh giá mỗi khi thực hiện đạt đến điểm đó. Trình gỡ rối sẽ chỉ dừng ở đó khi điều kiện là đúng. Nhấn F8 để "chuyển sang" cuộc gọi DoStuff và nếu điều kiện là đúng, trình gỡ lỗi sẽ dừng ở đó như thể bạn đã nhấn F7.

Bạn có thể chuyển đổi tùy chọn "sử dụng gỡ lỗi DCU" để tránh bước vào hầu hết các đơn vị RTL và VCL. Tôi không biết liệu FastMM có được bao gồm trong bộ đó hay không. Sự khác biệt chính là liệu các DCU mà bạn đã liên kết đến có được biên dịch với thông tin gỡ rối hay không. Cài đặt sẽ thay đổi đường dẫn thư viện để bao gồm hoặc loại trừ thư mục phụ nơi DCU gỡ lỗi. Tôi nghĩ rằng bạn có thể định cấu hình bộ thư mục gỡ lỗi được bao gồm hoặc loại trừ để một nhóm thư mục tùy chỉnh được thêm hoặc xóa dựa trên cài đặt "gỡ lỗi DCU".

Quay lại điểm ngắt. Bạn có thể thiết lập nhóm điểm ngắt bằng cách chỉ định tên cho điểm ngắt của mình. Bạn có thể sử dụng điểm ngắt nâng cao để bật hoặc tắt nhóm điểm ngắt có tên khi bạn vượt qua. (Các nhóm Breakpoint có thể chỉ có một điểm dừng, nếu bạn muốn.) Vì vậy, ví dụ, nếu bạn chỉ muốn phá vỡ vị trí X nếu bạn cũng đã chuyển một số vị trí Y khác trong chương trình của mình, bạn có thể thiết lập một điểm dừng vô hiệu tại X và một điểm ngắt không phá vỡ tại Y. Đặt cài đặt "bật nhóm" tại Y để bật nhóm X.

Bạn cũng có thể tận dụng các điểm ngắt được tắt mà không bật và tắt tự động. Điểm ngắt của bạn xuất hiện trong cửa sổ trình gỡ lỗi "điểm ngắt". Nếu bạn đang bước qua DoStuff và bạn quyết định bạn muốn kiểm tra bla lần này, hãy chuyển đến cửa sổ điểm ngắt và bật điểm ngắt tại bla. Không cần điều hướng đến việc triển khai bla để đặt điểm ngắt tại đó.

Để biết thêm về điểm ngắt nâng cao, hãy xem Using Non-Breaking Breakpoints in Delphi và bài viết của Cary Jensen từ vài năm trước.

+0

>> ... do đó, một bộ khách hàng các thư mục được thêm vào hoặc loại bỏ dựa trên cài đặt "gỡ lỗi DCUs". Điều đó không bao giờ xảy ra với tôi. Tôi vừa thêm các nguồn DevEx vào đường dẫn DCU Debug - et voilà: không cần chỉnh sửa thủ công đường dẫn tìm kiếm dự án nữa. –

+0

Bạn nói đúng, ví dụ này yếu vì vấn đề cụ thể của FastMM sẽ không xảy ra ở đó. Tôi nghi ngờ có chấp nhận câu trả lời này hay của Mason không. Câu trả lời này có đầy đủ các thông tin và lời khuyên thú vị, nhưng câu trả lời của Mason ngay lập tức giải quyết được vấn đề. –

5

Tôi có thể đã bỏ lỡ nội dung nào đó với bài đăng của bạn, nhưng với FastMM4 bạn có thể chỉnh sửa FastMM4Options.Inc bao gồm tệp và xóa '.' từ define:


Từ FastMM4Options.inc ****

{Kích hoạt tùy chọn này để ngăn chặn việc tạo ra thông tin gỡ lỗi cho đơn vị FastMM4.pas. Điều này sẽ ngăn chặn các chương trình gỡ rối tích hợp từ bước vào mã quản lý bộ nhớ.}

{$ .define NoDebugInfo}


Khi biên dịch lại (có thể cần xây dựng) trình gỡ lỗi sẽ (nên) không còn gỡ lỗi Mã fastMM.

+0

(+1) Eventmough fastmm được sử dụng làm ví dụ duy nhất, tôi nghĩ đề xuất của bạn là cách tốt nhất để xử lý fastmm4 .. Bằng cách nào đó cảm thấy sai khi sửa đổi fastmm4.pas; –

3

Trong tập tin DPR dự án, tôi sử dụng

uses 
{$IFNDEF DEBUG} FastMM4, {$ENDIF} 
    ... // other units 

để loại trừ FastMM4 trong chế độ gỡ lỗi. Không yêu cầu thay đổi trong FastMM4 vì vậy tôi không phải nhớ thêm {$ D-} trong FastMM khi tôi thay đổi sang phiên bản khác.

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