Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get instruction pointer of running application on Unix

Is there a way to get the instruction pointer of a running application Unix?

I have a running process (C++) and want to get its current location, and thereafter in GDB (on a different machine) map the location to source location ('list' command).

like image 537
LK__ Avatar asked Aug 31 '09 13:08

LK__


People also ask

What is instruction pointer in Linux?

The program counter (PC), commonly called the instruction pointer (IP) in Intel x86 and Itanium microprocessors, and sometimes called the instruction address register (IAR), the instruction counter, or just part of the instruction sequencer, is a processor register that indicates where a computer is in its program ...

How do I check running processes in Unix using PID?

The easiest way to find out if process is running is run ps aux command and grep process name. If you got output along with process name/pid, your process is running.

How do you check if Linux process is hung?

strace -p $process_id - if there is not continuous output, that means it is waiting for something. If it waits too long, you could consider that "hung". you could also use the timeout command to set a limit on a command.


2 Answers

On Linux, there is /proc/[pid]/stat. From "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, the 29th field of the output corresponds to the current instruction pointer of the process. For example:

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>
like image 103
Employed Russian Avatar answered Sep 30 '22 14:09

Employed Russian


The instruction pointer can be retrieved on Linux with the following code:

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);
like image 20
steve Avatar answered Sep 30 '22 14:09

steve