2017-03-27 9 views
0

私のプログラムが始まる前に発生する特に奇妙な問題をデバッグしています。これはコードが "_start"シンボルで実行を開始する前のロード時に発生します。そして、はい、ELFを手動で変更しています。 ELF形式が悪いという兆候はありません。私はlibelfを使って修正を行い、今までは成功しています。GDBを使用してローダー/リンカーの問題をデバッグする方法

GDBでは、メモリ内の.plt.got、.data(rw data)と.bssセクションを確認し、 "_start"アドレス(またはreadelfによって返されたエントリポイントアドレス)にブレークポイントを設定することができます。私がプログラムを実行する前にplt.gotと.dataがすべてうまく見えます。そして、私はプログラムと私の.dataセクションを実行し、.plt.gotの最後のエントリはゼロで消去されます。

最初は私は考えました.bssの初期化は間違ったアドレスになっていましたが、.bssデータ(2つのグローバル変数)が正しくロードされています。次に、.dataのサイズを変更すると、私の.dataセクションのサイズより常に大きい16バイトで、.bssセクションのサイズを変更しても成長しません。

これをどのようにデバッグできますか? GDBは、実行時にロードされたライブラリに傍受または追加することはできません(または私にはわかりません)。そしておそらく、ローダー/リンカーがいくつかのデータを間違っていたと確信していますメモリ。

ロード/リンク時に実行され、いくつかの初期化を実行し、そのブロック内のどのプロセスがプログラムのページ内のデータの初期化を実行するのか、特にキーオフするものは何ですか? .dataセクションのサイズここで

は、いくつかの関連データである:

$ ld --version 
GNU ld version 2.26.20160125 

gcc --version 
gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) 


Relocation section '.rela.plt' at offset 0x870 contains 24 entries: 
    Offset   Info   Type   Sym. Value Sym. Name + Addend 
000000605f98 000100000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fa0 000200000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fa8 000300000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fb0 000400000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fb8 000500000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fc0 000600000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fc8 000700000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fd0 000800000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fd8 000900000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fe0 000a00000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605fe8 000b00000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605ff0 000c00000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000605ff8 000d00000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606000 000e00000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606008 000f00000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606010 001000000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606018 001200000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.14 + 0 
000000606020 001300000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606028 001400000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606030 001500000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606038 001600000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606040 001700000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606048 001800000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 
000000606050 001900000007 R_X86_64_JUMP_SLO 0000000000000000 [email protected]_2.2.5 + 0 

初期化が([email protected]_2.2.5ある.got.pltの最後のエントリを一掃)0x606050から始まり

や関連セクション:しかし、大規模な私は.dataセクションを作る

[25] .got.plt   PROGBITS   0000000000605f80 00005f80 
     00000000000000d8 0000000000000008 WA  0  0  8 
    [26] .data    PROGBITS   0000000000606058 00006058 
     0000000000000040 0000000000000000 WA  0  0  1 
    [27] .bss    NOBITS   00000000006060e0 00006098 
     0000000000000030 0000000000000000 WA  0  0  32 

注、私はゼロに設定取得.dataセクションよりも大きな0x606050 16バイトから始まるブロックを見ている - これはB TWはすべての私のrwデータを上書きします。

答えて

2

直接ld.soを呼び出すことができます。man 8 ld.soを参照してください。そうすれば、gdbを使ってダイナミックリンカの動作をデバッグすることができます。おそらく、パッケージマネージャーを通じて、ディストリビューションのld.soのデバッグシンボルとソースを取得することができます。それ以外の場合は、この目的のためにソースからビルドすることに興味があるかもしれません。 (ダイナミックリンカをデバッグするのは非常に珍しいことです)。

setting a watchpointに興味があり、PLTエントリをゼロにする場所をキャッチします。ローダをデバッグする方法に関する有用な、このリンクが見つかり

1

https://sourceware.org/glibc/wiki/Debugging/Loader_Debugging

は私の問題は、私は新しいセクションサイズのための私のrw LOADセグメントを調整していなかったということでしたが判明します。だから私を混乱させた?

  1. デバッガ、dddプログラムが実行される前に、そのがメモリにロードされたかのように、プログラムデータを示しています。この時点では何もメモリにロードされていません。 rw .dataセクションは、実際にはそうではないときに、メモリ内にあって正しいと思われました。

  2. プログラムが実行されたら、それもエントリーポイント(_start)で実行を開始する前に、rw .dataセクションはrw .dataセクションが実際にメモリにロードされていなかったのでアウトzero'ed、またはゼロに初期化しているように見えました。それはで、実際、それは常にゼロだったとき、それは変更されたことを示すためにこのメモリを強調しているので

dddがmiss-有数です。

デバッガdddは、実際にメモリにロードされる前にプログラムデータを表示するときには、LOADセグメントサイズを無視する必要があります。

関連する問題