我在Boost.Interprocess(v1.66)库中遇到问题,我在C / C ++库中使用它,我在C#中通过编组使用(从C#调用C本机代码)。
如果我使用Boost.Interprocess named_semaphore进行进程间的同步,我发现了问题。 (在open_or_create模式下)
如果我将C / C ++ lib与其他本机C / C ++代码一起使用,一切正常(在最新的Windows 10,Linux(4+内核)甚至Mac OS X(> = 10.11)下)。 问题发生在Windows下 - 使用C#我有C ++代码的C包装器。如果我使用简单的自己构建EXE的编组 - >一切正常!但是如果我在第三方应用程序中使用相同的C#代码(使用相同的C lib)作为DLL插件,我在named_semaphore中从get_bootstamp获得了segfault。
所以我有第三方C#SW为其创建插件(C#DLL)。在该插件中,我通过编组使用我的C库。编组工作在测试C#项目中工作正常(它只从C lib调用C函数)但在第三方软件中使用相同的代码段错误。
C图书馆工作流程:
C#代码具有相同的工作流程。
发现问题
问题发生在boost::interprocess::ipcdetail::get_booststamp(在named_semaphore中调用)。这里:
struct windows_bootstamp
{
windows_bootstamp()
{
//Throw if bootstamp not available
if(!winapi::get_last_bootup_time(stamp)){
error_info err = system_error_code();
throw interprocess_exception(err);
}
}
//Use std::string. Even if this will be constructed in shared memory, all
//modules/dlls are from this process so internal raw pointers to heap are always valid
std::string stamp;
};
inline void get_bootstamp(std::string &s, bool add = false)
{
const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get();
if(add){
s += bootstamp.stamp;
}
else{
s = bootstamp.stamp;
}
}
如果我调试到行
const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get()
booststamp.stamp不可读。大小设置为31,容量设置为一些奇怪的值(如19452345),数据不可读。如果我走到
s += bootstamp.stamp;
发生了段错误!
找到原因
我再次调试并将调试点设置为windows_bootstamp构造函数条目,但没有命中,因此标记未初始化(我猜)。
确认
如果我将get_bootstamp更改为
inline void get_bootstamp(std::string &s, bool add = false)
{
const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get();
std::string stamp;
winapi::get_last_bootup_time(stamp);
if(add){
s += stamp;
}
else{
s = stamp;
}
}
重新编译我的lib和exe - 一切正常(没有任何问题)。
我的问题是 - 我做错了什么?我非常彻底地阅读了Boost.Interprocess文档但是没有关于我的问题的建议/警告(是的,在Interprocess doc中有&#34; COM Initialization&#34;但它似乎没有帮助。)
或者它只是Boost.interprocess中的一个错误,我可能会将它报告给Boost bug跟踪器?
注意 - 如果我手动启动服务器(在运行C#代码之前)它没有segfaults