Re-throw exception on main thread in PROXY_TO_PTHREAD mode

Without this, an exception on the prozied main thread will
be swallows and the browser main (or node main) thread will
just keep running.
diff --git a/emcc.py b/emcc.py
index 8d6f8f4..27a6fd9 100755
--- a/emcc.py
+++ b/emcc.py
@@ -1615,7 +1615,7 @@
         building.user_requested_exports += ['exit']
 
       if shared.Settings.PROXY_TO_PTHREAD:
-        shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_proxy_main']
+        shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_proxy_main', '_emscripten_proxy_main_thread_id']
 
       # pthread stack setup and other necessary utilities
       def include_and_export(name):
diff --git a/src/library_pthread.js b/src/library_pthread.js
index e9816bb..cc9914c 100644
--- a/src/library_pthread.js
+++ b/src/library_pthread.js
@@ -8,6 +8,9 @@
   $PThread__postset: 'if (!ENVIRONMENT_IS_PTHREAD) PThread.initMainThreadBlock();',
   $PThread__deps: ['_emscripten_thread_init',
                    'emscripten_register_main_browser_thread_id',
+#if PROXY_TO_PTHREAD
+                   'emscripten_proxy_main_thread_id',
+#endif
                    '$ERRNO_CODES', 'emscripten_futex_wake', '$killThread',
                    '$cancelThread', '$cleanupThread',
 #if USE_ASAN || USE_LSAN
@@ -369,6 +372,14 @@
 
       worker.onerror = function(e) {
         err('pthread sent an error! ' + e.filename + ':' + e.lineno + ': ' + e.message);
+#if PROXY_TO_PTHREAD
+        // If the worker running the main thread generates an error, we want
+        // it to take down the main browser thread too.  Especially on node
+        // we want the process to exit in that case.
+        if (worker.pthread && worker.pthread.thread === _emscripten_proxy_main_thread_id()) {
+          throw e;
+        }
+#endif
       };
 
 #if ENVIRONMENT_MAY_BE_NODE
diff --git a/system/include/emscripten/threading.h b/system/include/emscripten/threading.h
index aaf02b0..cf04619 100644
--- a/system/include/emscripten/threading.h
+++ b/system/include/emscripten/threading.h
@@ -363,6 +363,8 @@
 
 pthread_t emscripten_main_browser_thread_id(void);
 
+pthread_t emscripten_proxy_main_thread_id(void);
+
 // Synchronously sleeps the calling thread for the given number of milliseconds.
 // Note: Calling this on the main browser thread is _very_ _very_ bad for
 // application logic throttling, because it does not save any battery, it will
diff --git a/system/lib/pthread/library_pthread.c b/system/lib/pthread/library_pthread.c
index 415b31e..e62d87f 100644
--- a/system/lib/pthread/library_pthread.c
+++ b/system/lib/pthread/library_pthread.c
@@ -911,17 +911,22 @@
 // the main thread is waiting, we wake it up before waking up any workers.
 EMSCRIPTEN_KEEPALIVE void* _emscripten_main_thread_futex;
 
+static pthread_t _main_thread;
 static int _main_argc;
 static char** _main_argv;
 
 extern int __call_main(int argc, char** argv);
 
-static void* _main_thread(void* param) {
+static void* _main_thread_entry(void* param) {
   // This is the main runtime thread for the application.
   emscripten_set_thread_name(pthread_self(), "Application main thread");
   return (void*)__call_main(_main_argc, _main_argv);
 }
 
+pthread_t emscripten_proxy_main_thread_id() {
+  return _main_thread;
+}
+
 int emscripten_proxy_main(int argc, char** argv) {
   pthread_attr_t attr;
   pthread_attr_init(&attr);
@@ -934,8 +939,7 @@
   emscripten_pthread_attr_settransferredcanvases(&attr, (const char*)-1);
   _main_argc = argc;
   _main_argv = argv;
-  pthread_t thread;
-  int rc = pthread_create(&thread, &attr, _main_thread, NULL);
+  int rc = pthread_create(&_main_thread, &attr, _main_thread_entry, NULL);
   pthread_attr_destroy(&attr);
   return rc;
 }
diff --git a/tests/core/pthread/test_proxy_to_pthread_exception.c b/tests/core/pthread/test_proxy_to_pthread_exception.c
new file mode 100644
index 0000000..e747f2e
--- /dev/null
+++ b/tests/core/pthread/test_proxy_to_pthread_exception.c
@@ -0,0 +1,6 @@
+#include <emscripten.h>
+
+int main() {
+  EM_ASM(missingFunc());
+  return 0;
+}
diff --git a/tests/core/pthread/test_proxy_to_pthread_exception.out b/tests/core/pthread/test_proxy_to_pthread_exception.out
new file mode 100644
index 0000000..1e80697
--- /dev/null
+++ b/tests/core/pthread/test_proxy_to_pthread_exception.out
@@ -0,0 +1 @@
+ReferenceError: missingFunc is not defined
diff --git a/tests/test_core.py b/tests/test_core.py
index e48211f..c69b993 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -8117,6 +8117,12 @@
     self.emcc_args += ['--pre-js', path_from_root('tests', 'core', 'pthread', 'test_pthread_exit_runtime.pre.js')]
     self.do_run_in_out_file_test('tests', 'core', 'pthread', 'test_pthread_exit_runtime.c', assert_returncode=43)
 
+  @node_pthreads
+  def test_proxy_to_pthread_exception(self):
+    self.set_setting('PROXY_TO_PTHREAD')
+    self.set_setting('PTHREAD_POOL_SIZE', '1')
+    self.do_run_in_out_file_test('tests', 'core', 'pthread', 'test_proxy_to_pthread_exception.c', assert_returncode=NON_ZERO)
+
   def test_emscripten_atomics_stub(self):
     self.do_run_in_out_file_test('tests', 'core', 'pthread', 'emscripten_atomics.c')