cdt-gdb-adapter
Advanced tools
Comparing version 0.0.18 to 0.0.19-next.20230201033307.6d71ff0.0
@@ -69,3 +69,3 @@ import { DebugClient } from '@vscode/debugadapter-testsupport'; | ||
}): Promise<DebugProtocol.StackTraceResponse>; | ||
waitForOutputEvent(category: string, timeout?: number): Promise<DebugProtocol.OutputEvent>; | ||
waitForOutputEvent(category: string, output?: string, timeout?: number): Promise<DebugProtocol.OutputEvent>; | ||
/** | ||
@@ -72,0 +72,0 @@ * Send a response following a Debug Adapter Reverse Request. |
@@ -180,6 +180,7 @@ "use strict"; | ||
/* | ||
* Returns a promise that will resolve if an output event with a specific category was received. | ||
* Returns a promise that will resolve if an output event | ||
* with a specific category and optional output message was received. | ||
* The promise will be rejected if a timeout occurs. | ||
*/ | ||
waitForOutputEvent(category, timeout = this.defaultTimeout) { | ||
waitForOutputEvent(category, output, timeout = this.defaultTimeout) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -190,15 +191,20 @@ const isOutputEvent = (event) => { | ||
}; | ||
const timer = setTimeout(() => { | ||
throw new Error(`no output event with category '${category}' received after ${timeout} ms`); | ||
}, timeout); | ||
for (;;) { | ||
const event = yield new Promise((resolve) => this.once('output', (e) => resolve(e))); | ||
if (!isOutputEvent(event)) { | ||
continue; | ||
} | ||
if (event.body.category === category) { | ||
clearTimeout(timer); | ||
return event; | ||
} | ||
} | ||
return new Promise((resolve, reject) => { | ||
const outputProcessor = (event) => { | ||
if (isOutputEvent(event) && event.body.category === category) { | ||
if (output === undefined || output === event.body.output) { | ||
clearTimeout(timer); | ||
this.off('output', outputProcessor); | ||
resolve(event); | ||
} | ||
} | ||
}; | ||
const timer = setTimeout(() => { | ||
this.off('output', outputProcessor); | ||
reject(new Error(`no output event with category '${category}' ${output === undefined | ||
? '' | ||
: `and output message '${output}'`} received after ${timeout} ms`)); | ||
}, timeout); | ||
this.on('output', outputProcessor); | ||
}); | ||
}); | ||
@@ -205,0 +211,0 @@ } |
@@ -76,23 +76,79 @@ "use strict"; | ||
const stack = yield dc.stackTraceRequest({ threadId }); | ||
let frameId = undefined; | ||
let printHelloFrameId = undefined; | ||
let callerFrameId = undefined; | ||
for (const frame of stack.body.stackFrames) { | ||
if (frame.name === 'PrintHello') { | ||
frameId = frame.id; | ||
printHelloFrameId = frame.id; | ||
} | ||
else if (printHelloFrameId !== undefined) { | ||
callerFrameId = frame.id; | ||
break; | ||
} | ||
} | ||
if (frameId === undefined) { | ||
if (printHelloFrameId === undefined) { | ||
(0, assert_1.fail)("Failed to find frame with name 'PrintHello'"); | ||
} | ||
const scopes = yield dc.scopesRequest({ frameId }); | ||
const vr = scopes.body.scopes[0].variablesReference; | ||
const vars = yield dc.variablesRequest({ variablesReference: vr }); | ||
const varnameToValue = new Map(vars.body.variables.map((variable) => [ | ||
variable.name, | ||
variable.value, | ||
])); | ||
(0, chai_1.expect)(varnameToValue.get('thread_id')).to.equal(idInProgram.toString()); | ||
// The "name" variable is a pointer, so is displayed as an address + the | ||
// extracted nul terminated string | ||
(0, chai_1.expect)(varnameToValue.get('name')).to.contain(name); | ||
if (callerFrameId === undefined) { | ||
(0, assert_1.fail)("Failed to find frame that called 'PrintHello'"); | ||
} | ||
{ | ||
const scopes = yield dc.scopesRequest({ | ||
frameId: callerFrameId, | ||
}); | ||
const vr = scopes.body.scopes[0].variablesReference; | ||
const vars = yield dc.variablesRequest({ | ||
variablesReference: vr, | ||
}); | ||
const varnameToValue = new Map(vars.body.variables.map((variable) => [ | ||
variable.name, | ||
variable.value, | ||
])); | ||
// Make sure we aren't getting the HelloWorld frame's variables. | ||
// The calling method (in glibc or similar) may end up with a local | ||
// variable called thread_id, if so, update this heuristic | ||
(0, chai_1.expect)(varnameToValue.get('thread_id')).to.be.undefined; | ||
} | ||
{ | ||
const scopes = yield dc.scopesRequest({ | ||
frameId: printHelloFrameId, | ||
}); | ||
const vr = scopes.body.scopes[0].variablesReference; | ||
const vars = yield dc.variablesRequest({ | ||
variablesReference: vr, | ||
}); | ||
const varnameToValue = new Map(vars.body.variables.map((variable) => [ | ||
variable.name, | ||
variable.value, | ||
])); | ||
(0, chai_1.expect)(varnameToValue.get('thread_id')).to.equal(idInProgram.toString()); | ||
// The "name" variable is a pointer, so is displayed as an address + the | ||
// extracted nul terminated string | ||
(0, chai_1.expect)(varnameToValue.get('name')).to.contain(name); | ||
} | ||
{ | ||
// Make sure we can get variables for frame 0, | ||
// the contents of those variables don't actually matter | ||
// as the thread will probably be stopped in a library | ||
// somewhere waiting for a semaphore | ||
// This is a test for #235 | ||
const scopes = yield dc.scopesRequest({ | ||
frameId: stack.body.stackFrames[0].id, | ||
}); | ||
const vr = scopes.body.scopes[0].variablesReference; | ||
const vars = yield dc.variablesRequest({ | ||
variablesReference: vr, | ||
}); | ||
const varnameToValue = new Map(vars.body.variables.map((variable) => [ | ||
variable.name, | ||
variable.value, | ||
])); | ||
// Make sure we aren't getting the HelloWorld frame's variables. | ||
// The calling method (in glibc or similar) may end up with a local | ||
// variable called thread_id, if so, update this heuristic | ||
// We could be stopped PrintHello, so we don't perform the check | ||
// if that is the case | ||
if (stack.body.stackFrames[0].id !== printHelloFrameId) { | ||
(0, chai_1.expect)(varnameToValue.get('thread_id')).to.be.undefined; | ||
} | ||
} | ||
} | ||
@@ -99,0 +155,0 @@ }); |
@@ -6,3 +6,3 @@ "use strict"; | ||
let command = '-stack-info-depth'; | ||
if (params.threadId) { | ||
if (params.threadId !== undefined) { | ||
command += ` --thread ${params.threadId}`; | ||
@@ -18,3 +18,3 @@ } | ||
let command = '-stack-list-frames'; | ||
if (params.threadId) { | ||
if (params.threadId !== undefined) { | ||
command += ` --thread ${params.threadId}`; | ||
@@ -46,6 +46,6 @@ } | ||
} | ||
if (params.thread) { | ||
if (params.thread !== undefined) { | ||
command += ` --thread ${params.thread}`; | ||
} | ||
if (params.frame) { | ||
if (params.frame !== undefined) { | ||
command += ` --frame ${params.frame}`; | ||
@@ -52,0 +52,0 @@ } |
{ | ||
"name": "cdt-gdb-adapter", | ||
"version": "0.0.18", | ||
"version": "0.0.19-next.20230201033307.6d71ff0.0", | ||
"description": "gdb adapter implementing the debug adapter protocol", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -29,3 +29,3 @@ /********************************************************************* | ||
let command = '-stack-info-depth'; | ||
if (params.threadId) { | ||
if (params.threadId !== undefined) { | ||
command += ` --thread ${params.threadId}`; | ||
@@ -51,3 +51,3 @@ } | ||
let command = '-stack-list-frames'; | ||
if (params.threadId) { | ||
if (params.threadId !== undefined) { | ||
command += ` --thread ${params.threadId}`; | ||
@@ -93,6 +93,6 @@ } | ||
} | ||
if (params.thread) { | ||
if (params.thread !== undefined) { | ||
command += ` --thread ${params.thread}`; | ||
} | ||
if (params.frame) { | ||
if (params.frame !== undefined) { | ||
command += ` --frame ${params.frame}`; | ||
@@ -99,0 +99,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 7 instances in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 7 instances in 1 package
736457
11846