2011-07-07 10 views
11

Giả sử tôi có một số lớp cơ sở A và hai lớp dẫn xuất B và C. Lớp A có một số phương thức được gọi là f().Tôi có thể đặt điểm ngắt có điều kiện trong phương thức lớp cơ sở chỉ kích hoạt nếu đó là một thể hiện của lớp dẫn xuất cụ thể không?

Có cách nào để đặt điểm ngắt có điều kiện trong A :: f() trong studio trực quan sẽ chỉ được nhấn khi 'this' của tôi thực sự là một thể hiện của lớp C không?

Ví dụ


    void A::f() 
    { 
    some code and a breakpoint 
    } 

    void foo(A* a) 
    { 
     a->f(); 
    } 

    void bar() 
    { 
     A a; 
     B b; 
     C c; 
     foo(&a); // breakpoint isn't hit 
     foo(&b); // breakpoint isn't hit 
     foo(&c); // breakpoint is hit 
    }

tôi đã quản lý để đạt được điều đó bằng cách kiểm tra con trỏ bảng ảo trong tình trạng breakpoint nhưng có nhận được một tốt hơn (dễ hơn) cách.

Xin cảm ơn trước.

EDIT: Sửa đổi mã nguồn như đã được đề xuất trong nhận xét không phải là loại giải pháp mà tôi đang tìm kiếm. Nó phải được thực hiện chỉ bằng phương tiện của trình sửa lỗi VC++.

+1

ghi đè phương thức trong lớp dẫn xuất để chỉ cần gọi lớp cơ sở và đặt điểm ngắt của bạn ở đó? – AJG85

+0

@ AJG85 - có, nhưng có thể nhị phân không thể sửa đổi được. fwiw Tôi không nghĩ rằng BP có điều kiện cho phép điều này được thực hiện. –

+0

Trong trường hợp đó câu trả lời là "Không" – AJG85

Trả lời

0

Tại trang web gọi (ví dụ: nơi đang thực hiện cuộc gọi foo), gần như không thể thực hiện điều đó. Trong chính chức năng, bạn có thể thực hiện điều này bằng cách có một hàm ảo, một trong số chúng sẽ trả về true. Tất cả những người khác sẽ trả về false. Nếu hàm trả về true, bạn có thể gọi tới số DebugBreak. Hoặc đặt giá trị trả về của nó vào một số biến số bool và đặt điểm ngắt có điều kiện. Có, tất nhiên, điều này đòi hỏi một chức năng ảo để được thêm vào trong tất cả các lớp (hoặc một số). Ngoài ra, bạn có thể có một biến đơn giản bool trong lớp cơ sở, sẽ được gán bởi lớp dẫn xuất. Lớp dẫn xuất thích hợp (C trong trường hợp của bạn) có thể gán nó là true. Bạn có thể thực hiện công cụ ảo/biến này trong chế độ gỡ lỗi chỉ bằng cách sử dụng macro _DEBUG.

Một giải pháp khác là có macro, gọi hàm foo. Việc triển khai yêu cầu một biến chức năng ảo/thành viên trong lớp cơ sở như mô tả ở trên, nhưng foo sẽ không bị sửa đổi.

#define CALL_FOO(obj) \ 
    if(obj->member_variable_test) DebugBreak(); \ 
    foo(&obj); 

Và gọi CALL_FOO ở vị trí của foo:

CALL_FOO(&c); // breakpoint is hit 

Mặc dù, điều này có lẽ không thể chấp nhận, nhưng công trình. Và breakpoint được nhấn chính xác nơi bạn cần! Bạn có thể làm cho macro này chỉ hoạt động trong quá trình gỡ lỗi.

1

This post seems to hint at the possibility of programmatic debugging in Visual Studio.

Ngoài ra, nếu bạn có thể dịch chương trình nguồn trong gcc hoặc bằng cách nào đó sử dụng gdb, bạn có thể tận dụng các chức năng scripting python để tạo ra breakpoint có điều kiện phức tạp.

Here are some gdb python tutorials. Here is the relevant gdb documentation.

+0

Có, tôi biết có thể với gdb. Không may là tôi đang xếp chồng với Visual Studio. – Serge

2

Đây là dynamic_cast là để làm gì.

void A::f() { 
    ... 
    if (dynamic_cast<C*>(this)) { 
     __debugbreak(); 
    } 
    ... 
} 

Nếu bạn phải làm điều đó bằng cách trình gỡ lỗi, sau đó bạn sẽ phải phá vỡ, kiểm tra các loại sử dụng dynamic_cast trong cửa sổ ngay lập tức, và sau đó tiếp tục nếu không muốn nói.

+0

Không, không thể sửa đổi mã. – Serge

4

Bạn có thể.Trước tiên, hãy xác định địa chỉ của bảng ảo loại bạn muốn kiểm tra. Sau đó, thiết lập điểm ngắt với điều kiện như (arg) .__ vfptr! = 0x01188298 trong đó 0x01188298 là địa chỉ loại vtable của bạn. Đó là nó.

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