InitializeCriticalSection在一个项目中工作,但在另一个项目中失败

阿兰

在Windows 10 x64上使用Visual Studio 2019 Professional。我有几个C ++ DLL项目,其中一些是多线程的。我将CRITICAL_SECTION对象用于线程安全。

在DLL1中:

CRITICAL_SECTION critDLL1;
InitializeCriticalSection(&critDLL1);

在DLL2中:

CRITICAL_SECTION critDLL2;
InitializeCriticalSection(&critDLL2);

当我将critDLL1与EnterCriticalSection一起使用时,LeaveCriticalSection_DEBUGNDEBUG模式下一切都很好但是,当我使用critDLL2时,我的“ ntdll.dll”中存在访问冲突NDEBUG(尽管不是_DEBUG)。

NDEBUG模式下弹出消息框后,我终于能够跟踪到第一次使用的问题EnterCriticalSection

是什么导致该CRITICAL_SECTION项目在一个项目中失败而在其他项目中起作用?MSDN页面是没有帮助的。

更新1

比较DLL1(有效)和DLL2(无效)的项目设置后,我不小心使DLL2正常工作。我已通过还原到早期版本(崩溃)并进行项目更改(没有崩溃!)来确认这一点。

这是设置:

Project Properties > C/C++ > Optimization > Whole Program Optimization

将此设置为Yes (/GL),我的程序崩溃。将其更改为No,它可以正常工作。什么是/GL开关做和为什么它可能导致这个崩溃?

更新2

@Acorn的出色回答和@RaymondChen的评论提供了线索,以查找并解决问题。有两个问题(都是程序员错误)。

问题1

Whole Program Optimzation(wPO)的假设是MSVC编译器正在编译“整个程序”。对于我的DLL项目,这是一个不正确的假设,该DLL项目在内部使用第3方库,然后由用Delphi编写的外部应用程序使用。此设置Yes (/GL)默认设置为,但应为No这感觉像是Visual Studio中的错误,但是无论如何,程序员都需要意识到这一点。我不知道该怎么做的所有细节WPO,但是至少对于要由其他应用程序使用的DLL,应该更改默认值。

问题2

严重的程序员错误。这是对第3方库的调用,该库返回了128字节的ASCII码,这是错误的:

// Before
// m_config::acSerial defined as "char acSerial[21]"
(void) m_pLib->GetPara(XPARA_PRODUCT_INFO, &m_config.acSerial[0]);
EnterCriticalSection(&crit);  // Crash!

// After
#define SERIAL_LEN 20
// m_config::acSerial defined as "char acSerial[SERIAL_LEN+1]"
//...
char acSerial[128];
(void) m_pLib->GetPara(XPARA_PRODUCT_INFO, &acSerial[0]);
strncpy(m_config.acSerial, acSerial, max(SERIAL_LEN, strlen(acSerial)));
EnterCriticalSection(&crit);  // Works!

现在很明显的错误是,第三方库没有将设备的序列号复制到char*我提供的设备中...而是将128个字节复制到了我char*对内存中所有连续的东西的踩踏中acSerial之前没有注意到这一点,因为这是m_pLib->GetPara(XPARA_PRODUCT_INFO, ...)第3方库中的第一个调用,而在那一点上其余的连续数据大多为NULL。

问题从来都不与CRITICAL_SECTION我感谢Acorn和RaymondChen ...理智已恢复到宇宙的这个角落。

橡子

如果您的程序在WPO下崩溃(优化假设您正在编译的是整个程序),则意味着该假设不正确或优化器最终利用了一些以前未定义的行为(未应用优化) ),即使该假设是正确的。

通常,除非您确实确定自己满足要求,否则请避免启用优化。

为了进一步分析,请提供MRE

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Angular 语言服务在一个项目中工作而不是另一个项目

在另一个项目中引用样式文件

尽管代码在另一个项目中为我工作,但由于“ fatJar任务”,Gradle构建失败

如何从另一个项目中的一个项目调用方法?

在另一个项目的xhtml中使用一个项目中的bean

等级:无法从另一个项目访问一个项目中定义的配置

Android Studio 在一个项目中看到设备,但在另一个项目中看不到

在另一个项目中使用项目中的工具 (c#)

如何在java中的另一个项目中使用一个项目中的类?

使用BigQuery Python API在一个项目中创建视图,引用另一个项目中的表

AsyncDisplayKitcalculateLayoutThatFits()函数可在一个项目中使用,而不在另一个项目中使用

将一个项目中的Css Intellisense包含在另一个项目中

R Markdown在一个项目中找不到.bib文件,而在另一个项目中正常工作

AVAudioPlayer不会在具有所有正确参数的一个项目中播放音频,但在另一个项目中可以正常工作

从另一个项目中选择一个包

从另一个项目中调用一个函数

我想使用另一个库的项目中的一个库

如何在另一个项目中引用一个类?

已安装自定义软件包,但在另一个项目中找不到

当 laravel 项目在另一个项目中时访问命名空间

在另一个Maven项目中使用Maven实施项目

将多个项目本身添加为另一个项目中的依赖项

将Listview项目拖放到另一个项目中

在项目上更改值也会在另一个项目中更改-RecyclerView Android

如何在当前项目中在Angular中创建另一个项目

在我的qmake项目中包含另一个项目的qmake文件

仅使用gitignore的另一个项目中的完全独立的Git项目

图书馆?静态的?动态?还是框架?在另一个项目中的项目

如何从另一个项目更新recyclerview项目中的数据?