页次: 1
lua 版本:Lua 5.3.5 Copyright (C) 1994-2018 Lua.org, PUC-Rio
环境:archlinux
宿主语言:c++
编译器:g++
malloc.c:3839: _int_malloc: Assertion `chunk_main_arena (bck->bk)' failed.
malloc.c:4036: _int_malloc: Assertion `(unsigned long) (size) >= (unsigned long) (nb)' failed.
以上2种断言失败有可能是什么原因导致?
越界?还是有其他可能
在我的程序中,是在调用vkCreateSwapchainKHR导致的。在重建交换链时,具体代码:
const ImVec4 clear_color = ImVec4(0.2f , 0.2f , 0.2f , 1.0f);
setup(window, g_PhysicalDevice, g_MainWindowData);
// Main loop
while (!glfwWindowShouldClose(window)){
glfwPollEvents();
if (g_SwapChainRebuild){
g_SwapChainRebuild = false;
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount);
g_MainWindowData.FrameIndex = 0;
}
// Start the Dear ImGui frame
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
drawWidget(g_MainWindowData);
ImGui::EndFrame();
ImGui::Render();
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
FrameRender(wd);
FramePresent(wd);
renderFinish();
}
// Cleanup
err = vkDeviceWaitIdle(g_Device);
cleanup(window, g_Device);
check_vk_result(err);
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
在while循环中的ImGui_ImplVulkanH_CreateWindow函数里面的vkCreateSwapchainKHR出错。具体代码可以看imgui的例子 vk glfw:imgui
重建之前vkCreateSwapchainKHR的参数信息
(gdb) p info
$2 = {sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, pNext = 0x0, flags = 0, surface = 0x20000000002, minImageCount = 3, imageFormat = VK_FORMAT_B8G8R8A8_UNORM,
imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, imageExtent = {width = 1916, height = 1023}, imageArrayLayers = 1, imageUsage = 16, imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
queueFamilyIndexCount = 0, pQueueFamilyIndices = 0x0, preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
presentMode = VK_PRESENT_MODE_FIFO_KHR, clipped = 1, oldSwapchain = 0x30000000003}
以下是出错时,使用bt得到的堆栈信息...特么出错的位置一直不一样,图片上是在分配命令buffer的时候出的错误。虽然出错的函数不一样,但都在malloc断言失败
有时候出错的地方也会是下面的函数:
[Thread 0x7fffef7fe700 (LWP 13484) exited]
Thread 1 "Three_kingdoms" received signal SIGSEGV, Segmentation fault.
0x0000555555571c88 in FindHoveredWindow () at imgui.cpp:4350
4350 if (!window->Active || window->Hidden)
(gdb) bt
#0 0x0000555555571c88 in FindHoveredWindow () at imgui.cpp:4350
#1 0x000055555556f6d0 in ImGui::UpdateHoveredWindowAndCaptureFlags () at imgui.cpp:3666
#2 0x0000555555570252 in ImGui::NewFrame () at imgui.cpp:3843
#3 0x00005555555ebe16 in main () at main.cpp:359
(gdb) p window
$3 = (ImGuiWindow *) 0x0
(gdb)
上面的出现的错误都因为在某些地方调用了get_table_val函数,该函数重载了多个不同类型的函数:
bool get_table_val(lua_State *L, const char *table_name, const char *key, std::string&val){
if(!L || !table_name || !key){
std::cout << "in function " << __FUNCTION__ << ":lua_State *L = nullptr || const char *table_name = nullptr || const char *key = nullptr" << std::endl;
return false;
}
lua_getglobal(L, table_name);
if(!lua_istable(L, -1)){
fprintf(stderr, "error:%s is not a table name\n", table_name);
return LUA_TNIL;
}
if(LUA_TSTRING != lua_getfield(L, -1, key)){
fprintf(stderr, "error:%s[%s] type is not a string\n", table_name, key);
return false;
}
val = lua_tostring(L, -1);
lua_pop(L, 1);
return true;
}
//最后,以下代码导致的以上错误的发生,如果注释掉则程序正常运行,以下代码都能正确获得脚本中的值:
//这些代码在setup创建的线程中执行。
std::string skill_name;
uint32_t skill_count = 0;
knight_info.skills.clear();
if(!get_table_val(g_LuaState, g_TableName[knightName].c_str(), "skill_count", skill_count)){
fprintf(stderr, "请确认是否在%s文件中加入了该表名\n", (KNIGHT_RESOURCE_PATH + knightName + ".lua").c_str());
}
knight_info.skills.resize(skill_count);
for (uint32_t i = 0; i < skill_count; ++i){
char key[MAXBYTE] = { 0 };
sprintf(key, "skill_%d", i + 1);
if(get_table_val(g_LuaState, g_TableName[knightName].c_str(), key, skill_name)){//经测试,不是随机武将的时候越界;只要不调用下面的函数,则一切正常
// KnightInformation info;
// get_table_val(g_LuaState, skill_name.c_str(), "name", info.skills[i].name);
// get_table_val(g_LuaState, skill_name.c_str(), "lock", info.skills[i].bLock);
// get_table_val(g_LuaState, skill_name.c_str(), "initiative", info.skills[i].bInitiative);
// get_table_val(g_LuaState, skill_name.c_str(), "description", info.skills[i].description);
// get_table_val(g_LuaState, skill_name.c_str(), "effect", info.skills[i].effect_function);
// get_table_val(g_LuaState, skill_name.c_str(), "trigger", info.skills[i].trigger_condition);
// get_table_val(g_LuaState, skill_name.c_str(), "trigger_stage", (uint32_t&)info.skills[i].triggerStage);
get_table_val(g_LuaState, skill_name.c_str(), "name", knight_info.skills[i].name);//name类型是std::string
get_table_val(g_LuaState, skill_name.c_str(), "lock", knight_info.skills[i].bLock);//这是bool后面同理
get_table_val(g_LuaState, skill_name.c_str(), "initiative", knight_info.skills[i].bInitiative);
get_table_val(g_LuaState, skill_name.c_str(), "description", knight_info.skills[i].description);//std::string
get_table_val(g_LuaState, skill_name.c_str(), "effect", knight_info.skills[i].effect_function);//std::string
get_table_val(g_LuaState, skill_name.c_str(), "trigger", knight_info.skills[i].trigger_condition);//std::string
get_table_val(g_LuaState, skill_name.c_str(), "trigger_stage", (uint32_t&)knight_info.skills[i].triggerStage);//size_t
// std::cout << knight_info.skills[i].name << " " << knight_info.skills[i].description << " " << knight_info.skills[i].triggerStage << std::endl;
}
}
本意只想知道上面2个malloc出错的可能,并不是一定要知道那里出错。当然,能知道更好。或者提供一个调试的方法,多谢
最近编辑记录 beginner (2020-06-02 23:21:53)
离线
你对问题优质不优质的判断标准是字数?
反社会,精神极其不稳定,随时可能炸碎身边所有人
离线
标准文档没有谈及malloc会abort,你abort的位置全部都在libc的malloc函数内,疑似libc有bug,换之测试
最近编辑记录 xtricman (2020-06-03 08:52:48)
反社会,精神极其不稳定,随时可能炸碎身边所有人
离线
本意只想知道上面2个malloc出错的可能,并不是一定要知道那里出错。当然,能知道更好。或者提供一个调试的方法,多谢
你内存写越界,把分配器的数据覆盖了。
valgrind 看看吧。
离线
beginner 说:本意只想知道上面2个malloc出错的可能,并不是一定要知道那里出错。当然,能知道更好。或者提供一个调试的方法,多谢
你内存写越界,把分配器的数据覆盖了。
valgrind 看看吧。
所以glibc的malloc会做一个assert来做一个数据检查,如果查到破坏会abort?有文档说吗?我看manpage没有描述malloc会abort吧,它不返回null而是abort这个行为比较意外…
反社会,精神极其不稳定,随时可能炸碎身边所有人
离线
依云 说:beginner 说:本意只想知道上面2个malloc出错的可能,并不是一定要知道那里出错。当然,能知道更好。或者提供一个调试的方法,多谢
你内存写越界,把分配器的数据覆盖了。
valgrind 看看吧。所以glibc的malloc会做一个assert来做一个数据检查,如果查到破坏会abort?有文档说吗?我看manpage没有描述malloc会abort吧,它不返回null而是abort这个行为比较意外…
你都 UB 了 abort 掉一点也不奇怪啊。
离线
多谢,我已经开始用valgrind了。
不过,如果使用了valgrind后仍有不解的地方可能还会来问。
离线
页次: 1