Problem:
Debugging through COBOL calling C with both debuggers.
Resolution:
Debugging through Net Express 4.0 COBOL int code and Visual Studio 6 C DLL code
===========================================================
The project locations for this example are "C:\\cobol\\cobcallc" for the COBOL project and "C:\\cobol\\csubprog"
for the Visual Studio C DLL project.
It may be necessary to first edit the Windows System PATH environment variable to add the location of the C DLL so that the COBOL program can load the C DLL if they are in different locations.
Open the Net Express project.
Choose the "Animate" menu, "Settings..." menu:
In the "Mixed Language Debugging" group, make sure that the "enable mixed-language debugging and disable generated and linked code debugging" radio button is selected.
In the "General" group, the "Start Animating at" field should point to the location of Visual Studio 6 IDE,
such as:
"C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\Bin\\MSDEV.EXE"
The "Local working directory" field should be the project directory of your Net Express application such as:
C:\\COBOL\\cobcallc
The "Command line parameters" field should be the location of the Net Express runw trigger program that the
IDE starts at animation, with a parameter of the .int code file name that you want to debug, such as:
"C:\\Net Express 4.0\\Base\\BIN\\runw.exe" C:\\COBOL\\cobcallc\\DEBUG\\cobcallc.int
Be sure to use quotes around path names and program names with spaces. Close the Animate Settings dialog box.
In Net Express, choose the "Animate", "Step" menus and Visual Studio should start.
Hit the F5 key when focus is in the Visual Studio IDE and a dialog box will be displayed saying that runw.exe does not contain debugging information...and click the OK button.
Back over to the Net Express IDE, animate to the point just before the first call to a function in the C program.
Back over to the Visual Studio IDE, select the "Project", then "Settings..." menus, select the "Debug" tab on the dialog box and change the "Category" dropdown to "Additional DLLs". In the "Modules" listview,
click on the first empty row under the column "Local Name", then click the "Browse" button and
select your C DLL. Click OK to close the dialog box.
Select the "Edit" and "Breakpoints..." menus and type in the name of the first C function entry point which will be called from COBOL in the "Break at" field.
In this example, csub1 and csub2 can be used.
Click OK to close the dialog box.
It may be necessary to right-click on the source window if assembly instructions are displayed, and choose the "Go to Source" menu option.
Switch back to the Net Express IDE and step into the call to the C program/function.
In the Visual Studio 6 IDE, there should be a pointer set at the called function name.
To set additional breakpoints from here, right-click in the left-hand margin and select "Insert/Remove Breakpoint".
F5 (Go) can then be pressed to run to the next breakpoint, or step using F10 or F11.
When all of the C code has been run, go back to the Net Express IDE and continue animating. When finished close the Visual Studio workspace, to be prompted to save the workspace information for runw.exe (probably in Net Express\\base\\bin\\runw.opt). If this is done then the next time the project is debugged it will not be necessary to browse for the C DLL or to set the breakpoints for the C DLL code.
COBOL code for cobcallc.cbl:
identification division.
$set case
program-id. cobcallc.
data division.
working-storage section.
01 i pic x(4) comp-5.
01 junk pic x.
01 pptr procedure-pointer.
procedure division.
set pptr to entry "csubprog.dll".
if pptr not = null
move 3 to i
display "In cobcallc, i is " i
display "Hit Enter to continue..."
accept junk
call "csub1" using by reference i
display "Returning from csub1, i is " i
call "csub2" using by reference i
display "Returning from csub2, i is " i
display "Hit Enter to end..."
accept junk
else
display "failed to load csubprog.dll"
end-if.
stop run.
C code for csubprog.c:
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void csub1 (int *i) {
printf("In csub1, i is " *i);
*i = *i 1;
printf("In csub1, i is now " *i);
}
__declspec(dllexport) void csub2 (int *i) {
printf("In csub2, i is " *i);
*i = *i - 1;
printf("In csub2, i is now " *i);
}
#ifdef __cplusplus
} /*extern "C" */
#endif
