ここでは非常に奇妙で具体的な問題があります。私たちは一見有効なコードをリンカに入れて、リンカは、有効なptrラベルを削除するなど、いくつかの間違いを犯しています。代わりに値を0に置き換えます。しかしどこでもそうではありません。それはかなり恣意的な点から始まります。有効なコードを無効なコードに置き換えるリンカ
背景:私たちは、(社内のコンパイラのようなアプリケーションで)手作業で生成されたアセンブリのチャンクをまとめ、必要に応じて変数を追加することで、アセンブリに変換されるインタープリタ言語を持っています。これは、現在の形式であるにもかかわらず、もはやそうでない場合、約10年間働いているシステムなので、この方法の妥当性は現在問題ではありません。このアセンブリは、Microsoftアセンブラ(ml.exeまたはMASM)を使用してobjファイルにアセンブルされます。
別の手順で、このobjファイルは、Microsoft Incremental Linkerを使用して、実行可能ファイルを作成するためのいくつかの他のライブラリ(静的ライブラリとdllのインポートライブラリ)とリンクされます。
が続いアセンブリ(.ASM)ファイルの一部であり、それが最初のステップでOBJファイルを作成し、アセンブラ出力:
call _c_rt_strcmp
mov di, 1
mov ebp, esp
cmp ax, 0
je sym2148
dec di
sym2148: mov [ebp+6], di
add esp, 6
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0bb49h
pop ax
mov byte ptr [ebx],al
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 012656h
push ebx
mov eax, OFFSET sym2151
push eax
call _c_rt_strcmp
mov di, 1
mov ebp, esp
cmp ax, 0
je sym2152
dec di
sym2152: mov [ebp+6], di
add esp, 6
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0bb32h
pop ax
mov byte ptr [ebx],al
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 012656h
push ebx
mov eax, OFFSET sym2155
push eax
call _c_rt_strcmp
mov di, 1
mov ebp, esp
cmp ax, 0
je sym2156
dec di
sym2156: mov [ebp+6], di
add esp, 6
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0bb4ah
pop ax
mov byte ptr [ebx],al
mov ebx, dword ptr [_smfv1_ptr]
add ebx, 0126bbh
push ebx
mov eax, OFFSET sym2159
push eax
call _c_rt_strcmp
限り私が見ることができるように、それは、正しいと理にかなっている。私は、これを生成するコードは文字列を比較し、文字列の比較結果に基づいて値を格納すると信じています。それは20-30のセクションなので、最初のビットが投稿される前に10以上のグループがあります、そして最後に私が投稿したビットの約15-20です。
004093D2 call 00629570
004093D7 mov di,1
004093DB mov ebp,esp
004093DD cmp ax,0
004093E1 je 004093E5
004093E3 dec di
004093E5 mov word ptr [ebp+6],di
004093E9 add esp,6
004093EC mov ebx,dword ptr ds:[64174Ch]
004093F2 add ebx,0BB49h
004093F8 pop ax
004093FA mov byte ptr [ebx],al
004093FC mov ebx,dword ptr ds:[64174Ch]
00409402 add ebx,12656h
00409408 push ebx
00409409 mov eax,0
0040940E push eax
0040940F call 00409414
00409414 mov di,1
00409418 mov ebp,esp
0040941A cmp ax,0
0040941E je 00409422
00409420 dec di
00409422 mov word ptr [ebp+6],di
00409426 add esp,6
00409429 mov ebx,dword ptr ds:[0]
0040942F add ebx,0BB32h
00409435 pop ax
00409437 mov byte ptr [ebx],al
00409439 mov ebx,dword ptr ds:[0]
0040943F add ebx,12656h
00409445 push ebx
00409446 mov eax,0
0040944B push eax
0040944C call 00409451
00409451 mov di,1
00409455 mov ebp,esp
00409457 cmp ax,0
0040945B je 0040945F
0040945D dec di
0040945F mov word ptr [ebp+6],di
00409463 add esp,6
00409466 mov ebx,dword ptr ds:[0]
0040946C add ebx,0BB4Ah
00409472 pop ax
00409474 mov byte ptr [ebx],al
00409476 mov ebx,dword ptr ds:[0]
0040947C add ebx,126BBh
00409482 push ebx
00409483 mov eax,0
00409488 push eax
00409489 call 0040948E
実際のクラッシュの場所は0x00409429です:後
は、実行可能クラッシュしたときのVisual C++ 5.0(古い私が知っているが、これは残念ながら、レガシーシステム上にある)を示すことをクラッシュ位置の解体図です。 。
2つのコードは、同じセクションのコードと同じです。ただし、.asmファイルの最初のものはリンカに入り、もう1つはリンカから出てきます。
私は、0のアドレスを参照解除しようとしているため、その場所でクラッシュしています。もちろん、それは失敗するでしょう。また、0x004093D2、0x0040940F、0x0040944C、0x00409489の異なる関数呼び出しを見てみると、最初のものだけが有効です。他の関数呼び出しは単に関数呼び出しを呼び出しているだけです。そして、この破損したコードは、そのファイルで定義されている次の15〜20個の同様のコードセグメントのために継続されます。
両方のセクションで関数呼び出しと不良ポインターの対応する行を見ると、.asmファイルですべてが正しいように見えますが、何らかの形でリンカーはコンパイル時にすべてを破棄しますexe、そして非常に特定の場所では、正しく構築されたファイル内のコードの前に同様のチャンクがあるためです。
"LINK:warning LNK4049:ローカル定義シンボル" _smfv1_ptr "をインポートしました。しかし、それが働いていても同じ警告が表示されていました。
使用されたアセンブラは、ml.exeバージョン6.11であり、リンカーは、Visual C++ 5.0の両方のバージョンであったlink.exeバージョン5.10.7303でした。アセンブルされたコードは正しいと思われるので、私はVisual Studio 2005、2008、および2010からリンカーを試して、変更があるかどうか確認します。
私はこの種のエラーを作り出すことができるとは想像もできませんし、記号がうんざりしているかもしれないと思っていましたが、場所にジャンプします(小さなif文の場合)彼らはリンカーを通過した後に正常に動作します。
リンカの中でシンボルテーブルなどが過負荷になっている可能性はありますか?それは悪い値またはデフォルト値に戻っているだけですか?
私は正常に接続するために投稿をお勧めしたいが、何のポイントは、このような古いツールでは全くありません。リンカー警告を取り除くことに焦点を当てます。あなたのツールを更新してください。 –
Wow、Visual C++ 5.0?私は誰もが少なくともVisual C++ 6に更新したと思っていました...この問題をデバッグしてこの質問を書いた時間は、最近のバージョンのコンパイラでコードをコンパイルすることに費やされました。 –
皆さん、私はそれが古いことを知っています。アップグレードは可能ですが、問題が解決する場合に限り、Visual Studio 2005、2008、および2010のリンカーを使用してテストしたところ、まったく同じ問題で同じ実行可能ファイルが作成されました。 生成されたアセンブリがまったく同じように見えるため、アセンブラは以前のバージョンです。それでも正しい。 – NaimK