C++ boost::进程间\u异常-创建共享\u内存\u对象时出现库\u错误异常
在某些罕见的情况下(事实上是在单个客户端的计算机上),下面的代码会引发异常“库错误””: 在日志文件中: [ERR]失败,出现异常“boost::进程间异常::库错误” Boost v1.58,平台win32,vs13C++ boost::进程间\u异常-创建共享\u内存\u对象时出现库\u错误异常,c++,exception,boost,interprocess,C++,Exception,Boost,Interprocess,在某些罕见的情况下(事实上是在单个客户端的计算机上),下面的代码会引发异常“库错误””: 在日志文件中: [ERR]失败,出现异常“boost::进程间异常::库错误” Boost v1.58,平台win32,vs13 如果你帮我解决这个问题,我将非常感激。提前谢谢你 问题的原因是事件ID为=“6005”的事件,源名称是“系统”Windows日志中的“事件日志”。 如果系统日志不包含至少一个这样的事件,则方法boost::interprocess::winapi::get_last_bootu
如果你帮我解决这个问题,我将非常感激。提前谢谢你 问题的原因是事件ID为=“6005”的事件,源名称是“系统”Windows日志中的“事件日志”。 如果系统日志不包含至少一个这样的事件,则方法boost::interprocess::winapi::get_last_bootup_time()返回false,boost::interprocess::ipctail::windows_bootstamp构造函数抛出异常。 (定义BOOST\u进程间\u已使用\u内核\u引导时间) 因此,清除“系统”windows事件日志就足够了,任何使用Boost共享内存的应用程序都将停止工作 多么糟糕的逻辑:使用windows事件日志的内容。 这个boost ipc实现错误似乎尚未修复(boost_1_61_0) 我在这种情况下的临时解决方法(不重新启动计算机):
使用它并再次尝试使用ipc::shared_memory_object:)问题的原因是事件ID为“6005”且源名称为“System”Windows日志中的“EventLog”。 如果系统日志不包含至少一个这样的事件,则方法boost::interprocess::winapi::get_last_bootup_time()返回false,boost::interprocess::ipctail::windows_bootstamp构造函数抛出异常。 (定义BOOST\u进程间\u已使用\u内核\u引导时间) 因此,清除“系统”windows事件日志就足够了,任何使用Boost共享内存的应用程序都将停止工作 多么糟糕的逻辑:使用windows事件日志的内容。 这个boost ipc实现错误似乎尚未修复(boost_1_61_0) 我在这种情况下的临时解决方法(不重新启动计算机):
使用它并再次尝试使用ipc::shared_memory_object:)该库的一位作者对该问题的许多详细解释:这里:
显然,一个可靠的解决方案是为函数调用定义预处理器常量BOOST\u INTERPROCESS\u SHARED\u DIR\u PATH,一旦机器启动,函数调用总是返回与字符串相同的目录路径。例如,格式化启动时写入的文件的更新时间戳。库的一位作者对此问题进行了许多详细解释:这里: 显然,一个可靠的解决方案是为函数调用定义预处理器常量BOOST\u INTERPROCESS\u SHARED\u DIR\u PATH,一旦机器启动,函数调用总是返回与字符串相同的目录路径。例如,通过格式化启动时写入的文件的更新时间戳。您可以定义BOOST#u进程间(BOOTSTAMP)基于会话(u MANAGER)或BOOST_进程间(u BOOTSTAMP)是(u LASTBOOTUPTIME)切换到注册表或基于WMI的启动时间检测。 或者,您可以使用BOOST\u进程间\u共享\u DIR\u路径,但它在Windows上是无用的,因为它使用硬编码路径。BOOST\u进程间\u共享\u目录\u FUNC是更好的选择,因为它允许您定义返回共享目录路径的函数。您可以定义BOOST\u进程间\u BOOTSTAMP\u是基于会话管理器的,或者BOOST\u进程间\u BOOTSTAMP\u是切换到注册表或基于WMI的启动时间检测的LASTBOOTUPTIME。
或者,您可以使用BOOST\u进程间\u共享\u DIR\u路径,但它在Windows上是无用的,因为它使用硬编码路径。BOOST_INTERPROCESS_SHARED_DIR_FUNC是更好的选项,因为它允许您定义一个返回共享目录路径的函数。是否检查系统中是否已经存在共享内存段?不,这不是必需的,因为函数CNameGenHelper::genniquenameutf8()基于GUID生成一个唯一的名称。我通过ex.get_error_code()和ex.get_native_error()将获取错误代码添加到日志文件中,以获取其他异常信息。现在我正在等待客户端的日志文件。。。感谢您对这个问题的关注!对于catch中的更新行:logError(“因异常\%s\”而失败,错误%d,本机错误%d”,例如what(),例如get_error_code(),例如get_native_error());--在日志文件中:[ERR]失败,出现异常“boost::进程间异常::库错误”,错误1,本机错误0。--错误1-系统错误(来自枚举错误代码)请帮助我…注意:我正在尝试分配相对较小的内存量,只有~8 MB。为什么不在函数中单步执行调试器?这肯定会帮助您找到引发异常的代码。您是否正在检查系统中是否已经存在共享内存段?不,这不是必需的,因为函数CNameGenHelper::genUniqueNameUtf8()会根据GUID生成唯一的名称。我通过ex.get_error_code()和ex.get_native_error()将获取错误代码添加到日志文件中,以获取其他异常信息。现在我正在等待客户端的日志文件。。。感谢您对这个问题的关注!对于catch中的更新行:logError(“因异常\%s\”而失败,错误%d,本机错误%d”,例如what(),例如get_error_code(),例如get_native_error());--在日志文件中:[ERR]失败,出现异常“boost::进程间异常::库错误”,错误1,本机错误0。--错误1-系统错误(来自枚举错误代码)请帮助我…注意:我正在尝试分配相对较小的内存量,只有~8 MB。为什么不在函数中单步执行调试器?这肯定会帮助您找到抛出异常的代码。
namespace ipc = boost::interprocess;
ipc::shared_memory_object m_shm;
...
bool initAsServer(size_t sharedMemSize)
{
ipc::permissions perm;
perm.set_unrestricted();
try
{
m_shm = ipc::shared_memory_object(
ipc::create_only,
CNameGenHelper::genUniqueNameUtf8().c_str(), // static std::string genUniqueNameUtf8()
ipc::read_write, perm);
}
catch(const ipc::interprocess_exception& ex)
{
logError("failed with exception \"%s\"", ex.what());
return false;
}
...
}
bool fixBoostIpcSharedMem6005issue() const
{
bool result = false;
HANDLE hEventLog = ::RegisterEventSourceA(NULL, "EventLog");
if(hEventLog)
{
const char* msg = "simple boost shared memory fix for 6005";
if(::ReportEventA(hEventLog, EVENTLOG_INFORMATION_TYPE, 0, 6005, NULL, 1, 0, &msg, NULL))
result = true;
::DeregisterEventSource(hEventLog);
}
return result;
}