【问题标题】:VS2008 to VS2010 - Problematic Configuration and Upgrade - NewbieVS2008 到 VS2010 - 有问题的配置和升级 - 新手
【发布时间】:2013-03-15 20:59:09
【问题描述】:

我已在下面开始使用执行摘要更新了这个问题。然后,如果需要,将提供大量详细信息。感谢您的建议。

执行摘要: 我是VS的新手。我对一些继承的代码有疑问。代码在 VS2008 (XP64) 上构建和执行良好。相同的代码要么构建但不运行,要么无法在 XP64 或 W7 上构建 VS2008 和/或 VS2010。在更改了一些编译器选项后,我设法让它在 XP64 上的 VS2010 上运行而没有问题;但是,在 W7 上,没有运气。

我最终发现堆正在损坏。

ae312i3.3.exe 中 0x76e540f2 (ntdll.dll) 处的未处理异常:0xC0000374:堆已损坏。

我不熟悉如何考虑修复堆问题;也许现有代码中指向另一个线程或程序正在使用的内存的指针存在问题,损坏的 ntdll.dll 文件,其他?

重新启动 PC 以检查 ntdll.dll 是否已损坏并没有帮助。修改调试设置,收到如下反馈:

HEAP[ae312i3.3.exe]:指定给 RtlSizeHeap 的地址无效(0000000000220000, 000000002BC8BE58) Windows 已在 ae312i3.3.exe 中触发断点。

这可能是由于堆损坏,这表明 ae312i3.3.exe 或其已加载的任何 DLL 中存在错误。这也可能是由于用户在 ae312i3.3.exe 获得焦点时按 F12。

似乎当它崩溃时,C++ 正在将一个布尔变量返回到表单的表达式

While (myQueryFcn(inputvars))

  • 问题:

那么,它不是将 C++ 布尔值返回到 VB 布尔值吗?我确实相信这两者是不同的表示形式(一个使用 True/False,另一个使用整数?)这可能是一个问题吗?如果是这样,为什么它在 VB2008 中不是问题?**

或者,可能是 C++ 代码写入了分配的内存,返回 VB 后崩溃???

** 我最近了解到“Insure++”,并将尝试使用它来追踪问题。关于其使用的任何建议,其他可能的见解? **

如果有任何建议,我将不胜感激。再次感谢。

。 . . . .

导致上述摘要的详细信息(如下):

我是VS2010的新手;熟悉工程应用级别的编程(Python、Fortran,但自从我广泛使用 C++ 以来已经有几十年了),但不是专业程序员。

我有一个由多个项目组成的解决方案,全部在 VS2008 中。项目有: 阅读器(C++ 项目;利用第 3 方 DLL) 查询(C++ 项目;取决于 Reader) Main(VB;取决于 Reader 和 Query)。

以下适用于 XP64 操作系统。 解决方案和项目是由我以外的其他人编写、构建和发布的。 我已经获取了现有文件,并制作了一个副本,放在我选择的目录中,然后在 VS2010 中打开(我的 PC 上没有安装 VS2008)。我能够成功构建(尽管有很多警告 - 稍后会详细介绍);但是当我运行可执行文件时,它会到达一个点并崩溃。经过多次试验和错误,我发现修改编译器设置为我解决了以下问题:

它将在 DEBUG 配置中构建和执行,但不会在 Release 中。我发现在查询项目属性页/配置属性/C++/优化/优化-> 发布(x64)配置使用“最大化速度(/O2)而调试使用“禁用(/Od)”->所以我切换到'禁用(/ Od)。 另外,Query的项目Property Page / Configuration Properties / General / Whole Program Optimization --> 需要设置为'Use Link Time Code Generation'。

以上构建并在VS2010的XP64上运行成功。

