static void Main(string[] args) { if (args.Length < 1) { Console.Error.WriteLine("Usage: jsdbg [extensions directory]"); return; } string extensionsDirectory = args[0]; // This process has been started by python, stdio talks back to python and asks it // to look up type data, read memory, etc. It also receives events from Python // (e.g. program hit a break point). StdioDebugger debugger = new StdioDebugger(); PersistentStore persistentStore = new PersistentStore(); using (WebServer webServer = new WebServer(debugger, persistentStore, extensionsDirectory)) { // Turn off printing of debugger messages, because they fill up the gdb console too quick. webServer.PrintDebuggerMessages = false; webServer.LoadExtension("default"); try { // Because Ctrl+C is used by GDB to break into the program, // we should not exit the server when that happens. Console.CancelKeyPress += (sender, eventArgs) => { eventArgs.Cancel = true; }; var serverTask = webServer.Listen().ContinueWith(async(Task result) => { await Task.Delay(500); }); // Run the debugger. If the debugger ends, kill the web server. debugger.Run(webServer.Url).ContinueWith((Task result) => { webServer.Abort(); }); serverTask.Wait(); } catch (Exception ex) { Console.Error.WriteLine("Shutting down due to exception: {0}\n{1}", ex.Message, ex.StackTrace); } } }
static int Main(string[] args) { Configuration configuration = null; try { configuration = Configuration.Load(); } catch { Console.WriteLine("The configuration.json file could not be read. Please ensure that it is present in\n\n {1}\n\nand has the following schema:\n\n{0}\n", Configuration.Schema, Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)); Console.Write("Press any key to exit..."); Console.ReadKey(); return(-1); } string remoteString; if (args.Length < 1 || args[0] == "/ask") { // A debugger string wasn't specified. Prompt for a debug string instead. Console.WriteLine("You can run the following command to create a remote debugging server in WinDbg: '.server npipe:pipe=jsdbg'"); Console.Write("Please specify a debug remote string (e.g. npipe:Pipe=foo,Server=bar):"); remoteString = Console.ReadLine().Trim(); if (remoteString.StartsWith("-remote ")) { remoteString = remoteString.Substring("-remote ".Length).Trim(); } if (remoteString.Length == 0) { return(-1); } } else { remoteString = args[0]; } DebuggerRunner runner; try { Console.Write("Connecting to a debug session at {0}...", remoteString); runner = new DebuggerRunner(remoteString); Console.WriteLine("Connected."); } catch (Exception ex) { Console.WriteLine("Failed: {0}", ex.Message); Console.Write("Press any key to exit..."); Console.ReadKey(); return(-1); } PersistentStore persistentStore = new PersistentStore(); using (WebServer webServer = new WebServer(runner.Debugger, persistentStore, configuration.ExtensionRoot)) { webServer.LoadExtension("default"); SynchronizationContext previousContext = SynchronizationContext.Current; try { SingleThreadSynchronizationContext syncContext = new SingleThreadSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(syncContext); // Run the debugger. If the debugger ends, kill the web server. runner.Run().ContinueWith((Task result) => { webServer.Abort(); }); // The web server ending kills the debugger and completes our SynchronizationContext which allows us to exit. webServer.Listen().ContinueWith(async(Task result) => { await runner.Shutdown(); await Task.Delay(500); syncContext.Complete(); }); JsDbg.Remoting.RemotingServer.RegisterNewInstance(remoteString, () => { BrowserLauncher.Launch(webServer.Url); }); BrowserLauncher.Launch(webServer.Url); // Pressing ctrl-c kills the web server. Task.Run(() => ReadKeysUntilAbort(webServer.Url)).ContinueWith((Task result) => { Console.WriteLine("Shutting down..."); webServer.Abort(); }); // Process requests until the web server is taken down. syncContext.RunOnCurrentThread(); } catch (Exception ex) { Console.WriteLine("Shutting down due to exception: {0}", ex.Message); } finally { SynchronizationContext.SetSynchronizationContext(previousContext); } } return(0); }