传递给引发异常的构造函数的视图字符串

View string passed to constructor of thrown exception

本文关键字:构造函数 视图 字符串 异常      更新时间:2023-09-26

我正试图调试一个用Emscripten编译的C++程序,该程序会抛出异常,特别是传递字符串作为what_arg的运行时错误。然而,当它们抛出时,我只是在Javascript控制台中得到一个数字(指针值?)输出。传递给构造函数的字符串会更有帮助。

例如,程序

#include <stdexcept>
int main()
{
  throw std::runtime_error("I want to see this in the console");
  return 0;
}

使用命令使用Emscripten 1.35.0 64位(在Mac OS X上)编译

em++ exception.cc -o exception.html

当在浏览器中查看时,输出到控制台

Uncaught 5247024

在运行时,我如何查看what_arg参数是什么?

理想情况下,这将在C++代码中没有try-catch块,因此我可以使用DISABLE_EXCEPTION_CATCHING标志。有一些方法可以使用Pointer_stringify将C样式字符串的内存地址转换为Javascript字符串。也许作为异常传递的数字也有类似的情况?

有一种使用window.onerror的方法,它似乎是在抛出未处理的异常时调用的。使用这个,我可以

  • 获取oneror处理程序的第5个参数
  • 如果不是数字,则不执行任何操作
  • 使用例如ccall将数字传回C++世界给函数
  • 然后,函数对数字执行reinterpret_cast,以获得指向runtime_error的指针
  • runtime_error上调用what,并将结果字符串传递给cerr

实现这一点的一个示例C++程序是

#include <stdexcept>
#include <iostream>
#include <emscripten.h>
extern "C" void EMSCRIPTEN_KEEPALIVE what_to_stderr(intptr_t pointer)
{
  auto error = reinterpret_cast<std::runtime_error *>(pointer);
  std::cerr << error->what() << "'n";
}
int main()
{
  throw std::runtime_error("I want to see this in the console");
  return 0;
}

可以使用命令进行编译

em++ -std=c++11 exception.cc -o exception.js

并在一个简单的HTML页面中运行

<!doctype html>
<html>
  <head>
    <title>Exception test</title>
    <script>
      var Module = {};
      window.onerror = function(message, url, line, column, e) {
        if (typeof e != 'number') return;
        var pointer = e;
        Module.ccall('what_to_stderr', 'number', ['number'], [pointer]);
      }
    </script>
    <script src="exception.js"></script>
  </head>
  <body>
  </body>
</html>

它似乎适用于Chrome 46和Firefox 41。

您需要catch它并手动打印what()字符串。

编辑:这个要用try/catch块在C++中完成,类似于:

int main(int argc, char** argv)
{
    try
    {
        throw std::runtime_error("I want to see this in the console");
    }
    catch (const std::runtime_error& error)
    {
        std::cout << error.what() << std::endl;
    }
    return 0;
}