この質問を更新し、以下の冒頭にエグゼクティブ サマリーを追加しました。その後、必要に応じて詳細な説明が続きます。提案をありがとう。
Exec Summary: 私は VS の初心者です。継承されたコードに問題があります。コードは VS2008 (XP64) で正常にビルドおよび実行されます。VS2008 や VS2010 を使用する XP64 または W7 では、同じコードがビルドされて実行されないか、ビルドに失敗します。いくつかのコンパイラ オプションを変更した後、XP64 上の VS2010 で問題なく実行することができました。ただし、W7 ではうまくいきません。
最終的に、ヒープが破損していることを発見しました。
ae312i3.3.exe の 0x76e540f2 (ntdll.dll) で未処理の例外: 0xC0000374: ヒープが破損しています。
ヒープの問題を修正する方法をよく知りません。おそらく、別のスレッドまたはプログラムによって使用されているメモリを指す既存のコードのポインターに問題があるか、ntdll.dll ファイルが破損している可能性がありますか?
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 ブール値に戻していませんか? 2つは異なる表現であると思います(一方はTrue / Falseを使用し、もう一方は整数を使用していますか?)これは問題になる可能性がありますか?もしそうなら、VB2008 で問題にならなかったのはなぜですか?**
あるいは、C++ コードが割り当てられたメモリに書き込んでいて、VB に戻るとクラッシュするのかもしれません。
** 最近「Insure++」のことを知り、それを使って問題を追跡しようとしています。その使用に関する提案、他の可能な洞察はありますか? **
提案をいただければ幸いです。再度、感謝します。
. . . . .
上記の概要につながる詳細 (以下):
私は VS2010 の初心者です。エンジニアリング アプリケーション レベル (Python、Fortran、ただし C++ を広範囲に使用してから数十年) でのプログラミングには精通していますが、プロのプログラマーではありません。
すべてVS2008の複数のプロジェクトで構成されるソリューションがあります。プロジェクトは次のとおりです。 Reader (C++ プロジェクト、サード パーティの DLL を使用) Query (C++ プロジェクト、Reader に依存) Main (VB、Reader と Query に依存)。
以下は XP64 OS に適用されます。 ソリューションとプロジェクトは、私以外の誰かによって書かれ、構築され、リリースされました。既存のファイルを取得してコピーを作成し、選択したディレクトリに配置して、VS2010 で開くだけです (私の PC には VS2008 がインストールされていません)。私は正常にビルドすることができました (ただし、多くの警告がありました - 詳細は後で説明します)。しかし、実行可能ファイルを実行すると、ポイントに到達してクラッシュしました。多くの試行錯誤の後、コンパイラ設定を変更すると、次のように問題が解決することがわかりました。
DEBUG 構成でビルドおよび実行されますが、リリースではありません。クエリ プロジェクトのプロパティ ページ / 構成プロパティ / C++ / 最適化 / 最適化 --> リリース (x64) 構成では「速度の最大化 (/O2)」が使用され、デバッグでは「無効 (/Od)」が使用されていることがわかりました -->だから私は「無効(/ Od)」に切り替えました。また、クエリのプロジェクト プロパティ ページ / 構成プロパティ / 全般 / プログラム全体の最適化 --> を「リンク時のコード生成を使用する」に設定する必要がありました。
上記は、VS2010 の XP64 で正常にビルドおよび実行されました。
次に、単純にファイルをコピーし、VS2010 を搭載した W7 マシンにコピーを配置しました。 2010年までにソリューションを開き、ファイルを自動的に「アップグレード」しました。VS2010 を起動すると、次の 4 つの警告が自動的に表示されます。彼らです:
- 演算子 '&' に使用されるオブジェクト型のオペランド。実行時エラーが発生する可能性があります。ファイル 'CobraIFile.vb' の 1845 行目、37 列目。
- 完全に同一エラー
- インスタンスを介した共有メンバー、定数メンバー、列挙型メンバー、または入れ子になった型へのアクセス。修飾式は評価されません。ファイル 'FileWriter.vb' の行 341、列 51
- 演算子「=」に使用されるオブジェクト型のオペランド。「Is」演算子を使用して、オブジェクトの同一性をテストします。ファイル 'FormMain.vb' 内。行 4173、列 32。
1 & 2 の警告のコードは次のとおりです。 ValueStr = String.Empty For iCols = 0 To 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
上記の 3 つのファイルの情報を利用できませんでした (そうする方法を知らなかった)。
W7 で受け取る警告は、XP64 の場合とまったく同じではないにしても、非常に似ています。それらは次のタイプのラインに沿っており、1,600 以上あります。上記の元の 4 つの警告の下に、警告の種類を追加します。W7 ではなく XP64 での実行に成功したので、これらは個別に対処する必要はなく、単なる警告であると想定/期待していました。
- 警告 C4267: 'argument': 'size_t' から 'int' への変換、データが失われる可能性があります。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\atr_StringBase.h 351 1 リーダー
- 警告 C4018: '<' : 符号付き/符号なしの不一致 C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\omi_BlkBitVectTrav.h 69 1 Reader
- 警告 C4244: 'initializing': 'double' から 'float' への変換、データが失われる可能性があります。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\g3d_Vector.h 76 1 リーダー
- 警告 C4244: 'initializing': 'double' から 'float' への変換、データが失われる可能性があります。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\g3d_Vector.h 76 1 リーダー
- 警告 C4800: 'int': 値を bool 'true' または 'false' に強制しています (パフォーマンス警告)。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\exec\win64\6111\include\rgnC_Region.h 219 1 リーダー
- 警告 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) で定義されています。2 番目の定義は無視されます C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Reader\ABQSMAOdbCore_import.lib(ABQSMAOdbCore.dll) Reader
- 警告 LNK4221: このオブジェクト ファイルは、以前に未定義のパブリック シンボルを定義していないため、このライブラリを使用するリンク操作では使用されません。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Reader\ABQSMAOdbCore_import.lib(ABQSMAOdbCore.dll) リーダー
- 警告 C4996: 'sprintf': この関数または変数は安全でない可能性があります。代わりに sprintf_s の使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGS を使用します。詳細については、オンライン ヘルプを参照してください。C:\Users\mcgrete\Documents\iCOBRA\pts\p312\source\312i3.3\Query\Query.cpp 271 1 クエリ
- 警告 MSB8004: 出力ディレクトリが末尾のスラッシュで終わっていません。このビルド インスタンスは、出力ディレクトリを適切に評価できるようにするために必要なため、スラッシュを追加します。C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets 299 6 クエリ
今、私の助けを求める要求に:
明確にする必要があります。上記の警告を詳細に掘り下げたいと思います。ただし、その努力を投資する前にコードを書いていなかったので、私はそうしていません。私は単に真の根本原因を理解しようとしているだけであり、その方向に努力を集中しています。
- 経験した XP64 の問題にがっかりしました。構成に必要な変更が必要なのか、それとも、行った変更が実際には未確認の問題の「回避策」にすぎないのか確信が持てませんでした。
- ソリューションの XP64 VS2010 バージョンが動作可能になると、ソフトウェアがビルドされ、VS2008 と XP64 で正常に動作するため、問題なく W7 に移行されると予想していました。それは悪い仮定ですか?何が欠けている可能性がありますか?
- 構成を再度変更することを検討する必要がありますか、それとも根本的な原因は上記の警告に関連している可能性がありますか? 警告の場合、なぜ VS2008 では明らかに問題にならなかったのですか - VS2010 での変更により、VS2008 では幸運にも痛みを「免れた」実際の実行時エラーが効果的に生成されましたか?
私の限られた経験から、VS2010 に多数のコンパイラのバグまたは関連があることが Web で検索されているように見えるので、続行する方法についてのガイダンスと洞察に感謝します。私の問題に関連するものがあるかどうか、多数の警告が実際に問題であり、コードをかなりクリーンアップする必要があるかどうか、または対処しなければならない構成の問題があるだけかどうかはわかりません。
参考までに - 私がインストールした VS2010 の最新の更新プログラム/SP は VS10SP1-KB2736182.exe です。デバッガーの使用も試みましたが、管理者として VS2010 を実行している場合でも、クエリまたはリーダー プロジェクト コードのブレークポイントで停止できませんでした。W7 には .NET Framework 4.0 Multi-Targeting Pack がインストールされており、私のソリューションは .NET Framework 4.0 Client Profile を使用するように構成されています。
前もって感謝します!
更新 2013 年 3 月 18 日 自分の質問への回答方法がわからなかったので、ここで更新します。
私はまだデバッガを動作させることができませんでした。だから、私は昔ながらの方法でそれを行いました-さまざまなメッセージボックスを追加して、クラッシュしている場所を見つけました。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 を読み取り、出力します... コードは TEM1=vec_temp[index]->size() を読み取り、出力しますMessageBox で値 = 2... コードは bool_out を MessageBox で true (値 = 1) として出力します...その後、コードがクラッシュします。上記のコードを呼び出す行の直後に配置された MessageBox は実行されません。VS2010 からの出力は、「プログラム '[6892] ae312i3.3.exe: Managed (v4.0.30319)' はコード -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 ブール値に戻していませんか? 2つは異なる表現であると思います(一方はTrue / Falseを使用し、もう一方は整数を使用していますか?)これは問題になる可能性がありますか?もしそうなら、なぜVB2008で問題にならなかったのですか?