- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我收到以下“第一次机会异常”消息,该消息来 self 编写的 DLL,该 DLL 在我未编写的可执行文件中运行。也就是说,DLL 是一个插件。第一次触发此异常时,尝试打开共享内存映射文件失败。如果我忽略第一次机会异常而只是运行,应用程序最终会卡住或崩溃。
First-chance exception at 0x76a7c41f in notmyexe.exe: Microsoft C++ exception: boost::interprocess::interprocess_exception at memory location 0x002bc644..
几个小时后,它似乎是由一段无限循环的代码块引起的,直到预期的异常条件被清除。事实证明,如果它永远不会清除,那么最终,这个异常会变成另一个低级异常条件和/或变成堆损坏。所有这一切只是为了使用 Boost::interprocess 打开一个共享内存区域。
使事情复杂化的第一件事是,在我基于 Visual C++ 2008 的项目中,第一个 boost::interprocess::interprocess_exception
第一次机会异常不会被抛出并被识别为它来自的位置,因为 Visual C++ 2008 编译器无法找到有问题的复杂 boost-flavor 模板代码。然而,通过单步执行汇编语言 View ,我发现了错误的代码。
我自己的代码中开始出现问题的顶级行是:
segment = new managed_shared_memory( open_or_create
, MEMORY_AREA_NAME
, SHARED_AREA_SIZE );
以上managed_shared_memory
类来自 interprocess_fwd.hpp,是 boost 共享内存 API/ header 的标准部分。因为它是基于模板的,所以上面的表达式扩展为大约 2Kchars 长的 C++ boost 模板表达式,它被链接器和调试器以不同的长度截断。 Visual C++ 2008 不再具有源代码调试功能,似乎这些限制正在发挥作用。
例如,当它爆炸时,我得到这个调用堆栈:
KernelBase.dll!76a7c41f()
[Frames below may be incorrect and/or missing, no symbols loaded for KernelBase.dll]
KernelBase.dll!76a7c41f()
> msvcr90d.dll!_malloc_dbg(unsigned int nSize=2290875461, int nBlockUse=264, const char * szFileName=0x01fcb983, int nLine=1962999808) Line 160 + 0x1b bytes C++
8bfc4d89()
上面的堆栈转储中没有实际的最终用户编写的源函数。
我应该如何调试它?其次,在 Visual C++ 2008 中,boost-interprocess 是否存在一些已知问题?第三,下面的boost代码是做什么的,为什么要无限循环?
boost::interprocess::basic_managed_shared_memory<char,
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
boost::interprocess::offset_ptr<void,int,unsigned int,0>,0>,
boost::interprocess::iset_index>::basic_managed_shared_memory<char,boo...
再往下一层,我们得到:
basic_managed_shared_memory (open_or_create_t,
const char *name, size_type size,
const void *addr = 0, const permissions& perm = permissions())
: base_t()
, base2_t(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
ipcdetail::DoOpenOrCreate), perm)
{}
无论如何, children 不要试图在家里调试它,这是会发生的事情:
最后,利用我的忍者般的能力单步执行数百万行汇编语言,我已经克服了 Visual C++ 2008 的邪恶调试器限制,并找到了有问题的代码。
这就是爆炸的事实:create_device<FileBased>(dev...
.
这里的一些上下文:managed_open_or_create_impl.h 第 351 行...
else if(type == DoOpenOrCreate){
//This loop is very ugly, but brute force is sometimes better
//than diplomacy. If someone knows how to open or create a
//file and know if we have really created it or just open it
//drop me a e-mail!
bool completed = false;
while(!completed){
try{
create_device<FileBased>(dev, id, size, perm, file_like_t()); // <-- KABOOM!
created = true;
completed = true;
}
catch(interprocess_exception &ex){
if(ex.get_error_code() != already_exists_error){
throw;
}
else{
try{
DeviceAbstraction tmp(open_only, id, read_write);
dev.swap(tmp);
created = false;
completed = true;
}
catch(interprocess_exception &e){
if(e.get_error_code() != not_found_error){
throw;
}
}
catch(...){
throw;
}
}
}
catch(...){
throw;
}
thread_yield();
}
}
最佳答案
我相信我遇到过一些与您相同的问题。查看“\boost\interprocess\shared_memory_object.hpp”中的函数“shared_memory_object::priv_open_or_create”。在该函数的顶部是另一个函数调用“create_tmp_and_clean_old_and_get_filename”,它启动一个函数链,最终删除共享内存文件。我最终将 priv_open_or_create 函数中的函数调用移到了 case 语句开始的位置附近。我相信我正在使用 boost 1.48。这是我修改的那个函数的最终版本:
inline bool shared_memory_object::priv_open_or_create
(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm)
{
m_filename = filename;
std::string shmfile;
std::string root_tmp_name;
//Set accesses
if (mode != read_write && mode != read_only){
error_info err = other_error;
throw interprocess_exception(err);
}
switch(type){
case ipcdetail::DoOpen:
ipcdetail::get_tmp_base_dir(root_tmp_name);
shmfile = root_tmp_name;
shmfile += "/";
shmfile += filename;
m_handle = ipcdetail::open_existing_file(shmfile.c_str(), mode, true);
break;
case ipcdetail::DoCreate:
ipcdetail::create_tmp_and_clean_old_and_get_filename(filename, shmfile);
m_handle = ipcdetail::create_new_file(shmfile.c_str(), mode, perm, true);
break;
case ipcdetail::DoOpenOrCreate:
ipcdetail::create_tmp_and_clean_old_and_get_filename(filename, shmfile);
m_handle = ipcdetail::create_or_open_file(shmfile.c_str(), mode, perm, true);
break;
default:
{
error_info err = other_error;
throw interprocess_exception(err);
}
}
//Check for error
if(m_handle == ipcdetail::invalid_file()){
error_info err = system_error_code();
this->priv_close();
throw interprocess_exception(err);
}
m_mode = mode;
return true;
}
顺便说一句,如果有人知道我可以通过官方 channel 尝试验证并添加到 boost,请告诉我,因为我讨厌在不知道其全部效果的情况下修改这样的东西。
希望这对您有所帮助!
关于c++ - 如何调试或修复涉及 boost::interprocess managed_shared_memory 的无限循环和堆损坏问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16651878/
我有 3 个列表项,每 3 秒向上旋转一次。我正在使用 transformY 属性来做这件事。问题是,当它到达最后一个元素时,它会循环返回,从而产生重新开始的效果。 如何通过在最后一项之后继续向上旋转
我如何制作一个处理旋转的无限/重复世界,就像在这个游戏中一样: http://bloodfromastone.co.uk/retaliation.html 我通过具有这样的层次结构对我的旋转移动世界进
这个问题已经有答案了: Using explicitly numbered repetition instead of question mark, star and plus (4 个回答) 已关闭
程序说明: I have this program of mine which is intended to read every word from a file (large one) and t
while 循环应该比较这两个对象的 ibsn。正在比较的对象: list[0] = new ReadingMatter ("Words and Stuff", "9-082-1090-1");
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我完全被屏蔽了。我尝试修改 C 中的“警报”信号,以便在秒数到期时读取一个简单的变量。我的代码如下: 在主要部分: int semnal; signal(SIGALRM, alarmHandle
我正在接受多行信息(字符串,直到我稍后解析它们)。例如: 1 5 0 2 9 6 2 9 1 我编写这段代码来分隔行,因为我将不得不以某种方式操作每一行。 Scanner scan = new Sca
我不熟悉 jQuery,并且我有多余的 jQuery 调用,我想将它们放入循环中。 $('.class1').on('click', function () { ... $('.class2').on
我有一个树结构,其中每个节点都有 5 个子节点,并且不允许超过 5 个。我希望以广度优先搜索的方式遍历这棵树。 现在我想使用广度优先搜索方式从选定的父节点计算空节点。 例如 如果给定的父节点为 1,则
目标/动机 我想写一个服务,它应该一直运行。但是当服务已经运行时,应该不可能再次启动该服务。 用例 用户 X 打开页面 myService.php 并通过单击页面上的按钮启动服务。之后关闭浏览器。一段
我正在尝试编译 shogun 工具箱,但遇到了这个错误 C:/shogun-3.0.0/shogun-3.0.0/src/shogun/../shogun/mathematics/Math.h
需要学校的 JavaScript 作业帮助,但不知道该怎么做,希望得到一些提示? 我们应该创建一个 6 面掷骰子程序,用户可以选择应该掷多少个骰子,最少 1 个和最多 5 个骰子。 所用骰子数量的总和
我在无限 ScrollView 中有 5 张图片。 因此,为了使 scrollView 无限/循环,我将图像定位如下: 5 1 2 3 4 5 1含义:最后一张图片第一张图片第二张图片.....最后一
我正在使用 ExTwitter库,并希望能够偶尔终止对流式 API 的调用以更改参数。 我当前的代码看起来像这样: for tweet #finished end 关于elixir - 如何中断(无
我想每 3 秒更改一次 div 的背景。这需要循环,因此一旦最后一个背景图像显示,它就会循环回到第一个背景图像,依此类推。我在这样做时遇到了麻烦。 我之前发过一篇文章,内容非常模糊,没有得到帮助。
我在做this教程,无法让我的页面正确加载。我不断在控制台中收到错误:[$rootScope:infdig]。 我对 Angular 很陌生,但从我读到的内容来看,我在某个地方有一个无限循环。我预计它
所以我试图创建一个无限的 asyncIterator/生成器。该代码应该为“for wait of”循环生成“Hello”和“Hi”,然后永远等待下一个值。问题是它不等待第三个值,也不在循环后打印 2
下图显示了我如何在 HTML5/JS 中制作无限背景滚动。我的连续背景由 X block Canvas 组成。我将在到达下一个 Canvas 之前立即渲染它,并释放上一个 Canvas。这里的问题是动
作为一个业余项目,我正在研究一些自制的素数生成问题,尝试编写一些不同的实现作为自学 C 和 C++ 的方法。当然,生成低素数的最快方法是已经拥有它们,所以我想着手建立一个硬盘素数列表数据文件。我想编写
我是一名优秀的程序员,十分优秀!