2009-08-31 30 views
4

実行中のアプリケーションの命令ポインタを取得する方法はありますか?Unix上で実行中のアプリケーションの命令ポインタを取得

私は実行中のプロセス(C++)を持っていて、現在の場所を取得したい、その後はGDB(別のマシン上)で場所をソース場所( 'list'コマンド)にマップします。

+0

これはOS特有です。どのOSを使用していますか? – mark4o

+0

この特定のものはHPUX用です。しかし、Linuxにとっても面白いだろう。 –

答えて

6

Linuxの場合、/proc/[pid]/statがあります。 "man proc"から :

stat Status information about the process. This is used by 
     ps(1). It is defined in /usr/src/linux/fs/proc/array.c. 
     ... 
     kstkeip %lu 
     The current EIP (instruction pointer). 

AFAICT、出力の29フィールドは、プロセスの現在の命令ポインタに相当します。例えば:

gdb date 
GNU gdb Red Hat Linux (6.0post-0.20040223.20rh) 
Copyright 2004 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB. Type "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu"...(no debugging symbols found)...Using host libthread_db library "/lib64/tls/libthread_db.so.1". 

(gdb) set stop-on-solib-events 1 
(gdb) run 
(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...[Thread debugging using libthread_db enabled] 
[New Thread 182896391360 (LWP 27968)] 
(no debugging symbols found)...Stopped due to shared library event 
(gdb) c 
[Switching to Thread 182896391360 (LWP 27968)] 
Stopped due to shared library event 
(gdb) where 
#0 0x00000036b060bb20 in _dl_debug_state_internal() from /lib64/ld-linux-x86-64.so.2 
#1 0x00000036b060b51c in _dl_init_internal() from /lib64/ld-linux-x86-64.so.2 
#2 0x00000036b0600f72 in _dl_start_user() from /lib64/ld-linux-x86-64.so.2 
#3 0x0000000000000001 in ??() 
#4 0x0000007fbff62728 in ??() 
#5 0x0000000000000000 in ??() 
(gdb) shell cat /proc/27968/stat 
27968 (date) T 27839 27968 8955 34817 27839 4194304 42 0 330 0 0 0 0 0 18 0 0 0 1881668573 6144000 78 18446744073709551615 4194304 4234416 548680739552 18446744073709551615 234887363360 0 0 0 0 18446744071563322838 0 0 17 0 0 0 0 0 0 0 
(gdb) p/a 234887363360 <--- the value of 29th field 
$1 = 0x36b060bb20 <_dl_debug_state_internal> 
+0

タスクがブロックされていないが実行中の状態(gdbからブレークポイント/ ptraceでブロックした場合)の "kstkeip%lu現在のEIP"フィールドは正しいですか?このフィールドの印刷は、 'ptrace_may_access(task、PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT);' - http://lxr.free-electrons.com/source/fs/proc/array.c?v=4.4#L396;フィールドがいっぱいになったときはわかりません(リクエストや最後のタスクがブロックされていませんか?)。 – osgx

0

とにかくGDBを使用している場合は、単にこのような実行中のプロセスに自分自身を添付することができます:

programはあなたがデバッグしている実行可能ファイルの名前であり、そして 1234がPIDである
gdb program 1234 

。プロセスをデバッグするには、gdbのすべての機能を使用できます。

+0

私はアプリケーションが動作しているマシンにgdbを持っていません。 マッピングを実行した後で別のマシンで使用します。 –

+0

ああ...その場合:申し訳ありませんが、わかりません。 –

1

現在の命令ポインタを取得するには、プロセスまたはスレッドを一時的に停止する必要があります。 ptrace()または(HP-UXの場合)ttrace()のプロセスにアタッチして、レジスタにアクセスすることで実行できます。

2

命令ポインタは、次のコードでLinux上で検索することができる。

pid_t traced_process; 
struct user_regs_struct regs; 

ptrace(PTRACE_ATTACH, traced_process, NULL, NULL); 
ptrace(PTRACE_GETREGS, traced_process, NULL, &regs); 

printf("EIP: %lx\n", regs.eip); 
関連する問題