Skip to content

Debugging Strategies

Todd Schiller edited this page Apr 20, 2015 · 2 revisions

Debugging Strategies

It's almost universally useful to isolate the bug to the smallest possible case. Try to determine which classes or methods in the subject program are at issue, and create a program containing only them. This will eliminate other potential bugs, improve iteration speed, and allow you to create a test case to verify the correctness of the fix.

  1. First make sure the bug reporter has followed the steps found on the Reporting a Bug page, referring them to that page if necessary.
  2. Second, determine if the bug occurs during rewriting or program execution. You can tell this by adding --save-program as a command line argument. If the program cannot be successfully rewritten the bug is a rewriting bug, otherwise it's a bug that occurs during execution. * Rewriting bugs will give you an exception trace, see if any information in the exception is useful for debugging. It's helpful to look at the InnerException property from within Visual Studio's debugger. Bugs of this type probably will be fixed in the ILRewriter.cs file. * For bugs that occur during execution try first verifying the rewritten program. This can be accomplished from the Visual Studio Command Line tools window. Type peverify [executable-name] If there are any errors they may reveal what the problem is. Bugs of this type will probably be fixed in the ILRewriter.cs file.
  3. If the program passes the IL verifier but produces invalid output determine what about the output is invalid. Running the .dtrace through Daikon will usually produce useful error messages. See which line is causing the problems, and which variable is being instrumented at that line. Set conditional breakpoints in the VisitVariable method in VariableVisitor.cs or PrintVariable method in DeclarationPrinter.cs to get you to break at the time in the code when the bug is occurring.

Common Issues

  • Converting between CCI Metadata types, Assembly Qualified Names, and .NET types is a historically error prone area.

    • First, determine what the assembly qualified name of the type should be. This can be done by setting a breakpoint in the source program where a variable of the relevant type is in scope, suppose it's name val.
    • Run the source program outside of Celeriac, and when you get to the breakpoint determine val.GetType().AssemblyQualifiedName, remember this.
    • Then set a breakpoint in the ILRewriter code that calls TypeManager.ConvertCCITypeToAssemblyQualifiedName(). There are many callsites, each corresponding to a different variable case. Step through and see if the proper AssemblyQualifiedName is being produced.
    • If the proper AssemblyQualifiedName is being produced then you must check that it is resolved properly when the rewritten program is running. Set a conditional breakpoint in the VisitVariable method with the name of the variable used from the first step. Watch as the TypeManager.ConvertAssemblyQualifiedNameToType proceeds, which should point you in the direction of fixing the resolution error.
  • A StackOverflowException during program execution breaking in Visual Studio to VariableVisitor.SetInvocationNonce(), probably means you are re-instrumenting an already instrumented version of your program.

  • Getting an error of "Could not load file or assembly 'file:///...' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)" may occur if you get an executable downloaded from the internet or email, in these cases Windows attempts to block the file to prevent virus spread. To fix this problem right click on the executable in Windows Explorer, then click Properties. In the General tab near the bottom there is a button labeled Unblock, click this, then click OK to close the properties window.

  • An exception with error message like System.Runtime.InteropServices.COMException was unhandled HResult=-2147418113 Message=Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) may indicate that one of the CCI DLL files in the %CELERIAC_HOME% folder is not executable.