2008-09-24 39 views
12

Khi một lỗi xảy ra trong một hàm, tôi muốn biết chuỗi các sự kiện dẫn đến nó, đặc biệt khi hàm đó được gọi từ hàng tá địa điểm khác nhau. Có cách nào để lấy stack cuộc gọi trong VB6, hoặc tôi phải làm điều đó một cách khó khăn (ví dụ, đăng nhập mục trong mọi chức năng và xử lý lỗi, vv)?Có thể truy xuất ngăn xếp cuộc gọi lập trình trong VB6 không?

Trả lời

9

Tôi chắc chắn bạn phải làm điều đó một cách khó khăn. Tại công việc trước đây của tôi, chúng tôi đã có một quá trình xử lý lỗi rất thanh lịch cho VB6 với các thành phần DCOM. Tuy nhiên, đó là rất nhiều mã dự phòng cần phải được thêm vào mọi phương pháp, nhiều đến mức chúng tôi đã có các công cụ phát triển trong nhà để chèn tất cả cho bạn.

Tôi không thể cung cấp quá nhiều thông tin chi tiết về việc triển khai (cả hai vì tôi đã quên hầu hết và có khả năng họ coi đó là bí mật thương mại). Một điều nổi bật là tên phương thức không thể xuất phát trong thời gian chạy để nó được thêm vào dưới dạng biến chuỗi (một số nhà phát triển sẽ sao chép-dán thay vì sử dụng công cụ và nó sẽ dẫn đến lỗi ngăn xếp. ..).

HTH

+0

Đây là cách duy nhất tôi biết để làm điều đó. Như được đề xuất bên dưới, MZTools có thể trợ giúp. Trong mẫu của bạn cho trình xử lý lỗi, nếu bạn định truyền bá lỗi, hãy thêm hàm/sub hiện tại của bạn vào err.source. –

+0

Tôi tin rằng không có cách nào để làm những gì tôi hỏi, vì vậy tôi sẽ chấp nhận câu trả lời này. – raven

3

Cách thủ công, khó khăn là khá nhiều cách duy nhất. Nếu bạn kiểm tra câu hỏi this, ai đó đã đề xuất một công cụ gọi là MZTools sẽ làm nhiều công việc khó chịu cho bạn.

+0

Tôi đã sử dụng MZTools trong nhiều năm và tôi đồng ý rằng đó là một công cụ tuyệt vời. Tuy nhiên, tôi đang tìm kiếm một thay thế cho "dấu vết ngăn xếp của người nghèo". Tôi không nghĩ có một, nhưng tôi nghĩ rằng nó không thể làm tổn thương để hỏi ở đây. – raven

0

Compuware (hoặc là Numega tại thời điểm đó) DevStudio cho Visual Basic 6 được sử dụng để thực hiện việc này. Cách này là bằng cách thêm thêm công cụ cho mọi cuộc gọi được gọi là một đoạn mã rất nhỏ được thêm vào ngăn xếp mã. Trên bất kỳ lỗi nào, nó đổ ra khỏi callstack đó, và sau đó đã làm những việc như mail hoặc post tới một máy chủ web tất cả các thông tin gỡ lỗi. Thêm và loại bỏ các thiết bị đo đạc là một hoạt động gây nguy hiểm tiềm ẩn (đặc biệt là sau đó, khi chúng tôi đang sử dụng VSS như kiểm soát nguồn của chúng tôi), nhưng nếu nó hoạt động, nó hoạt động tốt.

Darrel pointed out, bạn có thể thêm nội dung rất mô phỏng bằng cách sử dụng MZTools và thiết lập mẫu. Đó là rất nhiều công việc, và có lẽ nhiều hơn effeort hơn phần thưởng sẽ được nhưng nếu bạn có rất khó khăn để theo dõi lỗi, nó có thể giúp).

11

Bạn phải làm điều đó một cách khó khăn, nhưng nó không thực sự tất cả rằng cứng ... Nghiêm túc, một khi bạn đã viết mẫu một lần, đó là một copy/paste nhanh/sửa đổi để phù hợp với tên hàm trong câu lệnh Err.Raise đến tên hàm thực tế.

Private Function DoSomething(ByVal Arg as String) 

    On Error GoTo Handler 

    Dim ThisVar as String 
    Dim ThatVar as Long 

    ' Code here to implement DoSomething... 

    Exit Function 

Handler: 
    Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description 

End Function 

Khi bạn có cuộc gọi lồng nhau, thao tác này sẽ được giải phóng theo từng lần xử lý thông thường và thêm tên của nó vào mô tả lỗi. Ở chức năng cấp cao nhất, bạn nhận được một "ngăn xếp cuộc gọi" hiển thị danh sách các thói quen được gọi, và số lỗi và mô tả về lỗi thực sự xảy ra. Nó không hoàn hảo, trong đó bạn không nhận được số dòng, nhưng tôi thấy rằng bạn không thường cần chúng để tìm đường cho vấn đề. (Và nếu bạn thực sự muốn số dòng, bạn có thể đặt chúng trong hàm và tham chiếu chúng trong câu lệnh Err.Raise bằng biến Erl. Không có số dòng, chỉ trả về 0.)

Ngoài ra, hãy lưu ý rằng trong chức năng riêng của mình, bạn có thể nâng lỗi của riêng bạn với các giá trị của các biến thú vị trong thông báo như vậy:

Err.Raise PCLOADLETTER_ERRNUM, , "PC Load Letter error on Printer """ & PrinterName & """" 

(các cú pháp tô sáng trông rung rinh trong xem trước ... tôi tự hỏi làm thế nào nó sẽ xem xét khi được đăng?)

+1

upvoted cho pc tải thư – rpetrich

1

Như những người khác đã nói (năm trước, tôi thấy ... nhưng có rất nhiều người vẫn đang sử dụng VB6! :)), tôi nghĩ rằng không thể để progr lấy một cách vô hạn Call Stack, trừ khi bạn sử dụng một số công cụ của bên thứ ba.

Nhưng nếu bạn cần làm điều đó cho mục đích gỡ lỗi, bạn có thể xem xét việc thêm vào biến thường gọi là biến chuỗi đầu vào tùy chọn, bạn sẽ đặt tên người gọi.

Sub MyRoutine 
    (...) ' Your code here 
    call DoSomething (Var1, Var2, Var3, "MyRoutine") 
    '          ^
    '  Present routine's name -----------+ 

    (...) ' Your code here 

End Sub 


Public DoSomething (DoVar1, DoVar2, DoVar3, Optional Caller as string = "[unknown]") 
    Debug.Print " DoSomething Routine Called. Caller = " & Caller 

    ... ' (your code here) 

End Sub 

Không quá thanh lịch, có thể, nhưng nó hiệu quả với tôi.

Kính trọng, Tối đa - Ý

+0

Ai đã từng nói VB6 là thanh lịch không? – RubberDuck

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