diff --git a/src/GDBDebugSession.ts b/src/GDBDebugSession.ts index ababf773..736c9051 100644 --- a/src/GDBDebugSession.ts +++ b/src/GDBDebugSession.ts @@ -338,15 +338,19 @@ export class GDBDebugSession extends LoggingDebugSession { ); await this.spawn(args); - if (!args.program) { - this.sendErrorResponse( - response, - 1, - 'The program must be specified in the request arguments' - ); - return; + if (request == 'launch') { + if (!args.program) { + this.sendErrorResponse( + response, + 1, + 'The program must be specified in the request arguments' + ); + return; + } + } + if (args.program) { + await this.gdb.sendFileExecAndSymbols(args.program); } - await this.gdb.sendFileExecAndSymbols(args.program); await this.gdb.sendEnablePrettyPrint(); if (request === 'attach') { @@ -997,7 +1001,7 @@ export class GDBDebugSession extends LoggingDebugSession { } response.body = { allThreadsContinued: isAllThreadsContinued, - } + }; this.sendResponse(response); } catch (err) { this.sendErrorResponse( diff --git a/src/GDBTargetDebugSession.ts b/src/GDBTargetDebugSession.ts index 2f2e33d6..638ca419 100644 --- a/src/GDBTargetDebugSession.ts +++ b/src/GDBTargetDebugSession.ts @@ -275,7 +275,9 @@ export class GDBTargetDebugSession extends GDBDebugSession { try { this.isAttach = true; await this.spawn(args); - await this.gdb.sendFileExecAndSymbols(args.program); + if (args.program) { + await this.gdb.sendFileExecAndSymbols(args.program); + } await this.gdb.sendEnablePrettyPrint(); if (args.imageAndSymbols) { if (args.imageAndSymbols.symbolFileName) { diff --git a/src/integration-tests/attach.spec.ts b/src/integration-tests/attach.spec.ts index 4f76b7dc..63d6dba5 100644 --- a/src/integration-tests/attach.spec.ts +++ b/src/integration-tests/attach.spec.ts @@ -51,4 +51,17 @@ describe('attach', function () { await dc.attachHitBreakpoint(attachArgs, { line: 25, path: src }); expect(await dc.evaluate('argv[1]')).to.contain('running-from-spawn'); }); + + it('can attach and hit a breakpoint with no program specified', async function () { + if (isRemoteTest) { + // attachRemote.spec.ts is the test for when isRemoteTest + this.skip(); + } + + const attachArgs = fillDefaults(this.test, { + processId: `${inferior.pid}`, + } as AttachRequestArguments); + await dc.attachHitBreakpoint(attachArgs, { line: 25, path: src }); + expect(await dc.evaluate('argv[1]')).to.contain('running-from-spawn'); + }); }); diff --git a/src/integration-tests/attachRemote.spec.ts b/src/integration-tests/attachRemote.spec.ts index ef9c53b8..499366ab 100644 --- a/src/integration-tests/attachRemote.spec.ts +++ b/src/integration-tests/attachRemote.spec.ts @@ -74,4 +74,15 @@ describe('attach remote', function () { await dc.attachHitBreakpoint(attachArgs, { line: 3, path: emptySrc }); expect(await dc.evaluate('argv[1]')).to.contain('running-from-spawn'); }); + + it('can attach remote and hit a breakpoint without a program', async function () { + const attachArgs = fillDefaults(this.test, { + target: { + type: 'remote', + parameters: [`localhost:${port}`], + } as TargetAttachArguments, + } as TargetAttachRequestArguments); + await dc.attachHitBreakpoint(attachArgs, { line: 3, path: emptySrc }); + expect(await dc.evaluate('argv[1]')).to.contain('running-from-spawn'); + }); });