接下来,我只是简单地复制了文件,然后将副本放在装有 VS2010 的 W7 机器上。 通过 2010 打开解决方案,它会自动“升级”文件。当我启动 VS2010 时,它会自动显示以下 4 个警告。它们是:

  1. 用于运算符“&”的对象类型的操作数;可能会发生运行时错误。在文件“CobraIFile.vb”中,第 1845 行,第 37 列。
  2. 完全一样的错误
  3. 通过实例访问共享成员、常量成员、枚举成员或嵌套类型;将不评估限定表达式。在文件“FileWriter.vb”中,第 341 行,第 51 列
  4. 用于运算符“=”的对象类型的操作数;使用“Is”运算符来测试对象身份。在文件'FormMain.vb'中;第 4173 行,第 32 列。

1 和 2 中的警告代码如下 ValueStr = String.Empty 对于 iCols = 0 到 DGrid.Columns.Count - 1 ValueStr &= DGrid.Item(iCols, iRows).Value & ";" // 这是警告线!!! 下一个

警告 3 的代码:

    With FormMain
        WriteComment("")
        WriteComment("Generated by :")
        WriteComment("")
        WriteComment("  Program         : " & .PROGRAM.ToUpper) // THIS IS WARNING LINE!!!

警告 4 的代码:

    ' Compare material against the material table
    For iRowMat As Integer = 0 To matCount - 1
        ' Ignore new row
        If Not .Rows(iRowMat).IsNewRow Then
            ' Check material description
            // LINE BELOW IS WARNING LINE!!!
            If .Item("ColMatDesc", iRowMat).Value = matDesc Then
                DataGridMatProp.Item("ColMatIdx", iRow).Value = .Item("ColMatFile", iRowMat).Value
                Exit For
            End If ' Check description
        End If ' Check new row
    Next iRowMat

当我构建解决方案时,它将成功构建且没有错误(但出现许多警告),并且当我运行可执行文件时,它成功加载 GUI,但在执行查询或阅读器项目时有时会崩溃(在采取带有 gui 按钮的操作)以及以下信息:

    C:\Users\mcgrete\AppData\Local\Temp\WER5D31.tmp.WERInternalMetadata.xml
    C:\Users\mcgrete\AppData\Local\Temp\WER68E6.tmp.appcompat.txt
    C:\Users\mcgrete\AppData\Local\Temp\WER722A.tmp.mdmp

我无法利用上述三个文件中的信息(不知道如何考虑这样做)。

我在 W7 中收到的警告与 XP64 中的非常相似/如果不相同的话;它们大致为以下类型,其中有1,600多种。添加到上面之前列出的原始 4 个警告下方的警告类型。由于我在 XP64 而不是在 W7 上成功运行,我假设/希望这些不需要单独解决,而只是警告。

  1. 警告 C4267:'argument':从 'size_t' 转换为 'int',可能会丢失数据。 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\atr_StringBase.h 351 1 个阅读器
  2. 警告 C4018:“
  3. 警告 C4244:“正在初始化”:从“double”转换为“float”,可能会丢失数据。 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\g3d_Vector.h 76 1 阅读器
  4. 警告 C4244:“正在初始化”:从“double”转换为“float”,可能会丢失数据。 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\g3d_Vector.h 76 1 阅读器
  5. 警告 C4800:“int”:强制将值设置为 bool“true”或“false”(性能警告)。 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\rgnC_Region.h 219 1 阅读器
  6. 警告 LNK4006: "public: class ddr_ShortcutImpl const & __cdecl cow_COW,struct cow_Virtual > >::ConstGet(void)const " (?ConstGet@?$cow_COW@V?$ddr_ShortcutImpl@VkmaC_Material@@@@U?$cow_Virtual @V?$ddr_ShortcutImpl@VkmaC_Material@@@@@@@@QEBAAEBV?$ddr_ShortcutImpl@VkmaC_Material@@@@XZ) 已在 ABQDDB_Odb_import.lib(ABQDDB_Odb.dll) 中定义;第二个定义被忽略 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Reader\ABQSMAOdbCore_import.lib(ABQSMAOdbCore.dll) Reader
  7. 警告 LNK4221:此目标文件未定义任何以前未定义的公共符号,因此任何使用此库的链接操作都不会使用它。 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Reader\ABQSMAOdbCore_import.lib(ABQSMAOdbCore.dll) 阅读器
  8. 警告 C4996:“sprintf”:此函数或变量可能不安全。考虑改用 sprintf_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS。详细信息请参见在线帮助。 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Query\Query.cpp 271 1 查询
  9. 警告 MSB8004:输出目录不以斜杠结尾。此构建实例将添加斜杠,因为它需要允许正确评估输出目录。 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets 299 6 查询

