Skip to content

Feature suggestion: C++ exception formatting #16326

@hoodmane

Description

@hoodmane

If there is an uncaught C++ exception, it prints a message like Uncaught 13777136, which isn't super useful. I want a function to convert the pointer into a more user friendly message like:
CppException myexception: My exception happened
or:
CppException int: An object of type int at address 15738976 was thrown as a C++ exception

This seems like something that could be added to Emscripten. WDYT? Also, I have no clue how wasm-exceptions work and whether the code would need to be different for that case, but if you are interested in adding a feature like this, I would be willing to figure it out.

I wrote the following code for this:

Details

C++

#include <exception>
#include <typeinfo>
using namespace std;

extern "C"
{

  const char* exc_what(exception& e) { return e.what(); }

  const std::type_info* exc_type() { return &typeid(exception); }

  const char* exc_typename(std::type_info* type) { return type->name(); }
}

Typescript

function cppExceptionInfo(ptr: number): [string, boolean, number]{
  const base_exception_type = Module._exc_type();
  const ei = new Module.ExceptionInfo(ptr);
  const caught_exception_type = ei.get_type();
  const stackTop = Module.stackSave();
  const exceptionThrowBuf = Module.stackAlloc(4);
  Module.HEAP32[exceptionThrowBuf / 4] = ptr;
  const exc_type_name = Module.demangle(
    Module.UTF8ToString(Module._exc_typename(caught_exception_type))
  );
  const is_exception_subclass = !!Module.___cxa_can_catch(
    base_exception_type,
    caught_exception_type,
    exceptionThrowBuf
  );
  const adjusted_ptr = Module.HEAP32[exceptionThrowBuf / 4];
  Module.stackRestore(stackTop);
  return [exc_type_name, is_exception_subclass, adjusted_ptr];
}

function convertCppException(ptr: number): CppException {
  const [exc_type_name, is_exception_subclass, adjusted_ptr] = cppExceptionInfo(ptr);
  let msg;
  if (is_exception_subclass) {
    // If the ptr inherits from exception, we can use exception.what() to
    // generate a message
    const msgPtr = Module._exc_what(adjusted_ptr);
    msg = Module.UTF8ToString(msgPtr);
  } else {
    msg = `The exception is an object of type ${exc_type_name} at address ${ptr}  was thrown as a C++ exception`;
  }
  return new CppException(exc_type_name, msg);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions