help
help copied to clipboard
C++ applications are embedded in nodejs static libraries, and I have encapsulated nodejs demo. After initialization, run the runnodeinstance function in the demo repeatedly for 2000 times, and memory leaks and crashes will occur. Is it my call error?
Test
test Embed nodejs static library
Platform
windows
Console output
D:\workspace\project\Test\Release\parse.exe[29596]: D:\a\libnode\libnode\node-v17.0.1\src\node_win32_etw_provider.cc:190: Assertion `(status) == (0L)' failed.
D:\workspace\project\Test\Release\parse.exe (进程 29596)已退出,代码为 134。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
Build links
Memory leaks and crashes
Additional information
//Pseudocode
int RunNodeInstance(node::MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args,
const std::string& data,
std::wstring& jsResult)
{
int exit_code = 0;
// Setup up a libuv event loop, v8::Isolate, and Node.js Environment.
std::vector<std::string> errors;
std::unique_ptr<CommonEnvironmentSetup> setup_ =
CommonEnvironmentSetup::Create(platform, &errors, args, exec_args);
if (!setup_) {
for (const std::string& err : errors)
fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
return 1;
}
Isolate* isolate = setup_->isolate();
Environment* env = setup_->env();
{
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
// The v8::Context needs to be entered when node::CreateEnvironment() and
// node::LoadEnvironment() are being called.
Context::Scope context_scope(setup_->context());
std::string resu = "const publicRequire = require('module').createRequire(process.cwd() + '/');";
resu += "globalThis.require = publicRequire;";
//resu += "require('vm').runInThisContext(process.argv[1]);";
MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
env,
resu.c_str()
);
if (loadenv_ret.IsEmpty()) // There has been a JS exception.
return 1;
{
// 外面包个try...catch
v8::TryCatch try_catch(isolate);
Local<String> source_ = String::NewFromUtf8(isolate,
data.c_str()
, NewStringType::kNormal).ToLocalChecked();
v8::Local<v8::Script> script;
if (!v8::Script::Compile(setup_->context(), source_).ToLocal(&script)) {
ReportException(isolate, &try_catch);
return -1;
}
// v8::Script::Compile(setup->context(), source_).ToLocal(&script);
v8::Local<v8::Value> result;
if (!script->Run(setup_->context()).ToLocal(&result))
{
ReportException(isolate, &try_catch);
return -1;
}
// script->Run(setup->context()).ToLocal(&result);
//// v8 异常处理
//if (try_catch.HasCaught()) {
// Local<Value> exception = try_catch.Exception();
// String::Utf8Value exception_str(isolate, exception);
// std::cout << *exception_str << endl;
//}
Local<String> strValues = String::NewFromUtf8(isolate, "result", NewStringType::kNormal).ToLocalChecked();
Local<Value> jsValues = setup_->context()->Global()->Get(setup_->context(), strValues).ToLocalChecked();
if (jsValues.IsEmpty())
{
jsResult = L"";
printf("empty\n");
}
else if (jsValues->IsString())
{
String::Utf8Value str(isolate, jsValues);
jsResult = Utf8ToUnicode(*str);
// printf("C++ Call JS values: %s\n", jsResult.c_str());
}
}
exit_code = node::SpinEventLoop(env).FromMaybe(1);
node::Stop(env);
}
return exit_code;
}
int init()
{
int argc = 1;
ptr_ = std::shared_ptr<char*>(new char* [argc + 1]);
std::string path = "";
ptr_.get()[0] = const_cast<char*>(path.c_str());
char** argv = ptr_.get();
argv = uv_setup_args(argc, ptr_.get());
args_.push_back("");
std::vector<std::string> errors;
int exit_code = node::InitializeNodeWithArgs(&args_, &exec_args_, &errors);
for (const std::string& error : errors)
fprintf(stderr, "%s: %s\n", args_[0].c_str(), error.c_str());
if (exit_code != 0) {
return exit_code;
}
platform_ = node::MultiIsolatePlatform::Create(4);
V8::InitializePlatform(platform_.get());
V8::Initialize();
return 0;
}
void parse()
{
std::string data_ = "var data = " + data + ";";
data_.append("var _config = {\"needTopLogo\":false,\"needBottomLogo\":false};");
std::wstring result = L"";
*code = RunNodeInstance(platform_.get(), args_, exec_args_, data_, result);
}
int main()
{
init();
for(int i =0;i <2000; i++)
parse();
}