【问题标题】:View string passed to constructor of thrown exception查看传递给抛出异常的构造函数的字符串
【发布时间】:2015-11-15 16:11:13
【问题描述】:

我正在尝试调试使用 Emscripten 编译的 C++ 程序,该程序会引发异常,特别是 runtime_errors,它将字符串作为 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 64bit(在 Mac OS X 上)通过命令编译

em++ exception.cc -o exception.html

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

Uncaught 5247024

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

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

【问题讨论】:

  • 我看不出将 C++ 转换为 JS 以执行浏览器的意义,但没关系。在任何情况下,您都会像这样在 C++ 中捕获异常:try {...} catch (std::exception ex) { std::cout &lt;&lt; ex.what( ); }
  • @szczurcio 你能解释一下为什么看这个论点没有意义吗?
  • 对不起,请详细说明,什么论据?如果您询问您传递给std::runtime_error 的构造函数的const char[] 消息,这就是what( ) 将给您的。
  • 啊抱歉...我误读了您的消息(或者我可能是您编辑了它?)。我以为它说“我看不出那个意思”,我把“那个”理解为想要看到 const char[] 消息,而不是将 C++ 转换为 JS 以供浏览器执行。我将 C++ 转换为 JS 以执行浏览器的原因是存在必须在浏览器中运行的现有 C++ 代码库。是的,了解what
  • 最初它确实说“我看不出那个意思”,因为我指的是您已删除的评论,而该评论又是对我已删除的初始评论的回应;)。无论如何,afaik 没有办法捕获从 std::exception 派生的异常并在没有 try-catch 块的情况下打印其 what( )。您可以阅读有关 std::set_terminatestd::set_unexpected 的信息,但它们不会让您打印消息,因为并非每种类型的异常都必须有一个(在 C++ 中,任何类都可以作为异常抛出,与 Java 不同)。

标签: javascript c++ exception emscripten


【解决方案1】:

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

  • 获取 onerror 处理程序的第 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。

【讨论】:

    【解决方案2】:

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

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

    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;
    }
    

    【讨论】:

    • 你能给出这个示例代码吗?这会在 C++ 中还是在 Javascript 中捕获它?
    • 这将在 C++ 中捕获它。然后你需要以某种方式将信息发送给 JS。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    相关资源
    最近更新 更多