现在我请求帮助:

我必须澄清一下,我愿意详细研究上面的警告;但是,我没有这样做,因为在投入这些精力并且没有编写代码开始之前,我只是想了解可能是真正的根本原因,然后将精力集中在那个方向上。

  1. 我对遇到的 XP64 问题感到失望,不确定是否需要对配置进行更改,或者我所做的更改是否实际上只是对未识别问题的“解决方法”?
  2. 我预计一旦 XP64 VS2010 版本的解决方案可以运行,它会毫无问题地转移到 W7,因为软件在 VS2008 和 XP64 上构建和运行良好。这是一个糟糕的假设吗?我可能缺少什么?
  3. 我是否应该考虑再次尝试修改配置,或者根本原因可能与上述警告有关?如果是警告,为什么它们在 VS2008 中显然不是问题 - VS2010 中的更改是否有效地导致了实际运行时错误的产生,而在 VS2008 中我幸运地“免除”了痛苦?

感谢任何有关如何继续的指导和见解,因为根据我有限的经验,从网络上的搜索中可以看出 VS2010 中存在许多编译器错误或相关错误。不确定是否有任何与我的问题有关,如果大量警告实际上是一个问题并且代码需要大量清理,或者是否只是一些我可能需要处理的配置问题。

仅供参考 - 我安装的 VS2010 的最新更新/SP 是 VS10SP1-KB2736182.exe。我也尝试过使用调试器,但无法让它在我的 Query 或 Reader 项目代码中的断点处停止,即使在以管理员身份运行 VS2010 时也是如此。 W7 确实安装了 .NET Framework 4.0 多目标包,并且我的解决方案配置为使用 .NET Framework 4.0 客户端配置文件。

提前致谢!

2013 年 3 月 18 日更新 我不知道如何回答我自己的问题,所以这里有一个更新。

我仍然无法让调试器工作;所以,我用老式的方式来做——添加了各种 MessageBox 来找到它崩溃的地方。 A. Main.vb 程序调用 'Query' 项目中的一个函数

OdbQueryGetIncrement(str_out, vec_ptr)

B.然后,函数 100% 执行,试图返回一个布尔值...这里是添加了一些老式调试代码的代码...

    //Gets the next item in a list.
    // Returns false if there is the vector is empty.
    // NOTE: Once an element is returned it is removed from the list.
    bool __stdcall OdbQueryGetItem(
                    char* &str_out,  // RETURN Next item in list.
            void * vec_ptr, // Pointer to the vector of pointers.
            int index)  // Index of pointers vector to return next item of.
    {
        // Cast the point into an array of pointers
        std::vector<std::string>* *vec_temp = (std::vector<std::string>* *) vec_ptr;
        bool bool_out = false;

        char vectempsize[1000];
        int TEM1;
        char temp[1000];
        TEM1 = vec_temp[index]->size();
        // Check vector is valid
        if (vec_temp) {
            if(vec_temp[index]->size() >= index)
            {
                sprintf(temp,"value: %d\n",(int)bool_out);
                ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - bool_out", MB_ICONINFORMATION);
                sprintf(temp,"value: %d\n",(int)index);
                ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - index", MB_ICONINFORMATION);
                sprintf(vectempsize,"value: %d\n",(int)TEM1);
                ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - index", MB_ICONINFORMATION);
            }

            if (!vec_temp[index]->empty()) {
                // Get the next item in the list
                std::string item = vec_temp[index]->front();
                // Initialise ouput string
                str_out = (char*)malloc( item.size()*sizeof(char) );
                sprintf(str_out, "%s", item.c_str());

                ::MessageBoxA(0,(LPCSTR) str_out, (LPCSTR) "hello", 0);
                // Remove first item from the vector
                vec_temp[index]->erase(vec_temp[index]->begin());
                bool_out = true;
            }
        }

      sprintf(temp,"value: %d\n",(int)bool_out);
      ::MessageBoxA(0, (LPCSTR) temp, (LPCSTR) "OdbQuery.dll - bool_out", MB_ICONINFORMATION);
      return bool_out;
    }

