我正试图调试一个用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;
}