gpt4 book ai didi

c++ - V8 内存泄漏和条件跳转

转载 作者:行者123 更新时间:2023-11-28 04:15:24 27 4
gpt4 key购买 nike

我在我的 C 应用程序中嵌入了 V8。我能够在我的 C 应用程序中执行 javascript。但是,当我尝试运行我的 C 应用程序时,我看到了一堆内存泄漏和条件跳转。我总共有 4 个文件。

1。 mjse_int.h

typedef struct
{
std::unique_ptr<v8::Platform> platform;
v8::Isolate::CreateParams create_params;
v8::Isolate *isolate;
}MJSEInstance;

2。 mjse.h

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Create MJSE instance
*/
void *mjse_create_instance(char **argv);

/**
* @brief Destroy MJSE instance
* @param instance -> MJSE instance
*/
void mjse_destroy_instance(void *minstance);

/**
* @brief Executes a script
* @param minstance - MJSE instance
* @param script - the javascript
* @param scriptlen - Length of script
*/
void mjse_execute_script(void *minstance, char *script, int scriptlen);

#ifdef __cplusplus
}
#endif

#endif

3。 mjse.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/libplatform/libplatform.h"
#include "include/v8.h"
#include "mjse.h"
#include "mjse_int.h"

extern "C" {

using namespace v8;

void *mjse_create_instance(char **argv)
{
MJSEInstance *instance = (MJSEInstance *)calloc(1, sizeof(MJSEInstance));

v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
instance->platform = v8::platform::NewDefaultPlatform();

v8::V8::InitializePlatform(instance->platform.get());
v8::V8::Initialize();

instance->create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
instance->isolate = v8::Isolate::New(instance->create_params);

printf("Version: %s\n", v8::V8::GetVersion());

return instance;
}

void mjse_destroy_instance(void *minstance)
{
MJSEInstance *instance = (MJSEInstance *)minstance;

if(instance == NULL)
return;

if(instance->isolate)
{
instance->isolate->Dispose();
}

v8::V8::Dispose();
v8::V8::ShutdownPlatform();

if(instance->create_params.array_buffer_allocator)
{
delete instance->create_params.array_buffer_allocator;
}

free(instance);
}

void mjse_execute_script(void *minstance, char *script, int scriptlen)
{
MJSEInstance *instance = (MJSEInstance *)minstance;

v8::Isolate::Scope isolate_scope(instance->isolate);

// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(instance->isolate);

// Create a new context.
v8::Local<v8::Context> context = v8::Context::New(instance->isolate);

// Enter the context for compiling and running the hello world script.
v8::Context::Scope context_scope(context);

{
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source =
v8::String::NewFromUtf8(instance->isolate, script,
v8::NewStringType::kNormal).ToLocalChecked();

// Compile the source code.
v8::Local<v8::Script> script =
v8::Script::Compile(context, source).ToLocalChecked();

// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();

// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(instance->isolate, result);
printf("%s\n", *utf8);
}
}
}

使用这 3 个文件,我构建了一个 .so 文件。现在我的测试代码如下所示。

4。主.c

int main(int argc, char **argv)
{
int len;
char *script;
void *instance;

instance = mjse_create_instance(argv);

script = "function js_add_elements1(var1, var2) \
{ \
var var3 = parseInt(var1) + parseInt(var2); \
var result = 'Addition of ' + var1 + ' and ' + var2 + ' results ' + var3; \
return result; \
};\
js_add_elements1(2, 3);";

len = strlen(script);
mjse_execute_script(instance, script, len);

script = "function js_add_elements2(var1, var2) \
{ \
var var3 = parseInt(var1) + parseInt(var2); \
var result = 'Addition of ' + var1 + ' and ' + var2 + ' results ' + var3; \
return result; \
};\
js_add_elements2(2, 3);";

len = strlen(script);
mjse_execute_script(instance, script, len);

script = "function js_add_elements3(var1, var2) \
{ \
var var3 = parseInt(var1) + parseInt(var2); \
var result = 'Addition of ' + var1 + ' and ' + var2 + ' results ' + var3; \
return result; \
};\
js_add_elements3(2, 3);";

len = strlen(script);
mjse_execute_script(instance, script, len);

mjse_destroy_instance(instance);

return 0;
}

有了这个,我构建了 main.c 并进行了测试。输出如下所示。

