We have legacy code in visual cobol (I believe the currently running code was compiled against VC 3.0, but not certain). I am trying to get it running compiled against VC10, but I'm facing runtime issues. After a lot of debugging I seem to have narrowed the issue down.
The basic flow is this:
- The host application (VB.NET) calls a managed cobol method.
- The managed cobol method invokes a method in a another managed cobol class.
- The second cobol class makes a Call to a non-managed cobol program.
- The second cobol class completes and returns to the first.
- The first managed cobol method makes a call to another non-managed cobol program.
- An exception is thrown with the stacktrace below
The key cannot be null
vid System.Collections.Hashtable.ContainsKey(Object key)
vid System.Collections.Hashtable.Contains(Object key)
vid MicroFocus.COBOL.Runtime.Common.SyncHashtableMF.get_Item(Object key)
vid MicroFocus.COBOL.Runtime.Common.RunUnit.GetNestedProgram(String program, MethodInfo& method, Object& instance)
vid MicroFocus.COBOL.Program.ProcedurePointer.CreateProcedurePointer(RunUnit runUnit, String programName)
vid MicroFocus.COBOL.Program.ProcedurePointer.GetProcedurePointer(RunUnit runUnit, String name)
vid MicroFocus.COBOL.Program.Control.CallReturningObject(UInt32 callConvention, String program, Object[] parameters, IObjectControl pgInstance)
vid MicroFocus.COBOL.Program.Control.Call(UInt32 callConvention, String program, Object[] parameters, IObjectControl pgInstance)
vid EcompClasser.P80PS008F.mHamtaPersonInfo(Person& dPerson, DataTable& dtLonespec, List`1& lSaldo, DataTable& dtAnstallningar, ReturKoder& dReturKoder)
vid ECompHandlers.PersonHandler.HamtaPersonInfo(Person& dPerson, DataTable& dtLoneSpec, List`1& dSaldo, DataTable& dtAnstallningar, ReturKoder& dReturKoder) i D:\\repos\\Muni.ECompWebb\\ECompWebb\\ECompHandlers\\Handlers\\PersonHandler.vb:rad 14
Some trial and error findings:
- The exception is not thrown if the second cobol class makes no non-managed call.
- The exception is not thrown if the second class and the first class calls the same non-managed program, only if they call different programs.
- The exception is not thrown if I call either of the two involved non-managed programs from the first class, before invoking the second class.
- The exception is thrown if I call some other non-managed program before the second class invokation.
Based on my trials it would seem the call context is stored per program on the first call. If the first call to a program is made from the invoked second class, any future calls to new programs will fail, but any that have already been called will use the stored values and work correctly.
Any ideas on what could be causing this and any workarounds? The second class in my example is a shared class that is called in almost every managed entry point in order to get basic configuration data, so this flow is present everywhere in our legacy code.