views:

999

answers:

4

I maintain an old application written in VB6. In client's environment it raises runtime errors which I can't reproduce under debugger. Is there any way to get the stacktrace or location of error?

I mean, without putting trace statements all over the code like here or adding error handlers for logging to every procedure like here.

It seems to be a simple question. Sorry. I just don't know VB6 very well. And it is surprisingly hard to google out any information, considering how widely it is (or used to be) used.

+1  A: 

It's been a while, but I don't think there is a way to get a stack trace in a VB6 application without adding an error handler and outputting the appropriate message. There were some third party tools that would add error handling to an entire application but I believe it just added "On Error Goto" error handlers throughout the code.

Just as an aside, one of the more insidious runtime errors I ever encountered in a VB6 app was when I used a font that didn't exist on the client's PC in the property of a control. This generates a runtime error that cannot be trapped in code, so no amount of error handling that I added ever uncovered the error. I finally came across it by chance. Hope this helps.

Bob Mc
If you invoke forms via the deprecated Form1.Show method, you won't be able to catch the error, but if you use the Dim form1Instance as Form1: Set form1Instance = new Form1(): form1Instance.Show syntax, an error will be thrown at the Set... line
rpetrich
+1  A: 

Try compiling to pcode and see if you still get the error. This is one common difference between the debug mode of VB6 and runtime. I used to compile to native and ran into errors that only occurred in runtime. When I switched to pcode I found either the error went away or more likely a new error that reflected the real problem cropped up and was more easily reproduced in debug mode.

If despite that you still getting the error then I really recommend starting at the top of your procedure stack and working you way down using Maero's suggestion of

On Error Goto Handler
<code>
Exit <routine>
Handler:
Err.Raise Err.Number, "(function_name)->" & Err.source, Err.Description

It is a pain but there is no real way around it.

RS Conley
The app is compiled to P-code. The problem is not debugging native code. The problem is, runtime error happens only in environment, I don't have access to. I just expected that interpreted (P-code) code would be able to give me some more information about runtime error in production system than C/C++, without me putting trace statements/error handlers all over the code.
Tomek Szpakowicz
I see one big drawback here. Now, if I do this, all runtime errors are handled. Debugger will not stop application at error location. Instead it will stop inside error handler in some other procedure down the stack. So this method helps with a I-have-no-debugger-in-production-environment scenario but breaks normal work with VB6 IDE.
Tomek Szpakowicz
@tomekszpakowicz: correct! A classic problem with a classic solution. Try this "If Not IsInIDE() Then On Error Goto Handler", using the IsInIDE function from here http://vbnet.mvps.org/index.html?code/helpers/isinide.htm
MarkJ
I'm not really satisfied by any answer here. I've chosen this answer only because a) I actually used this technique to pinpoint the cause of failure, although I'm not willing to litter all the code with this stuff, and b) as we migrate our codebase to .NET, I simply stopped to care about finding some better solution.
Tomek Szpakowicz
+1  A: 

If you check the "Create Symbolic Debug Info" checkbox on the Project Properties/Compile tab, then you can debug in Visual Studio just like you would a native C++ application.

Ant
+1. You can also use free debuggers like Windbg or Visual Studio 2008, see my answer.
MarkJ
I meant Visual Studio 2008 (or 2003 or 2005 or whatever), but yeah - good point about Windbg!
Ant
+1  A: 

The VB6 debugger is flaky sometimes. There are alternatives.

  • You could try Windbg, a free standalone debugger from Microsoft. Compile your VB6 with no optimisation and "create symbolic debug info" (i.e. create PDB files), and you will be able to debug. Here's a 2006 blog post by a Microsoft guy about using Windbg with VB6, and 2004 blog post by another Microsoft guy with a brief introduction to Windbg.
  • You could also use the Visual Studio 2008 debugger with VB6 and PDB files, e.g. with Visual C++ Express Edition (which is free). See this for more details.
  • Both Windbg and Visual Studio expect the source code to be in exactly the same path on the debug machine as it was on the build machine when the VB6 was built. The easiest way is to build and debug on the same machine. Otherwise you might need to fiddle with SUBST to create virtual drives - or I'm told the serious way is to use a Symbol Server.
MarkJ