From b35a8fd57059b0d09e06b38684ee8094c24ad9c0 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 29 Jan 2018 21:55:29 +0200 Subject: [PATCH] fix(debug): debug-brk option does not work for iOS Simulator The `debug-brk` option was broken in a previous commit as we were trying to connect to the backend port (18181). The problem is that connecting to it makes the runtime thinks debugger is attached and it continues to next statements. Instead of connecting to the port, check if it is in LISTEN state. --- lib/common | 2 +- lib/services/ios-debug-service.ts | 50 +++++++++++++++--------------- test/services/ios-debug-service.ts | 8 +++-- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/lib/common b/lib/common index 1ae842e048..623c2d8afc 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 1ae842e048cf4731d0b0f8ac8d3b971b9e832f51 +Subproject commit 623c2d8afc376f726f1c2ecb784eef667398a395 diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index 7da63432f4..28fbdc643d 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -32,7 +32,8 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS private $iOSNotification: IiOSNotification, private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor, private $processService: IProcessService, - private $socketProxyFactory: ISocketProxyFactory) { + private $socketProxyFactory: ISocketProxyFactory, + private $net: INet) { super(device, $devicesService); this.$processService.attachToProcessExitSignals(this, this.debugStop); this.$socketProxyFactory.on(CONNECTION_ERROR_EVENT_NAME, (e: Error) => this.emit(CONNECTION_ERROR_EVENT_NAME, e)); @@ -125,29 +126,28 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS const lineStream = byline(child_process.stdout); this._childProcess = child_process; - await new Promise((resolve: () => void, reject) => { - lineStream.on('data', (line: NodeBuffer) => { - const lineText = line.toString(); - if (lineText && _.startsWith(lineText, debugData.applicationIdentifier)) { - const pid = getPidFromiOSSimulatorLogs(debugData.applicationIdentifier, lineText); - if (!pid) { - this.$logger.trace(`Line ${lineText} does not contain PID of the application ${debugData.applicationIdentifier}.`); - return; - } - - this._lldbProcess = this.$childProcess.spawn("lldb", ["-p", pid]); - if (log4js.levels.TRACE.isGreaterThanOrEqualTo(this.$logger.getLevel())) { - this._lldbProcess.stdout.pipe(process.stdout); - } - this._lldbProcess.stderr.pipe(process.stderr); - this._lldbProcess.stdin.write("process continue\n"); - this.connectToApplicationOnEmulator(debugData.deviceIdentifier).then(resolve, reject); - } else { - process.stdout.write(line + "\n"); + lineStream.on('data', (line: NodeBuffer) => { + const lineText = line.toString(); + if (lineText && _.startsWith(lineText, debugData.applicationIdentifier)) { + const pid = getPidFromiOSSimulatorLogs(debugData.applicationIdentifier, lineText); + if (!pid) { + this.$logger.trace(`Line ${lineText} does not contain PID of the application ${debugData.applicationIdentifier}.`); + return; } - }); + + this._lldbProcess = this.$childProcess.spawn("lldb", ["-p", pid]); + if (log4js.levels.TRACE.isGreaterThanOrEqualTo(this.$logger.getLevel())) { + this._lldbProcess.stdout.pipe(process.stdout); + } + this._lldbProcess.stderr.pipe(process.stderr); + this._lldbProcess.stdin.write("process continue\n"); + } else { + process.stdout.write(line + "\n"); + } }); + await this.waitForBackendPortToBeOpened(debugData.deviceIdentifier); + return this.wireDebuggerClient(debugData, debugOptions); } @@ -158,13 +158,13 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS const iOSEmulatorService = this.$iOSEmulatorServices; await iOSEmulatorService.postDarwinNotification(attachRequestMessage); - await this.connectToApplicationOnEmulator(debugData.deviceIdentifier); + await this.waitForBackendPortToBeOpened(debugData.deviceIdentifier); return result; } - private async connectToApplicationOnEmulator(deviceIdentifier: string): Promise { - const socket = await this.$iOSEmulatorServices.connectToPort({ port: inspectorBackendPort }); - if (!socket) { + private async waitForBackendPortToBeOpened(deviceIdentifier: string): Promise { + const portListens = await this.$net.waitForPortToListen({ port: inspectorBackendPort, timeout: 10000, interval: 200 }); + if (!portListens) { const error = new Error("Unable to connect to application. Ensure application is running on simulator."); error.deviceIdentifier = deviceIdentifier; throw error; diff --git a/test/services/ios-debug-service.ts b/test/services/ios-debug-service.ts index 8926cca137..03408bb57b 100644 --- a/test/services/ios-debug-service.ts +++ b/test/services/ios-debug-service.ts @@ -17,9 +17,10 @@ class IOSDebugServiceInheritor extends IOSDebugService { $iOSNotification: IiOSNotification, $iOSSocketRequestExecutor: IiOSSocketRequestExecutor, $processService: IProcessService, - $socketProxyFactory: ISocketProxyFactory) { + $socketProxyFactory: ISocketProxyFactory, + $net: INet) { super({}, $devicesService, $platformService, $iOSEmulatorServices, $childProcess, $hostInfo, $logger, $errors, - $npmInstallationManager, $iOSNotification, $iOSSocketRequestExecutor, $processService, $socketProxyFactory); + $npmInstallationManager, $iOSNotification, $iOSSocketRequestExecutor, $processService, $socketProxyFactory, $net); } public getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string { @@ -49,7 +50,8 @@ const createTestInjector = (): IInjector => { }); testInjector.register("net", { - getAvailablePortInRange: async (startPort: number, endPort?: number): Promise => 41000 + getAvailablePortInRange: async (startPort: number, endPort?: number): Promise => 41000, + waitForPortToListen: async (opts: { port: number, timeout: number, interval?: number }): Promise => true }); return testInjector;