【问题标题】:Boost::Program_Options unhandled exception due to access violation由于访问冲突,Boost::Program_Options 未处理的异常
【发布时间】:2011-06-28 20:57:27
【问题描述】:

我有一个程序在 DEBUG 模式下运行良好,但在 RELEASE 模式下,由于访问冲突,我得到一个未处理的异常。我很确定这不是由于空指针。这是调用堆栈:

msvcr90d.dll!memchr(unsigned char * buf=0x0000002c, unsigned char chr='', unsigned long cnt=1243588)  Line 80         Asm
msvcp90d.dll!std::char_traits<char>::find(const char * _First=0x72656d6f, unsigned int _Count=15, const char & _Ch=',')  Line 590 + 0x15 bytes     C++
msvcp90d.dll!std::basic_string<char,std::char_traits<char>,std::_DebugHeapAllocator<char> >::find(const char * _Ptr=0x0012f9e4, unsigned int _Off=0, unsigned int _Count=1)  Line 1796 + 0x2d bytes  C++
Program.exe!boost::program_options::option_description::set_name()  + 0x61 bytes   C++
Program.exe!boost::program_options::option_description::option_description()  + 0x90 bytes C++
Program.exe!boost::program_options::options_description_easy_init::operator()()  + 0x58 bytes           C++
Program.exe!CommandLineInput(int count=2, char * * vector=0x003d3360)  Line 191 + 0xac bytes          C++
Program.exe!main(int argc=4233952, char * * argv=0x00000002)  Line 65535        C++
Program.exe!__tmainCRTStartup()  Line 582 + 0x17 bytes            C

代码:

namespace po = boost::program_options;

int _tmain(int argc, _TCHAR* argv[])
{
        try
        {
            CommandInput (argc, argv); //get command line input
        }
        catch ( std::exception e )
        {
            std::cout << "WARNING: Exception is thrown" << std::endl;
            return 0;
        }
}

void CommandInput (int count, _TCHAR* vector[])
{
        po::options_description desc("Available Parameters");
        std::cout << "\n";
        desc.add_options()
            ("option1", po::value<std::string>(), "description1")
            ("option2", po::value<std::string>(), "description2")
            ("option3", po::value<std::string>(), "description3");

/*
The code breaks at the above line
*/
}

异常如下:

Unhandled exception at 0x1026f09b (msvcr90d.dll) in Program.exe: 0xC0000005: Access violation reading location 0x72656d6f.

【问题讨论】:

  • 问题与工作有关,所以我不愿意发布任何代码。但现在我编辑了我的帖子以插入类似于实际代码的模拟代码。

标签: c++ boost boost-program-options


【解决方案1】:

有些东西很时髦。为什么是 argc 4233952?你能验证这不仅仅是调试器的产物吗?

我建议你重建你的项目,如果这不能修复它,那么在加载所有内容后调试程序并查看“模块”窗口。您可能正在混合不兼容的库,例如DLL/EXE 的发布和调试版本。

特别注意已加载的 CRT 文件,msvcr90d 等。查看已加载的所有 CRT DLL 的文件版本信息,并验证它们都具有相同的版本。

【讨论】:

  • 嗨大卫,我不确定你所说的“调试器的工件”是什么意思。你能澄清一下吗?此外,加载的模块是系统 DLL,所以我认为混合 DEBUG 和 RELEASE DLL 没有问题。 CRT DLL 的版本号相同,但我想我发现了一些可疑的东西。我的程序(在 RELEASE 中运行)加载了 DEBUG CRT DLL 的符号(在“x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456”文件夹中找到),但没有加载“x86_Microsoft.VC90”中 CRT DLL 的符号。 CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456" 文件夹。
  • 另外,argv 的值为 0x00000002...看起来这两个可能已经交换了? argc 为 2 和 argv 为 0x00409AE0 会更有意义。
  • 这是一个有趣的观察。但是,我认为这不是问题的原因,因为访问冲突错误发生在使用任一参数之前(它在 desc.add_options() 行中断)。
  • @Dan,我的意思是调试器试图通过查看 CPU 的寄存器并跟踪隐藏的 EBP 和 ESP 值到堆栈底部来猜测局部变量和调用堆栈的值.函数在其自身运行期间没有义务遵守 EBP 和 ESP,因此如果函数优化寄存器使用或使用非标准位置来维护堆栈信息,调试器将报告有关局部变量的错误信息。
【解决方案2】:

我认为我可能面临的问题是我的程序从 DEBUG CRT DLL 加载符号。到发生访问冲突时,不会加载来自 RELEASE CRT DLL 的符号。我检查了我的程序中涉及的所有项目,它们都使用多线程 DLL (/MD),但它仍在使用它的调试版本。

【讨论】:

  • 我发现了问题。似乎我在项目的属性页中链接到调试 Boost 库(“libboost_regex-vc90-mt-gd-1_42.lib”是罪魁祸首)。我通过转到 Properties->Linker->Input->Additional Dependencies 来修复它,并将库名称更改为指向 Release 版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 2013-11-22
相关资源
最近更新 更多