Obtenir le pointeur d’instruction de l’application en cours d’exécution sur Unix

Est-il possible d’obtenir le pointeur d’instruction d’une application en cours d’exécution Unix?

J’ai un processus en cours (C ++) et je veux obtenir son emplacement actuel, puis dans GDB (sur un autre ordinateur), mapper l’emplacement sur l’emplacement source (commande ‘list’).

Sur Linux, il y a /proc/[pid]/stat . De "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, le 29ème champ de la sortie correspond au pointeur d’instruction en cours du processus. Par exemple:

 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 dissortingbute 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> 

Le pointeur d’instruction peut être récupéré sous Linux avec le code suivant:

 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); 

Vous devrez arrêter temporairement le processus ou le thread pour obtenir son pointeur d’instruction en cours. Vous pouvez le faire en vous connectant au processus avec ptrace() ou (sous HP-UX) ttrace() et en accédant aux registres.

Si vous utilisez gdb de toute façon, vous pouvez simplement vous attacher à un processus en cours d’exécution comme ceci:

 gdb program 1234 

program est le nom de l’exécutable que vous déboguez et 1234 est le PID. Vous pouvez ensuite utiliser toutes les fonctionnalités de gdb pour déboguer le processus.