Version: 7.7.0 (candidate)
Addition of 2 and 3 results 5
Addition of 2 and 3 results 5
Addition of 2 and 3 results 5

从功能的角度来看,它看起来不错。然而,有相当多的条件跳转和内存泄漏,如下所示(只有少数是为了保持更小的大小)。

==31273== Conditional jump or move depends on uninitialised value(s)
==31273== at 0x5DB55E8: v8::internal::DeclarationScope::CheckConflictingVarDeclarations() (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x599DCE8: v8::internal::PreParser::PreParseFunction(v8::internal::AstRawString const*, v8::internal::FunctionKind, v8::internal::FunctionLiteral::FunctionType, v8::internal::DeclarationScope*, int*, v8::internal::ProducedPreparseData**, int) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x597C6B5: v8::internal::Parser::SkipFunction(v8::internal::AstRawString const*, v8::internal::FunctionKind, v8::internal::FunctionLiteral::FunctionType, v8::internal::DeclarationScope*, int*, int*, v8::internal::ProducedPreparseData**) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x5970495: v8::internal::Parser::ParseFunctionLiteral(v8::internal::AstRawString const*, v8::internal::Scanner::Location, v8::internal::FunctionNameValidity, v8::internal::FunctionKind, int, v8::internal::FunctionLiteral::FunctionType, v8::internal::LanguageMode, v8::internal::ZoneList<v8::internal::AstRawString const*>*) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x5996C7A: v8::internal::ParserBase<v8::internal::Parser>::ParseHoistableDeclaration(int, v8::base::Flags<v8::internal::ParseFunctionFlag, int>, v8::internal::ZoneList<v8::internal::AstRawString const*>*, bool) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x596EFE6: v8::internal::Parser::DoParseProgram(v8::internal::Isolate*, v8::internal::ParseInfo*) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x596E6D8: v8::internal::Parser::ParseProgram(v8::internal::Isolate*, v8::internal::ParseInfo*) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x599A4D9: v8::internal::parsing::ParseProgram(v8::internal::ParseInfo*, v8::internal::Isolate*) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x56EF5B5: v8::internal::(anonymous namespace)::CompileToplevel(v8::internal::ParseInfo*, v8::internal::Isolate*, v8::internal::IsCompiledScope*) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x56F0EA8: v8::internal::Compiler::GetSharedFunctionInfoForScript(v8::internal::Isolate*, v8::internal::Handle<v8::internal::String>, v8::internal::Compiler::ScriptDetails const&, v8::ScriptOriginOptions, v8::Extension*, v8::internal::ScriptData*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason, v8::internal::NativesFlag) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x56B5C64: v8::ScriptCompiler::CompileUnboundInternal(v8::Isolate*, v8::ScriptCompiler::Source*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason) (in /usr/local/mysys/system/libs/libmjse.so)
==31273== by 0x56B6356: v8::ScriptCompiler::Compile(v8::Local<v8::Context>, v8::ScriptCompiler::Source*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason) (in /usr/local/mysys/system/libs/libmjse.so)
==31273==

==31273== LEAK SUMMARY:<br>
==31273== definitely lost: 144 bytes in 1 blocks<br>
==31273== indirectly lost: 1,744 bytes in 11 blocks<br>
==31273== possibly lost: 960 bytes in 3 blocks<br>
==31273== still reachable: 1,474 bytes in 18 blocks<br>
==31273== suppressed: 0 bytes in 0 blocks<br>

不确定这里有什么问题。在这方面的任何帮助,非常感谢。

编辑

按照 Radosław Cybulski 的建议修改代码后,内存泄漏消失了。目前只有 168 字节的内存仍可访问。

然而,对于未初始化值的条件跳转仍然存在(使用 valgrind 运行)。如果我在 javascript 中删除函数参数,我会观察到一件事,这些未初始化值的条件跳转不会显示。假设我将使用如下 javascript。

char *jscript =  "function js_add_elements1() \
{ \
return 10; \
};\

js_add_elements1();";

使用上面的 javascript,我没有看到未初始化值的条件内存跳转。可能是什么原因?

最佳答案

free(instance);

释放内存,但防止 unique_ptr(平台成员)销毁。尝试:

instance->~MJSEInstance();
free(instance):

或者甚至更好地使用 new 和 delete 而不是 malloc 和 free。

关于c++ - V8 内存泄漏和条件跳转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56756508/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com