OVH Cloud OVH Cloud

Comment redémarrer un processus depuis son core ?

16 réponses
Avatar
JKB
Bonjour à tous,

Une question me taraude l'esprit. J'ai une application qui génère à
la demande un core (sans s'interrompre, en fait). Le core est bon
puisqu'avec un débugger (ddd), j'arrive à voir que le pointeur
programme est au bon endroit, avec les bonnes variables... Donc tout
est parfait. Mais comment redémarrer ce truc au point où il en était
lors de la création du core ?

J'ai tout essayé, sans succès... Une idée ?

JKB

--
En plus c'est simple, je fais ce genre de trucs en g77 depuis des années :
il suffit d'écrire un wrapper en C. Et comme ça, j'ai le meilleur des deux
mondes : la rigueur quasi-monacale du Fortran, et l'exubérance pétulante du C.

10 réponses

1 2
Avatar
FAb
JKB writes:

Bonjour à tous,

Une question me taraude l'esprit. J'ai une application qui génère à
la demande un core (sans s'interrompre, en fait). Le core est bon
puisqu'avec un débugger (ddd), j'arrive à voir que le pointeur
programme est au bon endroit, avec les bonnes variables... Donc tout
est parfait. Mais comment redémarrer ce truc au point où il en était
lors de la création du core ?

J'ai tout essayé, sans succès... Une idée ?

JKB


Ça dépend de ton programme, s'il a prévu de le faire il doit y avoir une doc
pour le reloader. Mais si c'est juste un trace de débug... Hmmm.
Sinon cela ne me semble pas toujours possible.
Comment restaurer les sockets ?

FAb

Avatar
Nicolas George
JKB wrote in message :
Une question me taraude l'esprit. J'ai une application qui génère à
la demande un core (sans s'interrompre, en fait). Le core est bon
puisqu'avec un débugger (ddd), j'arrive à voir que le pointeur
programme est au bon endroit, avec les bonnes variables... Donc tout
est parfait. Mais comment redémarrer ce truc au point où il en était
lors de la création du core ?


Je pense que tu vas avoir du mal. Je me lance dans mes idées.

C'est valable dans le cas ELF. Il faut d'abord maper l'exécutable en mémoire
en accord avec ses entêtes ELF (objdump -h), puis la même chose avec le core
lui-même. Chercher dans le core la sauvegarde des registres, et les charger.
Puis laisser tourner.

Ce qui louze : tous l'environnement qui n'est pas en mémoire (masque et
gestionnaires de signaux, umask, limites...) est perdu. Les fd ne sont pas
restaurés (et si c'est une connexion réseau, c'est un peu mort), et d'autres
trucs de ce genre. Il y a peut-être dans le core quelques informations en
plus pour restaurer plus de choses, mais je ne les ai pas trouvées.

Je dirais qu'avec un peu de chance, ça peut marcher si le programme fait
uniquement du calcul en mémoire avec une sortie du résultat sur stdout, ou
alors s'il est possible de faire en sorte que le programme fasse lui-même sa
phase d'initialisation (fd, signaux), et ensuite s'arrête pour charger
lui-même son core (et dans ce cas, il n'y a que le core à charger, pas le
binaire, donc c'est plus facile).

Avatar
JKB
Le 18-03-2005, à propos de
Re: Comment redémarrer un processus depuis son core
?,
Nicolas George écrivait dans fr.comp.os.unix :
JKB wrote in message :
Une question me taraude l'esprit. J'ai une application qui génère à
la demande un core (sans s'interrompre, en fait). Le core est bon
puisqu'avec un débugger (ddd), j'arrive à voir que le pointeur
programme est au bon endroit, avec les bonnes variables... Donc tout
est parfait. Mais comment redémarrer ce truc au point où il en était
lors de la création du core ?


Je pense que tu vas avoir du mal. Je me lance dans mes idées.

C'est valable dans le cas ELF. Il faut d'abord maper l'exécutable en mémoire
en accord avec ses entêtes ELF (objdump -h), puis la même chose avec le core
lui-même. Chercher dans le core la sauvegarde des registres, et les charger.
Puis laisser tourner.

Ce qui louze : tous l'environnement qui n'est pas en mémoire (masque et
gestionnaires de signaux, umask, limites...) est perdu. Les fd ne sont pas
restaurés (et si c'est une connexion réseau, c'est un peu mort), et d'autres
trucs de ce genre. Il y a peut-être dans le core quelques informations en
plus pour restaurer plus de choses, mais je ne les ai pas trouvées.

Je dirais qu'avec un peu de chance, ça peut marcher si le programme fait
uniquement du calcul en mémoire avec une sortie du résultat sur stdout, ou
alors s'il est possible de faire en sorte que le programme fasse lui-même sa
phase d'initialisation (fd, signaux), et ensuite s'arrête pour charger
lui-même son core (et dans ce cas, il n'y a que le core à charger, pas le
binaire, donc c'est plus facile).


En fait, le but est de pouvoir garder un instantané du déroulement
d'un programme. Je m'explique. J'ai écrit un langage de
programmation (pour faire des calculs justement), et certains
calculs tournent très longtemps. Le but du truc est de faire un dump
de la mémoire du processus (je sais faire, par contre, si quelqu'un
savait comment faire cette image sans envoyer un SIGQUIT...). Une
fois que ce dump est fait, j'aimerais pouvoir relancer l'exécutable
avec comme argument non pas mon script (rpl script.rpl), mais mon
image du processus (rpl -r core.script.rpl). A priori, je n'ai pas
problème d'initialisation ou d'environnement à restaurer, puisque le
wrapper s'en chargera. Ma première idée était de relancer un truc
comme gdb au travers d'un appel système execve(), mais je n'arrive
pas à trouver comment relancer ce programme.

J'aimerais bien garder une image mémoire du processus car une copie
de tous les éléments risque de s'avérer fastidieuse.

Pour ceux que cela intéresse, le langage en question est sur
http://www.systella.fr/~bertrand/rpl2 (GPL).

Voilà mes besoins, je recherche une solution ;-)

JKB
--
En plus c'est simple, je fais ce genre de trucs en g77 depuis des années :
il suffit d'écrire un wrapper en C. Et comme ça, j'ai le meilleur des deux
mondes : la rigueur quasi-monacale du Fortran, et l'exubérance pétulante du C.


Avatar
Jean-Marc Bourguet
JKB writes:

Bonjour à tous,

Une question me taraude l'esprit. J'ai une application qui génère à
la demande un core (sans s'interrompre, en fait). Le core est bon
puisqu'avec un débugger (ddd), j'arrive à voir que le pointeur
programme est au bon endroit, avec les bonnes variables... Donc tout
est parfait. Mais comment redémarrer ce truc au point où il en était
lors de la création du core ?

J'ai tout essayé, sans succès... Une idée ?


emacs fait (ou faisait ?) ce genre de chose. Je regarderais ses
sources pour savoir comment mais je crains que ce soit fort dependant
du systeme. Note que comme d'autres l'ont dit, ca implique deux
circuits d'initialisation: un normal et un pour la reexecution a
partir du core (et dans le cas d'emacs, c'est ce dernier qui est le
plus souvent execute).

A+

--
Jean-Marc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Nicolas George
JKB wrote in message :
J'aimerais bien garder une image mémoire du processus car une copie
de tous les éléments risque de s'avérer fastidieuse.


Je me doutais un peu que c'était ce genre de projet. Je pense qu'il vaut
mieux se taper une bonne fois pour toutes la sérialisation de toutes les
structures de données de l'interpréteur plutôt que laisser ce boulot à l'OS.
C'est peut-être un gros boulot au début, mais :

- ce sera infiniment plus fiable et plus portable, donc moins de boulot de
maintenance ;

- ça permet quelques avantages intéressants si c'est bien fait, comme le
fait de pouvoir continuer le programme sur une autre architecture ou de
corriger un bug sur la fin du programme quand c'est une portion qui n'a
pas encore été exécutée.

En ce qui concerne gdb, je soupçonne qu'il utilise exec pour faire charger
le binaire original en mémoire, puis ptrace pour charger les bouts du core
là où il faut. C'est abominablement non-portable tout ça.

Avatar
Pascal Bourguignon
JKB writes:
En fait, le but est de pouvoir garder un instantané du déroulement
d'un programme. Je m'explique. J'ai écrit un langage de
programmation (pour faire des calculs justement), et certains
calculs tournent très longtemps. Le but du truc est de faire un dump
de la mémoire du processus (je sais faire, par contre, si quelqu'un
savait comment faire cette image sans envoyer un SIGQUIT...). Une
fois que ce dump est fait, j'aimerais pouvoir relancer l'exécutable
avec comme argument non pas mon script (rpl script.rpl), mais mon
image du processus (rpl -r core.script.rpl). A priori, je n'ai pas
problème d'initialisation ou d'environnement à restaurer, puisque le
wrapper s'en chargera. Ma première idée était de relancer un truc
comme gdb au travers d'un appel système execve(), mais je n'arrive
pas à trouver comment relancer ce programme.


C'est pas prévu par unix.

Le core dump, c'est fait pour pouvoir déboguer post-mortem. Une fois
qu'un gros bug est arrivé (comme par exemple, ne pas traiter un signal
(et certains signaux sont intraitable exprès)), on sauvegarde l'état
du processus seulement afin que les programmeurs puissent avoir des
indices sur le problèmes. Certaines bogues n'apparaissent qu'en
production, et jamais quand on test ou débogue.

Il n'est pas possible de garder tout l'état (fichiers ouverts (les
fichiers peuvent avoir été supprimés), sockets (la plupart des
protocoles ne sont pas stateless: on ne peut pas suspendre et
reprendre les sessions), tout l'état qui est dans le noyau: AMC,
seules les données dans l'espace utilisateur sont dumpées, pas les
structures internes du noyau). Pour cette raison, il n'est pas prévu
par le système de restaurer l'état d'un processus pour le continuer.

En plus, si ça existait, ça serait trés dépendant du système
d'exploitation. Tu prefèreras écrire du code portable indépendant du
système.


J'aimerais bien garder une image mémoire du processus car une copie
de tous les éléments risque de s'avérer fastidieuse.


Mais nécessaire! Même si le système permettait de suspendre et de
reprendre les processus, il faudrait que les programmes en tiennent
compte et soit capable de gérer à tout moment de tels évènements.
Écrire les données sur le disque c'est encore ce qu'il y a de plus
simple.


pour ceux que cela intéresse, le langage en question est sur
http://www.systella.fr/~bertrand/rpl2 (GPL).

Voilà mes besoins, je recherche une solution ;-)


Tu peux t'inspirer des sources de certaines implémentations de
Common-Lisp ou de Smalltalk, qui peuvent enregistrer une "image" et la
reprendre. Voir:

http://www.squeak.org
http://clisp.cons.org
http://sbcl.sourceforge.net/

--
__Pascal Bourguignon__ http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay

Avatar
JKB
Le 18-03-2005, à propos de
Re: Comment redémarrer un processus depuis son
core
?,
Nicolas George écrivait dans fr.comp.os.unix :
JKB wrote in message :
J'aimerais bien garder une image mémoire du processus car une copie
de tous les éléments risque de s'avérer fastidieuse.


Je me doutais un peu que c'était ce genre de projet. Je pense qu'il vaut
mieux se taper une bonne fois pour toutes la sérialisation de toutes les
structures de données de l'interpréteur plutôt que laisser ce boulot à l'OS.
C'est peut-être un gros boulot au début, mais :

- ce sera infiniment plus fiable et plus portable, donc moins de boulot de
maintenance ;

- ça permet quelques avantages intéressants si c'est bien fait, comme le
fait de pouvoir continuer le programme sur une autre architecture ou de
corriger un bug sur la fin du programme quand c'est une portion qui n'a
pas encore été exécutée.


Bon, donc si j'ai bien compris, je suis contraint de me taper tout
le truc à la main... Vu les structures de données, je vais m'amuser
:-(

Merci,

JKB


Avatar
Pascal Bourguignon
JKB writes:
Bon, donc si j'ai bien compris, je suis contraint de me taper tout
le truc à la main... Vu les structures de données, je vais m'amuser
:-(


C'est pas forcément difficile.

En Smalltalk, c'est facile car toutes les données sont des objets,
donc il n'y a as de problème de type.

En Lisp, c'est aussi facile car toutes les données sont typées en
mémoire : les gestionnaires de bas niveau savent où il y a des
pointeurs et où il y a des données sans pointeur car chaque donnée est
étiquettée.

Même sans avoir le type des données, si on évite les pointeurs, on
peut sauvegarder le tas en bloc sans se poser le problème de la
relocation (utiliser des déplacements par rapport au début du tas,
c'est à dire, des adresses virtuelles).

Le plus délicat, c'est la pile: il faut reconnaitre les cadres. C'est
plus facile à faire si on a une machine virtuelle, qui peut être de
plus haut niveau, qu'avec une machine de bas niveau comme un x86 où on
ne distingue pas les pointeurs des entiers... Avec une machine
virtuelle, on peut même mettre la pile dans le tas (les cadres), et la
sauvegarder d'un coup avec le tas.

--
__Pascal Bourguignon__ http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"

Avatar
Thomas Labourdette
JKB a écrit le Vendredi 18 Mars 2005 14:35 :

En fait, le but est de pouvoir garder un instantané du déroulement
d'un programme. Je m'explique. J'ai écrit un langage de
programmation (pour faire des calculs justement), et certains
calculs tournent très longtemps. Le but du truc est de faire un dump
de la mémoire du processus (je sais faire, par contre, si quelqu'un
savait comment faire cette image sans envoyer un SIGQUIT...). Une
fois que ce dump est fait, j'aimerais pouvoir relancer l'exécutable
avec comme argument non pas mon script (rpl script.rpl), mais mon
image du processus (rpl -r core.script.rpl).

Voilà mes besoins, je recherche une solution ;-)


Et en s'inspirant des systèmes de mise en veille des portables (hibernate,
suspend ...) ?

@+
--
Dolly PRANE (signature aléatoire)
Sur mon bulletin scolaire :
"Un vrai touriste aurait au moins pris des photos."

Avatar
JKB
Le 19-03-2005, à propos de
Re: Comment redémarrer un processus depuis son core ?,
Thomas Labourdette écrivait dans fr.comp.os.unix :
JKB a écrit le Vendredi 18 Mars 2005 14:35 :

En fait, le but est de pouvoir garder un instantané du déroulement
d'un programme. Je m'explique. J'ai écrit un langage de
programmation (pour faire des calculs justement), et certains
calculs tournent très longtemps. Le but du truc est de faire un dump
de la mémoire du processus (je sais faire, par contre, si quelqu'un
savait comment faire cette image sans envoyer un SIGQUIT...). Une
fois que ce dump est fait, j'aimerais pouvoir relancer l'exécutable
avec comme argument non pas mon script (rpl script.rpl), mais mon
image du processus (rpl -r core.script.rpl).

Voilà mes besoins, je recherche une solution ;-)


Et en s'inspirant des systèmes de mise en veille des portables (hibernate,
suspend ...) ?


Les systèmes portables que j'ai vus tournent autour de
SIGSTOP/SIGCONT. Les autres sont intégrés dans les noyaux et tout
sauf portables.

Bref, je suis en train de ma palucher la sauvegarde à la mimine
(avec toutes les piles du langage en question et le pointeurs un peu
partout, c'est assez sportif...).

Philosophiquement, je ne comprends pas pourquoi il n'existe pas dans
les systèmes POSIX un tel appel. Le processus reçoit un signal, fait
une image de lui-même (avec l'exécutable, pas un simple core) que
l'on peut relancer plus tard (sur le même système bien entendu). Je
comprends bien le problème des sockets ouvertes et des fichiers,
mais avec ses restrictions, ce serait vraiment utile.

Cordialement,

JKB

--
En plus c'est simple, je fais ce genre de trucs en g77 depuis des années :
il suffit d'écrire un wrapper en C. Et comme ça, j'ai le meilleur des deux
mondes : la rigueur quasi-monacale du Fortran, et l'exubérance pétulante du C.


1 2