diff --git a/CblGdbExt/CblGdb/README.md b/CblGdbExt/CblGdb/README.md index 3ab7fc7b1e19d65110700e24404fbdcbbb0a1e43..972df113fd5e206814f23ab249d79e46d82316d8 100644 --- a/CblGdbExt/CblGdb/README.md +++ b/CblGdbExt/CblGdb/README.md @@ -14,11 +14,11 @@ That executable can also be debugged on the source-code level with this extensio ## Prerequisites: GnuCOBOL -In order to debug a COBOL program, it must first be compiled with the GnuCOBOL compiler. The compiler must be the 3.1 version. The package must be at least the 3.1-rc2 version; rc1 and earlier versions will not work. +In order to debug a COBOL program, it must first be compiled with the GnuCOBOL compiler. The compiler must be at least the 3.1.2 version; earlier versions will not work. GnuCOBOL installation packages for Ubuntu, RedHat, and Windows can be found at [COBOLworx downloads](https://cobolworx.com/pages/downloads.html). -Those who prefer to build the GnuCOBOL compiler from source can downloaded the latest version from [here](https://alpha.gnu.org/gnu/gnucobol/). The build sequence starts with `./configure`. +Those who prefer to build the GnuCOBOL compiler from source can download the latest version from [here](https://alpha.gnu.org/gnu/gnucobol/). The build sequence starts with `./configure`. As an alternative you may build from developer source code, which is available in the [GnuCOBOL SVN repository](https://svn.code.sf.net/p/gnucobol/code/branches/gnucobol-3.x). The build sequence starts with `./autogen.sh`; for details see its `HACKING` file. @@ -31,13 +31,15 @@ As part of the compilation process, the cbl-gdb extensions need to be applied be Download and install the appropriate `COBOLworx GnuCOBOL Debugging Extensions package` from [COBOLworx downloads](https://cobolworx.com/pages/downloads.html) or from the [COBOLworx source repository](https://gitlab.cobolworx.com/COBOLworx/cbl-gdb). +Once the cbl-gdb extensions are installed, you compile COBOL code for debugging by replacing the `cobc` command with `cobcd`. So, when compiling `foo.cbl`, you enter the command `cobcd foo.cbl` instead of `cobc foo.cbl`. + ## Installation -If you didn't install this extension from [Open VSX Registry](https://open-vsx.org/?search=COBOLworx) or the [Microsoft Visual Studio Code Marketplace](https://marketplace.visualstudio.com/vscode), then you probably downloaded a file named cbl-gdb-4.1.1.vsix, which is a Visual Studio Code extension package. You have a couple of options for loading the extension into VS code: +If you didn't install this extension from [Open VSX Registry](https://open-vsx.org/?search=COBOLworx) or the [Microsoft Visual Studio Code Marketplace](https://marketplace.visualstudio.com/vscode), then you probably downloaded a file named cbl-gdb-4.2.1.vsix, which is a Visual Studio Code extension package. You have a couple of options for loading the extension into VS code: - From inside Visual Studio Code, use the Command Palette `(Ctrl+Shift+P)` to find "Extensions: Load extension from VSIX..." Select that, and point it at the .VSIX file. -- From the command line, execute `code --install-extension cbl-gdb-4.1.1.vsix` +- From the command line, execute `code --install-extension cbl-gdb-4.2.1.vsix` ## Additional extensions @@ -77,8 +79,7 @@ Create a text file CTEST.CBL The shell command `cobc --version | head -n 1` should return one of - cobc (GnuCOBOL) 3.1-dev.202009023 - cobc (GnuCOBOL) 3.1-rc2.0 + cobc (GnuCOBOL) 3.1.2.0 or greater. @@ -114,8 +115,9 @@ The immediate output from GDB should look like this: ``` $ gdb -q CTEST Reading symbols from CTEST... -registering CPrint (Usage is "print <COBOL identifier>") [Version 4.1] -registering CWatch (Usage is "cwatch <COBOL identifier>") +Registering CPrint (Usage is "cprint <COBOL identifier>") [Version 4.18] +Registering CWatch (Usage is "cwatch <COBOL identifier>") +Registering CBreak (Usage is "cbreak <line number> <COBOL identifier> == <value>") ``` *It is important that the two lines indicating PRINT and CWATCH have been registered appear here. If they are missing, then the cbl-gdb package wasn't completely installed.* @@ -172,7 +174,7 @@ three ### Putting it all together -At this point, Visual Studio Code has been installed, and the VSC extension for the COBOLworx Debugging Extensions has been installed into VSC. GnuCOBOL 3.1-rc2 (or higher) has been installed and tested. The COBOLworx cbl-gdb debugging extensions have also been installed and tested. +At this point, Visual Studio Code has been installed, and the VSC extension for the COBOLworx Debugging Extensions has been installed into VSC. GnuCOBOL 3.1.2 (or higher) has been installed and tested. The COBOLworx cbl-gdb debugging extensions have also been installed and tested. We are now ready to demonstrate source-level debugging of COBOL with Visual Studio Code. diff --git a/CblGdbExt/CblGdb/development-notes.md b/CblGdbExt/CblGdb/development-notes.md index 01d67b650619691c2c5bf5ce1a8092b969e31943..dd45e10cacc94fe2c296b3f8f02abd64002f5f3f 100644 --- a/CblGdbExt/CblGdb/development-notes.md +++ b/CblGdbExt/CblGdb/development-notes.md @@ -17,7 +17,7 @@ sudo snap install --classic code-insiders for the regular and bleeding-edge versions of Visual Studio Code. You probably don't need the bleeding-edge code-insiders version. -I don't at what point npm was installed. I do know that getting `vsce` to work +I don't know at what point npm was installed. I do know that getting `vsce` to work involved running npm install -g vsce @@ -57,7 +57,7 @@ The `debugging adapter`, which is likely what you are most interested in changin The `extension package`, which acts as a bridge between a user and the debugging adapter, will be running as a second instance in this folder as the `Extension` configuration. -The extension configuration launches a third instance of Visual Studio Code. You'll use that one to open the folder containing the test program that will be debugged by the debugging adapter. At this writing, this development-notes.md file is in a folder named `CamelCobolExt/cbl-gdb`. Some suitable test programs can be found in `CamelCobolExt/samples`. +The extension configuration launches a third instance of Visual Studio Code. You'll use that one to open the folder containing the test program that will be debugged by the debugging adapter. At this writing, this development-notes.md file is in a folder named `CblGdbExt/CblGdb`. Some suitable test programs can be found in `CblGdbExt/samples`. ## The three launch configurations diff --git a/CblGdbExt/CblGdb/package-lock.json b/CblGdbExt/CblGdb/package-lock.json index 4013bdda3c8e0d5ae2ad4a59b21886a8c2dabd1a..1dcf31f133c8aa0aa7ae0b17b6cac450c0a39a2a 100644 --- a/CblGdbExt/CblGdb/package-lock.json +++ b/CblGdbExt/CblGdb/package-lock.json @@ -1,6 +1,6 @@ { "name": "cbl-gdb", - "version": "4.1.1", + "version": "4.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/CblGdbExt/CblGdb/package.json b/CblGdbExt/CblGdb/package.json index 9ae4ea3e15dc55849f731854df8df0a2e8f1016b..0655f88713376bdcf3f1fc05236e647235d2d429 100644 --- a/CblGdbExt/CblGdb/package.json +++ b/CblGdbExt/CblGdb/package.json @@ -8,7 +8,7 @@ "debug" ], "license": "COBOLworx", - "version": "4.1.1", + "version": "4.2.1", "publisher": "COBOLworx", "icon": "images/COBOLworx.png", "engines": { diff --git a/CblGdbExt/CblGdb/src/backend/mi2/mi2.ts b/CblGdbExt/CblGdb/src/backend/mi2/mi2.ts index 4838c745f03dbaeded01ad0d47d1c717bd6b375f..bc7d5e89afe540c536425fa6ce4c6ed541f39b08 100644 --- a/CblGdbExt/CblGdb/src/backend/mi2/mi2.ts +++ b/CblGdbExt/CblGdb/src/backend/mi2/mi2.ts @@ -124,7 +124,7 @@ export class MI2 extends EventEmitter implements IBackend { promises.push(this.sendCommand("gdb-set new-console on")); Promise.all(promises).then(() => { this.emit("debug-ready"); - resolve(); + resolve(true); // Dubner added true }, reject); } else { if (separateConsole !== undefined) { @@ -132,13 +132,13 @@ export class MI2 extends EventEmitter implements IBackend { promises.push(this.sendCommand("inferior-tty-set " + tty)); Promise.all(promises).then(() => { this.emit("debug-ready"); - resolve(); + resolve(true); // Dubner added true }, reject); }); } else { Promise.all(promises).then(() => { this.emit("debug-ready"); - resolve(); + resolve(true); // Dubner added true }, reject); } } @@ -224,7 +224,7 @@ export class MI2 extends EventEmitter implements IBackend { promises.push(this.sendCommand("exec-arguments " + procArgs)); Promise.all(promises).then(() => { this.emit("debug-ready"); - resolve(); + resolve(true); // Dubner added true }, reject); }); }).on("error", (err) => { @@ -332,7 +332,7 @@ export class MI2 extends EventEmitter implements IBackend { } Promise.all(commands).then(() => { this.emit("debug-ready"); - resolve(); + resolve(true); // Dubner added true }, reject); }); } @@ -357,7 +357,7 @@ export class MI2 extends EventEmitter implements IBackend { this.sendCommand("target-select remote " + target) ]).then(() => { this.emit("debug-ready"); - resolve(); + resolve(true); // Dubner added true }, reject); }); } @@ -368,7 +368,7 @@ export class MI2 extends EventEmitter implements IBackend { if( typeof buf == "string" ) { // The cobcd.py extension to gdb returns a string when issued the - // command "p/m ?". The processing up to this point converts that + // command "cprint/m ?". The processing up to this point converts that // string to a string, meaning any embedded control characters // have been converted to '\"', '\\', '\n,' and so on. @@ -475,16 +475,16 @@ export class MI2 extends EventEmitter implements IBackend { var end = this.buffer.lastIndexOf('\n'); - // The 'p/m ?' request is not an MI request, so sometimes the - // p/m response comes in, and then a little while later the token^done + // The 'cprint/m ?' request is not an MI request, so sometimes the + // cprint/m response comes in, and then a little while later the token^done // response comes in. This following code only runs when a - // 'p/m ?' request has been sent. It will strip out the '&p/m ?' response + // 'cprint/m ?' request has been sent. It will strip out the '&cprint/m ?' response // that the machine-interface sends back. And then it'll accumulate // strings until it sees ^done if( this.recent_variables_request > -1 ) { - // We did a 'p/m ?' request. + // We did a 'cprint/m ?' request. if( this.buffer.length>0 && this.buffer.charAt(0) == '&') { // Strip out the '&...' echo end = this.buffer.indexOf('\n'); @@ -624,7 +624,7 @@ export class MI2 extends EventEmitter implements IBackend { this.log("console", "Running executable"); this.sendCommand("exec-run").then((info) => { if (info.resultRecords.resultClass == "running") - resolve(); + resolve(true); // Dubner added true else reject(); }, reject); @@ -737,7 +737,7 @@ export class MI2 extends EventEmitter implements IBackend { changeVariable(name: string, rawValue: string): Thenable<any> { if (trace) this.log("stderr", "changeVariable"); - return this.sendStraightCommand("p/m " + name + "=" + rawValue); + return this.sendStraightCommand("cprint " + name + "=" + rawValue); } loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]> { @@ -925,7 +925,7 @@ export class MI2 extends EventEmitter implements IBackend { if (trace) this.log("stderr", "getStackVariables"); - const result = await this.sendStraightCommand(`p/m ?`); + const result = await this.sendStraightCommand(`cprint/m ?`); const variables = result.result("variables"); const ret: Variable[] = []; for (const element of variables) { @@ -957,7 +957,7 @@ export class MI2 extends EventEmitter implements IBackend { this.log("stderr", "evalExpression"); } - let command = "p/m "; + let command = "cprint/m "; command += name; //console.log("evalExpression(): ", command); // DUBNERDEBUG return await this.sendStraightCommand(command); @@ -1081,6 +1081,7 @@ export class MI2 extends EventEmitter implements IBackend { } else resolve(node); }; + //console.log("<command> " + sel + command); // DUBNERDEBUG this.sendRaw(sel + command); }); } @@ -1104,5 +1105,5 @@ export class MI2 extends EventEmitter implements IBackend { protected process: ChildProcess.ChildProcess; protected stream; protected sshConn; - protected recent_variables_request: number; // Most recent MI token for 'p/m ?' variables request + protected recent_variables_request: number; // Most recent MI token for 'cprint/m ?' variables request } diff --git a/CblGdbExt/CblGdb/src/mibase.ts b/CblGdbExt/CblGdb/src/mibase.ts index 63b2ba0c74822571b317103fadd520fa541c161c..da30a01bab892916aef4794f2996a2c8a1d7cf59 100644 --- a/CblGdbExt/CblGdb/src/mibase.ts +++ b/CblGdbExt/CblGdb/src/mibase.ts @@ -637,8 +637,13 @@ export class MI2DebugSession extends DebugSession { protected evaluateRequest(response: DebugProtocol.EvaluateResponse, args: DebugProtocol.EvaluateArguments): void { const [threadId, level] = this.frameIdToThreadAndLevel(args.frameId); - if (args.context == "watch" || args.context == "hover") { // Hover is too hard for the moment. 2020-08-06 RJD - if (args.context == "watch") { + if (args.context == "watch" || args.context == "hover") { + if (args.context == "watch" ) { // Hover is too hard for the moment. 2020-08-06 RJDUBNER + // Showing a variable on hover is much-requested, and I understand why. However, the + // VSC library routines that provide the expression to be evaluated interpret dash + // as a separator. So, hovering over "custmas-ctr" will show up here as "custmas" or + // "ctr". I haven't been able to figure out how to determine that the contiguous + // characters behind either of them are "custmas-ctr". So, we are out of luck on hovering. this.miDebugger.evalExpression(args.expression, threadId, level).then((res) => { response.body = { variablesReference: 0, diff --git a/CblGdbExt/samples/Makefile.inc b/CblGdbExt/samples/Makefile.inc index ac01aa6c0b8adbe2dfcfd42eab6f2afc1701d5ce..4a7e30696ced31f310e555dcfb37ad6756b87ff9 100644 --- a/CblGdbExt/samples/Makefile.inc +++ b/CblGdbExt/samples/Makefile.inc @@ -9,7 +9,7 @@ all: $(project) $(project) : $(project).cbl - COBCDFLAGS=$(COBCDFLAGS) COBCDXM=-x cobcd $< + COBCDFLAGS=$(COBCDFLAGS) cobcd -x $< # This cleans up the various project files, along with any additional # $(CLEAN) files specified by the parent Makefile It also clobbers any