diff --git a/shell/browser/api/electron_api_content_tracing.cc b/shell/browser/api/electron_api_content_tracing.cc index 6eaf1c69c1..8b19e08f26 100644 --- a/shell/browser/api/electron_api_content_tracing.cc +++ b/shell/browser/api/electron_api_content_tracing.cc @@ -151,7 +151,10 @@ void OnTraceBufferUsageAvailable( gin_helper::Promise promise, float percent_full, size_t approximate_count) { - auto dict = gin_helper::Dictionary::CreateEmpty(promise.isolate()); + v8::Isolate* isolate = promise.isolate(); + v8::HandleScope handle_scope(isolate); + + auto dict = gin_helper::Dictionary::CreateEmpty(isolate); dict.Set("percentage", percent_full); dict.Set("value", approximate_count); diff --git a/spec/api-content-tracing-spec.ts b/spec/api-content-tracing-spec.ts index 102d5e3697..c18edaf348 100644 --- a/spec/api-content-tracing-spec.ts +++ b/spec/api-content-tracing-spec.ts @@ -132,6 +132,36 @@ ifdescribe(!(['arm', 'arm64'].includes(process.arch)) || (process.platform !== ' }); }); + describe('getTraceBufferUsage', function () { + this.timeout(10e3); + + it('does not crash and returns valid usage data', async () => { + await app.whenReady(); + await contentTracing.startRecording({ + categoryFilter: '*', + traceOptions: 'record-until-full' + }); + + // Yield to the event loop so the JS HandleScope from this tick is gone. + // When the Mojo response arrives it fires OnTraceBufferUsageAvailable + // as a plain Chromium task — if that callback lacks its own HandleScope + // the process will crash with "Cannot create a handle without a HandleScope". + const result = await contentTracing.getTraceBufferUsage(); + + expect(result).to.have.property('percentage').that.is.a('number'); + expect(result).to.have.property('value').that.is.a('number'); + + await contentTracing.stopRecording(); + }); + + it('returns zero usage when no trace is active', async () => { + await app.whenReady(); + const result = await contentTracing.getTraceBufferUsage(); + expect(result).to.have.property('percentage').that.is.a('number'); + expect(result.percentage).to.equal(0); + }); + }); + describe('captured events', () => { it('include V8 samples from the main process', async function () { this.timeout(60000);