Is it possible to retrieve the call stack programmatically in VB6?

后端 未结 5 1982
天涯浪人
天涯浪人 2020-12-03 21:25

When an error occurs in a function, I\'d like to know the sequence of events that lead up to it, especially when that function is called from a dozen different places. Is t

相关标签:
5条回答
  • 2020-12-03 21:59

    I'm pretty sure you have to do it the hard way. At a previous job of mine, we had a very elegant error handling process for VB6 with DCOM components. However, it was a lot redundant code that had to be added to every method, so much that we had home-grown tools to insert it all for you.

    I can't provide too much insight on its implementation (both because I've forgotten most of it and there's a chance they may consider it a trade secret). One thing that does stand out was that the method name couldn't be derived at run-time so it was added as a string variable (some developers would copy-paste instead of using the tool and it would lead to error stacks that lied...).

    HTH

    0 讨论(0)
  • 2020-12-03 21:59

    You do have to do it the hard way, but it's not really all that hard... Seriously, once you've written the template once, it's a quick copy/paste/modify to match the function name in the Err.Raise statement to the actual function name.

    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
    

    When you have nested calls, this unwinds as each routine hits its Handler and adds its name to the error description. At the top level function, you get a "call stack" showing the list of routines that were called, and the error number and description of the error that actually occurred. It's not perfect, in that you don't get line numbers, but I've found that you don't usually need them to find your way to the problem. (And if you really want line numbers, you can put them in the function and reference them in the Err.Raise statement using the Erl variable. Without line numbers, that just returns 0.)

    Also, note that within the function itself, you can raise your own errors with the values of interesting variables in the message like so:

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

    (The syntax highlighting looks wonky in the preview... I wonder how will it look when posted?)

    0 讨论(0)
  • 2020-12-03 22:03

    The hard, manual way is pretty much the only way. If you check out this question, someone suggested a tool called MZTools that will do much of the grunt work for you.

    0 讨论(0)
  • 2020-12-03 22:08

    As other people said (years ago, I see... but there's so many people still using VB6! :) ), I think it's not possible to programmatically retrieve the Call Stack, unless you use some 3rd-party tool.

    But if you need to do that for debugging purposes, you can consider of adding to the called routine an Optional input string variable, were you'll put the caller's name.

    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
    

    Not so elegant, maybe, but it worked for me.

    Regards, Max - Italy

    0 讨论(0)
  • 2020-12-03 22:09

    Compuware (or was it Numega at the time) DevStudio for Visual Basic 6 used to do this. The way was by adding adding instrumenation to every call that called a very small snippet that added to the code stack. On any error it dumped out that callstack, and then did things like mail or post to a webserver all the debuging information. Adding and removing the instrumentation was a potentially lethal operation (especially back then, when we were using VSS as our source control), but if it worked, it work well.

    As Darrel pointed out, you could add something very simlar by using MZTools and setting up a template. It's a lot of working, and is probably more effeort than the reward would be but if you have very difficult to track down bugs, it might help).

    0 讨论(0)
提交回复
热议问题