代码以预期的 bool_out=false 开头(使用 MessageBox value=0 输出验证) 代码使用 MessageBox 读取并输出 index = 2... 该代码使用 MessageBox 读取并输出 TEM1=vec_temp[index]->size() 作为 value=2 ... 代码使用 MessageBox 将 bool_out 输出为 true (value=1)... 然后,代码崩溃。在调用上述代码的行之后放置的 MessageBox 永远不会被执行。 VS2010 的输出是“程序 '[6892] ae312i3.3.exe: Managed (v4.0.30319)' has exited with code -2147483645 (0x80000003).”

我不知道为什么从这个函数返回时执行会死掉。 编译器设置或错误是否存在一些问题?

感谢任何帮助!

更多信息

您好,我修改了“属性”页面上的一些设置,试图让调试器为我提供更多信息。这导致更多信息如下:

ae312i3.3.exe 中 0x76e540f2 (ntdll.dll) 处的未处理异常:0xC0000374:堆已损坏。

我不熟悉如何考虑修复堆问题;也许现有代码中指向另一个线程或程序正在使用的内存的指针存在问题,损坏的 ntdll.dll 文件,其他?

我会尝试重新启动 PC 看看是否有帮助,虽然我对此没有什么希望......没有帮助。

在调试器中找到“启用非托管代码调试”选项,检查它;清洁;重建;运行调试...

输出更具描述性--

HEAP[ae312i3.3.exe]:指定给 RtlSizeHeap 的地址无效(0000000000220000, 000000002BC8BE58) Windows 已在 ae312i3.3.exe 中触发断点。

这可能是由于堆损坏,这表明 ae312i3.3.exe 或其已加载的任何 DLL 中存在错误。这也可能是由于用户在 ae312i3.3.exe 获得焦点时按 F12。

似乎当它崩溃时,C++ 正在将一个布尔变量返回到表单的表达式

While (myQueryFcn(inputvars))

那么,它不是将 C++ 布尔值返回到 VB 布尔值吗?我确实相信这两者是不同的表示形式(一个使用 True/False,另一个使用整数?)这可能是一个问题吗?如果是这样,为什么它在 VB2008 中不是问题?

【问题讨论】:

  • 作为一个也写过很长帖子的人,我会尽量温和地说出来,但是这个问题太长了。这可能就是为什么你没有得到太多反馈的原因,即使你几天前第一次问过。 Visual Studio 是一款我非常了解的产品,但我真的没有时间坐下来仔细阅读整个问题。我真的需要知道我是否可以帮助您解决问题吗?我强烈建议在您的问题顶部附上“执行摘要”或“摘要”。将其余部分留在那里,以便我们仅在需要时阅读。

标签: visual-studio-2010 debugging upgrade


【解决方案1】:

我解决了自己的问题;问题的根本原因如下。

根本原因:

  1. VisualBasic (VB) 调用 C++。

  2. VB 创建了一个字符串并发送到 C++。以前的开发人员/编码人员在 C++ 中为相同的字符串分配了内存。

  3. 当 C++ 代码执行结束时,C++ 似乎已经终止了 VB 和 C++ 建立的内存分配。

解决方案: 1. 删除了 C++ 代码中的内存分配(下)。

str_out=(char*)malloc( (item.size()+1)*sizeof(char) );
  1. 修改 VB 代码以使用 StringBuilder 类型,而不是字符串。

    Dim str_out As StringBuilder = New StringBuilder(5120)

见:return string from c++ function to VB .Net

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 2011-03-30
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    相关资源
    最近更新 更多