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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions