如何调试或修复无限循环和堆损坏问题涉及的boost ::进程间managed_shared_memory? [英] How do I debug or fix the endless loop and heap corruption issue involving boost::interprocess managed_shared_memory?

查看:1299
本文介绍了如何调试或修复无限循环和堆损坏问题涉及的boost ::进程间managed_shared_memory?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的第一次机会异常消息是从一个DLL我写的是,我没有写一个可执行文件中运行的到来。也就是说,该DLL插件。第一次此异常火灾,试图打开一个共享内存映射文件失败。如果我忽略了第一次机会异常,只是运行,应用程序冻结或崩溃,最终。

微软C ++异常:

 在0x76a7c41f在notmyexe.exe第一次机会异常的boost ::进程间:: interprocess_exception内存位置0x002bc644 ..

几个小时后,它似乎是由code这是无休止地循环,直到预期的异常状况清除块造成的。事实证明,如果它从来不清晰,然后,最终,这个例外变成另一种低级别的异常条件和/或变成堆损坏。所有这一切都只是在努力使用boost ::进程间打开一个共享内存区。

这复杂的事情的第一件事是,在我的Visual C ++ 2008基于项目,第一个的boost ::进程间:: interprocess_exception 第一次机会没有抛出异常,并确定因为它来自何处,因为Visual C ++ 2008编译器编译无法找到问题的复杂提振味模板code附带的位置。然而,通过单一通过汇编语言观加强,我发现code,它打击了。

我自己的code的顶层线,这一切都开始走坏的是:

 段=新managed_shared_memory(open_or_create
                                      ,MEMORY_AREA_NAME
                                      ,SHARED_AREA_SIZE);

以上 managed_shared_memory 类是interprocess_fwd.hpp,是助推共享内存API /头的标准组成部分。因为它是基于模板,在上述扩展到大约2Kchars长c + +升压模板前pression,这是在不同的长度由链接器截断,并且由调试器。 VISUAL C ++ 2008中有没有更多的源$ C ​​$ C调试功能,似乎当这些限制在起作用。

例如,当它炸毁我得到这个调用堆栈:

  KernelBase.dll!76a7c41f()
    [相框下面可能不正确和/或缺失,没有加载KernelBase.dll符号]
    KernelBase.dll!76a7c41f()
> msvcr90d.dll!_malloc_dbg(无符号整数n大小= 2290875461,INT nBlockUse = 264,为const char * szFileName = 0x01fcb983,INT n线= 1962999808)线160 + 0x1b字节C ++
    8bfc4d89()

没有实际最终用户编写的源功能出现在堆栈转储以上。

我应该如何调试呢?其次,有没有用的升压进程间一些已知问题,用Visual C ++ 2008?三,什么是做以下的增压code和为什么必须把它无休止地循环?

 的boost ::进程间:: basic_managed_shared_memory<焦炭,
   提高::进程间:: rbtree_best_fit<提高::进程间:: mutex_family,
        提高::进程间:: offset_ptr<无效,整型,无符号整型,0> 0>中
        提高::进程间:: iset_index> :: basic_managed_shared_memory<焦炭,嘘...

另外层层下来,我们得到:

  basic_managed_shared_memory(open_or_create_t,
                              为const char *名称,SIZE_TYPE大小,
                              常量无效*地址= 0,const的权限和放大器;烫发=许可())
      :base_t()
      ,base2_t(open_or_create,名称,大小,READ_WRITE,地址,
                create_open_func_t(get_this_pointer(),
                ipcdetail :: DoOpenOrCreate),烫发)
   {}

不管怎么说,不要试图在家里的孩子调试此,这里发生了什么:

最后,用我的忍者般的能力,单步数百万行汇编语言的我已经打败的Visual C ++ 2008的邪恶的调试器限制,并已发现有问题的code。

这是什么,其实是在吹: create_device< FileBased>(DEV ...

一些背景这里:
managed_open_or_create_impl.h线351 ...

 否则,如果(类型== DoOpenOrCreate){
         //这个循环是非常难看,但蛮力有时是更好
         //不是外交。如果有人知道如何打开或创建
         //文件,并知道如果我们确实创造了它,或只是将其打开
         //给我发邮件!
         布尔完成= FALSE;
         而(!完成){
            尝试{
               create_device< FileBased>(DEV,ID,大小,烫发,file_like_t()); //< - KABOOM!
               创建= TRUE;
               完成=真;
            }
            赶上(interprocess_exception&安培;除息){
               如果(ex.get_error_ code()!= already_exists_error){
                  扔;
               }
               其他{
                  尝试{
                     DeviceAbstraction TMP(open_only,ID,READ_WRITE);
                     dev.swap(TMP);
                     创建= FALSE;
                     完成=真;
                  }
                  赶上(interprocess_exception急症){
                     如果(e.get_error_ code()!= not_found_error){
                        扔;
                     }
                  }
                  抓住(...){
                     扔;
                  }
               }
            }
            抓住(...){
               扔;
            }
            thread_yield();
         }
      }


解决方案

我相信我有一些你有同样的问题。看看在\\提升\\间\\ shared_memory_object.hpp功能shared_memory_object :: priv_open_or_create。在该函数的顶部是另一个函数调用create_tmp_and_clean_old_and_get_filename启动该卷起删除共享内存文件中的函数链。我结束了移动该函数调用在较低的地方周围的case语句开始priv_open_or_create功能。我相信我使用boost 1.48。下面是一个函数,我修改的最终版本:

 内联BOOL shared_memory_object :: priv_open_or_create
   (ipcdetail :: create_enum_t类型为const char *文件名,mode_t模式,常量权限和放大器;烫发)
{
   m_filename =文件名;
   标准::字符串shmfile;
   标准::字符串root_tmp_name;   //设置访问
   如果(模式= READ_WRITE和放大器;!&安培;模式= READ_ONLY!){
      ERROR_INFO ERR = OTHER_ERROR;
      扔interprocess_exception(ERR);
   }   开关(类型){
      案例ipcdetail :: DoOpen:
            ipcdetail :: get_tmp_base_dir(root_tmp_name);
            shmfile = root_tmp_name;
            shmfile + =/;
            shmfile + =文件名;
            m_handle = ipcdetail :: open_existing_file(shmfile.c_str()模式,真正的);
      打破;
      案例ipcdetail :: DoCreate:
            ipcdetail :: create_tmp_and_clean_old_and_get_filename(文件名,shmfile);
          m_handle = ipcdetail :: create_new_file(shmfile.c_str()模式,烫发,真正的);
      打破;
      案例ipcdetail :: DoOpenOrCreate:
         ipcdetail :: create_tmp_and_clean_old_and_get_filename(文件名,shmfile);
          m_handle = ipcdetail :: create_or_open_file(shmfile.c_str()模式,烫发,真正的);
      打破;
      默认:
         {
            ERROR_INFO ERR = OTHER_ERROR;
            扔interprocess_exception(ERR);
         }
   }   //检查错误
   如果(m_handle == ipcdetail :: invalid_file()){
      ERROR_INFO ERR = system_error_ code();
      这 - > priv_close();
      扔interprocess_exception(ERR);
   }   m_mode =模式;
   返回true;
}

顺便说一句,如果有谁知道官方渠道,我可以通过尝试,并得到这个验证并加入到推动请让我知道,因为我讨厌修改这样的东西不知道它的全部作用。

希望这有助于!

I have the following "first-chance exception" message which is coming from a DLL I wrote which is running inside an executable that I did not write. That is, the DLL is a plugin. The first time this exception fires, an attempt to open a shared memory map file is failing. If I ignore first chance exceptions and just run, the application freezes or crashes eventually.

First-chance exception at 0x76a7c41f in notmyexe.exe: Microsoft C++ exception: boost::interprocess::interprocess_exception at memory location 0x002bc644..

After several hours it appears to be caused by a block of code which is looping endlessly until an expected exception condition clears. It turns out that if it never does clear, and then, eventually, this exception turns into another low-level-exception-condition and/or turns into heap corruption. All of this is just in an effort to open a shared memory area using Boost::interprocess.

The first thing that complicates things is that on my Visual C++ 2008 based project, the first boost::interprocess::interprocess_exception first-chance exception is not thrown and identified as the location where it came from because the Visual C++ 2008 compiler cannot find the complex boost-flavor templates code in question. However by single stepping through the assembly language view, I found the code that blows up.

The top level line of my own code that it all starts to go bad on is:

  segment = new managed_shared_memory(   open_or_create
                                      ,  MEMORY_AREA_NAME
                                      , SHARED_AREA_SIZE );          

The above managed_shared_memory class is from interprocess_fwd.hpp, and is a standard part of the boost shared memory API/headers. Because it's template based, the above expands into about a 2Kchars long C++ boost template expression, which is truncated at different lengths by the linker, and by the debugger. Visual C++ 2008 has no more source code debugging capabilities, it seems when these limits are in play.

For example, when it blows up I get this call stack:

    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()  

No actual end-user written source functions appear in the stack dump above.

How should I debug this? Secondly, is there some known problem with boost-interprocess, with Visual C++ 2008? Third, what is the boost code below doing and why must it endlessly loop?

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...

Further layers down, we get to:

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)
   {}  

Anyways, don't try to debug this at home kids, here's what happens:

Finally, using my ninja-like ability to single step through several million lines of assembly language I have defeated Visual C++ 2008's evil debugger limitations, and have found the code in question.

This is what is blowing up in fact: create_device<FileBased>(dev....

Some context here: managed_open_or_create_impl.h line 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();
         }
      }

解决方案

I believe I've had some of the same issues you are having. Take a look at the function "shared_memory_object::priv_open_or_create" in "\boost\interprocess\shared_memory_object.hpp". At the top of that function is another function call "create_tmp_and_clean_old_and_get_filename" that starts a function chain that winds up deleting the shared memory file. I wound up moving that function call lower in the priv_open_or_create function around where the case statements start. I believe I'm using boost 1.48. Here's the final version of that function that I modified:

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;
}

BTW, if anyone knows the official channels I can go through to try and get this verified and added to boost please let me know as I hate modifying stuff like this without knowing its full effect.

Hope this helps!

这篇关于如何调试或修复无限循环和堆损坏问题涉及的boost ::进程间managed_shared_memory?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