From 74500746af4cef96a2e2ae27d4dd064f49d6cd83 Mon Sep 17 00:00:00 2001 From: Omar Elkhouly Date: Thu, 7 May 2026 17:22:38 +0200 Subject: [PATCH 1/6] sending a memory event on memory-changed notification --- src/gdb/GDBDebugSessionBase.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/gdb/GDBDebugSessionBase.ts b/src/gdb/GDBDebugSessionBase.ts index 779b44d5..08c735bf 100644 --- a/src/gdb/GDBDebugSessionBase.ts +++ b/src/gdb/GDBDebugSessionBase.ts @@ -18,6 +18,7 @@ import { Logger, logger, LoggingDebugSession, + MemoryEvent, OutputEvent, Scope, Source, @@ -3167,6 +3168,14 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession { case 'cmd-param-changed': this.handleCmdParamChanged(notifyData); break; + case 'memory-changed': + const memoryEvent = new MemoryEvent( + notifyData.addr, + 0, + parseInt(notifyData.len) + ); + this.sendEvent(memoryEvent); + break; default: logger.warn( `GDB unhandled notify: ${notifyClass}: ${JSON.stringify( From b807683f05e2cda46f48e2bc70382d449d327582 Mon Sep 17 00:00:00 2001 From: Omar Elkhouly Date: Thu, 7 May 2026 18:01:23 +0200 Subject: [PATCH 2/6] updating tests to include testing memory events --- src/integration-tests/mem.spec.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/integration-tests/mem.spec.ts b/src/integration-tests/mem.spec.ts index e41a3466..a6b5e2bc 100644 --- a/src/integration-tests/mem.spec.ts +++ b/src/integration-tests/mem.spec.ts @@ -199,6 +199,27 @@ describe('Memory Test Suite', function () { verifyReadMemoryResponse(memory, newValue, addrOfArray); }); + it('can write memory and handle memory notifications from gdb', async function () { + const addrOfArray = parseInt( + ( + await dc.evaluateRequest({ + expression: '&array[0]', + frameId: frame.id, + }) + ).body.result + ); + const memoryEvent = dc.waitForEvent('memory'); + await dc.evaluateRequest({ + expression: '>set array[0] = 0xde', + frameId: frame.id, + context: 'repl', + }); + //await dc.writeMemoryRequest(writeArguments); + const output = await memoryEvent; + expect(parseInt(output.body.memoryReference)).eq(addrOfArray); + expect(output.body.count).eq(1); + }); + it('fails when trying to write to read-only memory', async function () { const addrOfArray = parseInt( ( From 56ba4c8ec962b863f9bf16c37633a1bc859e859c Mon Sep 17 00:00:00 2001 From: Omar Elkhouly Date: Thu, 7 May 2026 18:14:58 +0200 Subject: [PATCH 3/6] adding curly braces around case scope and removing unneeded code --- src/gdb/GDBDebugSessionBase.ts | 5 +++-- src/integration-tests/mem.spec.ts | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gdb/GDBDebugSessionBase.ts b/src/gdb/GDBDebugSessionBase.ts index 08c735bf..5cc62d80 100644 --- a/src/gdb/GDBDebugSessionBase.ts +++ b/src/gdb/GDBDebugSessionBase.ts @@ -3168,14 +3168,15 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession { case 'cmd-param-changed': this.handleCmdParamChanged(notifyData); break; - case 'memory-changed': + case 'memory-changed': { const memoryEvent = new MemoryEvent( notifyData.addr, 0, parseInt(notifyData.len) ); this.sendEvent(memoryEvent); - break; + break; + } default: logger.warn( `GDB unhandled notify: ${notifyClass}: ${JSON.stringify( diff --git a/src/integration-tests/mem.spec.ts b/src/integration-tests/mem.spec.ts index a6b5e2bc..07b10de0 100644 --- a/src/integration-tests/mem.spec.ts +++ b/src/integration-tests/mem.spec.ts @@ -214,7 +214,6 @@ describe('Memory Test Suite', function () { frameId: frame.id, context: 'repl', }); - //await dc.writeMemoryRequest(writeArguments); const output = await memoryEvent; expect(parseInt(output.body.memoryReference)).eq(addrOfArray); expect(output.body.count).eq(1); From 6e1131f58aa45d00bee8c8813fad970c224cb612 Mon Sep 17 00:00:00 2001 From: Omar Elkhouly Date: Fri, 8 May 2026 08:34:38 +0200 Subject: [PATCH 4/6] protecting parseInt function --- src/gdb/GDBDebugSessionBase.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gdb/GDBDebugSessionBase.ts b/src/gdb/GDBDebugSessionBase.ts index 5cc62d80..3f26f1ac 100644 --- a/src/gdb/GDBDebugSessionBase.ts +++ b/src/gdb/GDBDebugSessionBase.ts @@ -3169,10 +3169,11 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession { this.handleCmdParamChanged(notifyData); break; case 'memory-changed': { + const length = isNaN(notifyData.len) ? 0 : parseInt(notifyData.len, 10); const memoryEvent = new MemoryEvent( notifyData.addr, 0, - parseInt(notifyData.len) + length ); this.sendEvent(memoryEvent); break; From c2dab69d609e92434fe6380b2735be4dfba40f21 Mon Sep 17 00:00:00 2001 From: Omar Elkhouly Date: Fri, 8 May 2026 08:35:31 +0200 Subject: [PATCH 5/6] running prettier --- src/gdb/GDBDebugSessionBase.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/gdb/GDBDebugSessionBase.ts b/src/gdb/GDBDebugSessionBase.ts index 3f26f1ac..95fea27c 100644 --- a/src/gdb/GDBDebugSessionBase.ts +++ b/src/gdb/GDBDebugSessionBase.ts @@ -3169,12 +3169,10 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession { this.handleCmdParamChanged(notifyData); break; case 'memory-changed': { - const length = isNaN(notifyData.len) ? 0 : parseInt(notifyData.len, 10); - const memoryEvent = new MemoryEvent( - notifyData.addr, - 0, - length - ); + const length = isNaN(notifyData.len) + ? 0 + : parseInt(notifyData.len, 10); + const memoryEvent = new MemoryEvent(notifyData.addr, 0, length); this.sendEvent(memoryEvent); break; } From 204dfa1e816aa238487e9ffed4b0fb934fb16685 Mon Sep 17 00:00:00 2001 From: Omar Elkhouly Date: Fri, 8 May 2026 11:21:56 +0200 Subject: [PATCH 6/6] sending a warning message if length is 0 --- src/gdb/GDBDebugSessionBase.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gdb/GDBDebugSessionBase.ts b/src/gdb/GDBDebugSessionBase.ts index 95fea27c..fe13eab5 100644 --- a/src/gdb/GDBDebugSessionBase.ts +++ b/src/gdb/GDBDebugSessionBase.ts @@ -3169,9 +3169,13 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession { this.handleCmdParamChanged(notifyData); break; case 'memory-changed': { - const length = isNaN(notifyData.len) - ? 0 - : parseInt(notifyData.len, 10); + let length = 0; + if (isNaN(notifyData.len)) { + logger.warn( + `GDB notify "memory-changed" has invalid length: ${notifyData.len}` + ); + } + length = parseInt(notifyData.len); const memoryEvent = new MemoryEvent(notifyData.addr, 0, length); this.sendEvent(memoryEvent); break;