2017-08-06 10 views
3

Je cherche une façon arch-agnostique d'obtenir le pointeur d'instruction (compteur de programme AKA) de la dernière instruction tentée (ou passée) sur laquelle SIGTRAP a été généré, du point de vue d'un traceur ptrace.Existe-t-il une façon arch-agnostique d'obtenir un pointeur d'instruction sur SIGTRAP?

Une manière dépendante de l'arche est d'utiliser PTRACE_GETREGS et de sélectionner par ex. EIP sur i386, x86_64 sur RIP, PC sur ARM etc ..

J'ai essayé d'utiliser siginfo.si_addr ainsi que siginfo.si_ptr de PTRACE_GETSIGINFO struct -returned, mais ces valeurs apparaissent complètement faux (4 chiffres hexadécimaux au lieu de 8, et non même semblable à la vraie adresse), donc ils ne semblent pas être ce dont j'ai besoin.

Dans Linux J'ai aussi essayé de faire usage de champ 30 /proc/<pid>/task/<tid>/stat, que le noyau remplit fs/proc/array.c:do_task_stat() avec KSTK_EIP(task) (qui, en dépit d'être nommé x86-centrique, semble définie pour beaucoup d'autres architectures). Mais pour une raison quelconque sur mon ARMv6 Linux 4.9.28+ (Raspbian 8), j'obtiens des zéros pour le compteur de programme et le pointeur de pile.

Donc, y a-t-il une façon indépendante de l'arc de déterminer l'adresse actuelle/suivante définie par POSIX ou au moins disponible sous Linux?

+0

Comment êtes-vous la configuration de votre gestionnaire de signal? [Utilisez-vous 'sigaction()' et définissez l'indicateur 'SA_SIGINFO' dans le membre de structure' sa_flags'?] (Http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html) Si oui, vous peut avoir trouvé un bug. POSIX exige que le membre 'si_addr' fasse référence à l'instruction fautive. Voir http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html#tag_13_43 Vous devriez ajouter plus d'informations, y compris votre code, et les détails du système tels que le matériel et le système d'exploitation exact. –

+1

@AndrewHenle Je démarre un nouveau processus, qui appelle 'ptrace' avec' PTRACE_TRACEME', puis j'attends le premier événement de débogage dans le parent en utilisant 'waidpid'. L'événement est 'SIGTRAP'. Votre lien indique seulement que c'est pour 'SIGILL' et' SIGFPE' que 'si_addr' est l'adresse de l'instruction fautive, mais ne dit rien sur SIGTRAP. – Ruslan

Répondre

1

Vous pouvez utiliser /proc/[pid]/syscall.

[email protected]:~$ gdb python 
... 
... 
... 
Program received signal SIGINT, Interrupt. 
0x00007ffff78ed573 in __select_nocancel() at ../sysdeps/unix/syscall-template.S:84 
84 ../sysdeps/unix/syscall-template.S: No such file or directory. 
(gdb) 

[email protected]:~/$ ps aux | grep python 
mark  77858 0.2 0.7 90216 37780 pts/2 S+ 15:13 0:00 gdb python 
mark  77860 0.0 0.1 38416 6424 pts/2 t 15:13 0:00 /usr/bin/python 

(voir 77860 qui est tracée - t)

[email protected]:~/$ sudo cat /proc/77860/syscall 
23 0x1 0x7fffffffd980 0x0 0x0 0x0 0x7ffff7fdb700 0x7fffffffd958 0x7ffff78ed573 

0x7fffffffd958 est sp0x7ffff78ed573 et est le compteur de programme.

Je ne trouve aucun ptrace appel qui aide ici.

http://man7.org/linux/man-pages/man5/proc.5.html

/proc/[pid]/syscall (since Linux 2.6.27) 
      This file exposes the system call number and argument regis‐ 
      ters for the system call currently being executed by the 
      process, followed by the values of the stack pointer and pro‐ 
      gram counter registers. The values of all six argument regis‐ 
      ters are exposed, although most system calls use fewer regis‐ 
      ters. 

      If the process is blocked, but not in a system call, then the 
      file displays -1 in place of the system call number, followed 
      by just the values of the stack pointer and program counter. 
      If process is not blocked, then the file contains just the 
      string "running". 
+1

En effet, j'ai vérifié, et cela semble fonctionner au moins sur x86, x68_64 et ARM. – Ruslan