8

GDBとカーネルスペースに割り当てられたいくつかのバッファで問題が発生しています。バッファは、メモリの連続ブロックを割り当てることになっているカーネルモジュールによって割り当てられ、次に、mmap()呼び出しを介してメモリがユーザースペースにマップされます。ただし、GDBはいつでもこれらのブロックにアクセスできないようです。たとえば、GDBでブレークポイントに到達した後:

(gdb) x /10xb 0x4567e000
0x4567e000:     Cannot access memory at address 0x4567e000

ただし、/ proc // smapsでアプリケーションの現在マップされているメモリ領域を見ると、次のことがわかります。

4567e000-456d3000 rwxs 8913f000 00:0d 883        /dev/cmem
Size:                340 kB
Rss:                 340 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Swap:                  0 kB

私がこれを調べている理由は、実行中のある時点で、このバッファアドレス(または同様の方法で割り当てられた別のアドレス)がSIGSEGVを引き起こすためです。

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x49aea490 (LWP 652)]
0x402e4ea8 in fwrite () from /lib/libc.so.6
(gdb)
(gdb)
(gdb) where
#0  0x402e4ea8 in fwrite () from /lib/libc.so.6
#1  0x000eb394 in EncryptedWriter::Write (this=0x198600, buffRaw=0x4567e000 <Address     0x4567e000 out of bounds>, iLenRaw=719) at encrypted_writer.cpp:397
#2  0x0006b0f4 in EncryptionWrapper::Write (this=0x3ab2698, buffer=0x4567e000, size=719) at encryption.cpp:54

このセグメンテーション違反は、クラッシュするまでバッファが頻繁に使用されていたにもかかわらず発生し、/ proc//smapsファイルはこのバッファが上記のようにマップされていることを示しています。

なぜこれが発生するのか、そしてマッピングが/ procでは有効であるように見えるが、GDBでは決して有効ではないのかについて私は完全に途方に暮れています。

4

2 に答える 2

8

gdbが必要なメモリにアクセスできない理由については、Linuxではptrace()を介してI/Oメモリにアクセスできないと思います。

cmemk.c(linuxutils_2_25.tar.gzで見つけました)によると mmap()は実際に問題のメモリにVM_IOフラグを設定します。

gdbからこのメモリにアクセスするには、このメモリを読み取る関数をプログラムに追加し、gdbにこの関数を呼び出させます。

于 2010-09-03T23:22:55.223 に答える
2

別のスレッドでのinspecting- mmaped -addresses-using-gdbの説明、特にここでの回答を参照してください。vm_operations_structモジュールのmmap実装でVMAにカスタムを追加できるはずです。

Linuxカーネルのmm/memory.cも参照してください。失敗すると、コードはメモリにアクセスするためにドライバget_user_pages()のカスタム実装を呼び出そうとします。vma->vm_ops->access

于 2014-12-13T20:32:12.493 に答える