6

Vì vậy, tôi muốn đặt điểm ngắt trong một thông báo API hoặc Windows cụ thể. Tôi không tìm thấy bất kỳ cách dễ dàng để làm điều đó mà không cần viết mã trong bất kỳ phiên bản Delphi nào. Có cách nào để làm điều đó tương tự như tôi có thể đặt điểm ngắt trong truy cập bộ nhớ không?Có bất kỳ cách nào nhanh chóng, trong khi gỡ lỗi, để dừng tại một Windows Message hoặc API cụ thể?

Trả lời

12

Để dừng tại bất kỳ lệnh gọi nào đến chức năng API, hãy tìm nó trong phần implementation của Windows.pas (hoặc bất kỳ nơi nào chức năng quan tâm được khai báo) và đặt điểm ngắt. Điều đó đảm nhận các chức năng bạn sử dụng với liên kết động thời gian tải. Đối với liên kết động thời gian chạy (LoadLibraryGetProcAddress), bạn sẽ cần một kỹ thuật khác. Biến được kết quả là GetProcAddress sẽ giữ địa chỉ bạn muốn ngắt, nhưng tôi không biết cách đặt breakpoint tại địa chỉ đó.

Dừng trên cửa sổ thư là phức tạp hơn vì thư có thể được truy xuất ở nhiều nơi. Bạn sẽ phải sử dụng các điểm ngắt có điều kiện để thay thế.

Để bắt hầu hết các thư đã đăng, bạn có thể đặt điểm ngắt trong TApplication.HandleMessage trên dòng đầu tiên sau khi gọi tới PeekMessage. Đặt điều kiện là Msg.Message = x. HandleMessage quản lý các tin nhắn được gửi đến hàng đợi tin nhắn của chuỗi chính cho vòng lặp tin nhắn chính Application.Run cũng như các vòng tin nhắn phương thức của VCL. Tuy nhiên, các hộp thoại phương thức khác (chẳng hạn như Windows.MessageBox) sẽ không sử dụng nó.

Quan sát gửi thông báo khó hơn vì hệ điều hành gửi chúng đến thủ tục cửa sổ mục tiêu của họ trực tiếp. Bạn sẽ phải thiết lập một điểm ngắt trong quy trình cửa sổ của mỗi lớp cửa sổ mà bạn quan tâm. Bạn có thể nhận được hầu hết các lớp cửa sổ VCL bằng cách đặt điểm ngắt có điều kiện của bạn trong Classes.StdWndProc.

Hãy nhớ rằng các điểm ngắt có điều kiện có thể rất chậm. Chúng hoạt động bởi trình gỡ lỗi đặt điểm ngắt vô điều kiện không có điều kiện ở đó và khi hệ điều hành kích hoạt nó, trình gỡ lỗi sẽ tiếp quản, kiểm tra điều kiện và sau đó tiếp tục thực hiện nếu điều kiện không thành công. Điều đó có thể liên quan đến rất nhiều chi phí, chuyển đổi giữa trình gỡ lỗi và ứng dụng của bạn; các chương trình nhận được thư, vì vậy nếu bạn có thể tìm cách tránh trình gỡ lỗi gián đoạn chương trình của bạn, hãy kiểm tra mỗi một trong số đó, hãy thực hiện.

Nếu điều này không khả thi đối với bất cứ điều gì bạn đang cố gỡ lỗi, thì tôi khuyên bạn nên đăng câu hỏi mới nơi bạn mô tả sự cố bạn đang thực sự cố giải quyết.

+4

Bạn có thể thêm điểm ngắt tại một địa chỉ cụ thể ... Vào cửa sổ điểm ngắt sau khi bạn chạy ứng dụng đã bị hỏng tại điểm ngắt (như tại cuộc gọi đến 'GetProcAddress'), nắm bắt địa chỉ của quy trình bằng cách nào đó, mở cửa sổ breakpoint, nhấp chuột phải và chọn Add> Address Breakpoint. Sau đó bạn đưa vào địa chỉ. Trình gỡ lỗi sẽ bị hỏng khi truy cập địa chỉ đó. Lưu ý: Địa chỉ rõ ràng chỉ hợp lệ đối với yêu cầu thực thi của bạn. – Nat

+0

+1. Câu hỏi này được thúc đẩy bởi một đồng nghiệp mới là một người dùng Delphi mới. Ông đã bỏ lỡ một thực tế rằng trong Visual Basic ông có thể làm một loại "theo dõi chuyển động người dùng tiếp theo" (trong khi gỡ lỗi, trình gỡ lỗi dừng lại trên người dùng nhấp, nhập, vv ... nhưng không phải trong khi ứng dụng là "nhàn rỗi"). Sử dụng callstack, tôi không bao giờ cảm thấy cần thiết. Nhưng nhận ra rằng tôi có thể sử dụng BP trong WindowsAPI và Messages để giải quyết một số lỗi lạ.Như tôi đã nhớ rằng trong một trình gỡ lỗi nâng cao khác, tôi chỉ có thể thực hiện 'BPX WM_GETTEXTA' trong cửa sổ bảng điều khiển, tôi đã tự hỏi liệu Delphi có dễ dàng hơn không. – EMBarbosa

+0

@Nat hmmm ... Có lẽ tôi có thể sử dụng một số API của Delphi Debugger mới để tự động hóa tác vụ đó ... Nhưng tôi không quá quen thuộc với điều đó ... Đây có phải là một câu hỏi hay không? – EMBarbosa

1

Bạn sẽ cần phải đi vào Tùy chọn | Linker và kiểm tra "Debug DCUs". theo mặc định, điều này không được kiểm tra để trình gỡ rối không bước qua toàn bộ VCL khi bạn đang cố gắng làm việc.

+0

Bên cạnh đây là nhận xét hợp lệ và quan trọng. Tôi không yêu cầu một cách để gỡ lỗi VCL. Bạn không thể bình luận với danh tiếng thấp ... Đó không phải là mát mẻ. Tôi biết... :( – EMBarbosa

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