OVH Cloud OVH Cloud

connaitre le nom de la routine appelante

8 réponses
Avatar
gilles civario
Cross_post entre fr.comp.os.unix et fr.comp.lang.c
Followup-to fr.comp.os.unix

Bonjour.
Dans le cadre du developpement d'une bibliothèque de profiling en
environnement unix, je cherche s'il existe un moyen en C, si possible
standard, de connaître le nom de la routine ayant appelée la routine
courante.
Je suppose qu'il faudrait pouvoir examiner la pile d'appel, mais je
n'ai aucune idée de comment faire.

Gilles.

8 réponses

Avatar
frederic.remy1WHITOUT
gilles civario writes:

Cross_post entre fr.comp.os.unix et fr.comp.lang.c
Followup-to fr.comp.os.unix

Bonjour.
Dans le cadre du developpement d'une bibliothèque de profiling en
environnement unix, je cherche s'il existe un moyen en C, si possible
standard, de connaître le nom de la routine ayant appelée la routine
courante.
Je suppose qu'il faudrait pouvoir examiner la pile d'appel, mais je
n'ai aucune idée de comment faire.

Gilles.


Utiliser le débogeur Gdb et compiler ton code avec l'option -g du
compilateur gcc ? man gcc, man gdb.

F.R.

Avatar
Marc Lasson
wrote:

Utiliser le débogeur Gdb et compiler ton code avec l'option -g du
compilateur gcc ? man gcc, man gdb.


Je pense que l'OP connaît gdb. Il cherche a faire ce que fait gdb.

Ce que je sais: c'est que c'est impossible en C standard car il n'y
aucune raison de retrouver les identifacteurs dans le code produit.

(ie il n'y a aucune difference entre le code compilé de:
int foo (void) { return 42; }
et de: int bar (void) { return 42; } )

Mais effectivement certains compilateurs permettent de rajouter au
code des données concernant le code source (dont le nom des
identificateurs), peut-être devrais-tu jeter un coup d'oeil aux
sources de gdb.

--
Marc.

Avatar
kilobug

Bonjour.


Salut

Dans le cadre du developpement d'une bibliothèque de profiling en
environnement unix, je cherche s'il existe un moyen en C, si possible
standard, de connaître le nom de la routine ayant appelée la routine
courante.


Il n'y a pas de moyen standard AFAIK, le seul moyen que je connaisse
est backtrace et backtrace_symbols qui sont des extensions de la libc
GNU (info libc, ou info libc Function Index backtrace)

Je suppose qu'il faudrait pouvoir examiner la pile d'appel, mais je
n'ai aucune idée de comment faire.


C'est ce que fait backtrace(), mais la structure de la pile d'appel
dépend de l'architecture.

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org

Avatar
kilobug

wrote:
Utiliser le débogeur Gdb et compiler ton code avec l'option -g du
compilateur gcc ? man gcc, man gdb.



Je pense que l'OP connaît gdb. Il cherche a faire ce que fait gdb.


Ce que je sais: c'est que c'est impossible en C standard car il n'y
aucune raison de retrouver les identifacteurs dans le code produit.


(ie il n'y a aucune difference entre le code compilé de:
int foo (void) { return 42; }
et de: int bar (void) { return 42; } )


En général si, pour permettre l'édition de liens, le standard C
autorise la compilation séparée, donc il est nécessaire que dans le .o
(ou équivalent: le résultat de la compilation d'une unité de
compilation) généré le nom de la fonction soit encore présent, pour
qu'un autre .c puisse l'appeller; cependant rien ne garantie que le
nom du symbole soit toujours présent après l'édition des liens. C'est
le cas sur la plupart des systèmes pour les fonctionalités style
dlopen() mais rien ne l'oblige.

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', gilles civario wrote:

Dans le cadre du developpement d'une bibliothèque de profiling en
environnement unix, je cherche s'il existe un moyen en C, si possible
standard, de connaître le nom de la routine ayant appelée la routine
courante.
Je suppose qu'il faudrait pouvoir examiner la pile d'appel, mais je
n'ai aucune idée de comment faire.


<fclc>
Le langage C ne fourni aucune réponse à ta question autre que "ça dépend de
l'implémentation".
</>
--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Pascal Bourguignon
(Gaël Le Mignot) writes:


wrote:
Utiliser le débogeur Gdb et compiler ton code avec l'option -g du
compilateur gcc ? man gcc, man gdb.


Je pense que l'OP connaît gdb. Il cherche a faire ce que fait gdb.

Ce que je sais: c'est que c'est impossible en C standard car il n'y
aucune raison de retrouver les identifacteurs dans le code produit.

(ie il n'y a aucune difference entre le code compilé de:
int foo (void) { return 42; }
et de: int bar (void) { return 42; } )


En général si, pour permettre l'édition de liens, le standard C
autorise la compilation séparée, donc il est nécessaire que dans le .o
(ou équivalent: le résultat de la compilation d'une unité de
compilation) généré le nom de la fonction soit encore présent, pour
qu'un autre .c puisse l'appeller;


Manifestement, il voulait dire:

static int foo (void) { return 42; }
et de: static int bar (void) { return 42; }


cependant rien ne garantie que le
nom du symbole soit toujours présent après l'édition des liens. C'est
le cas sur la plupart des systèmes pour les fonctionalités style
dlopen() mais rien ne l'oblige.


--
__Pascal_Bourguignon__ http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/



Avatar
gilles civario
Gaël Le Mignot wrote:

Bonjour.


Salut

Dans le cadre du developpement d'une bibliothèque de profiling en
environnement unix, je cherche s'il existe un moyen en C, si possible
standard, de connaître le nom de la routine ayant appelée la routine
courante.


Il n'y a pas de moyen standard AFAIK, le seul moyen que je connaisse
est backtrace et backtrace_symbols qui sont des extensions de la libc
GNU (info libc, ou info libc Function Index backtrace)

Je suppose qu'il faudrait pouvoir examiner la pile d'appel, mais je
n'ai aucune idée de comment faire.


C'est ce que fait backtrace(), mais la structure de la pile d'appel
dépend de l'architecture.



Bonjour, et merci pour cette info très précieuse.
Malheureusement, Linux n'est pas ma plateforme de développement principale.
En fait, je m'interresse en premier lieux aux architectures alpha sous
Tru64.
J'ai trouvé comment obtenir l'adresse de retour de la fonction courante, ce
qui devrait me permettre de faire ce que je souhaite. Ainsi, je vais stocker
dans un tableau les informations de profiling, indexées par adresse de retour.
Je vais les imprimer sur des fichiers spécifiques; Puis dans une deuxième passe,
avec une commande du genre "myprof <exec> <fichier de profiling>", je vais
faire la correspondance entre ces adresses et les fonctions auxquelles elles
appartiennent.
L'avantage que j'y vois, c'est que la seule partie non-standard est celle qui me
donne l'adresse de retour de la fonction courante.
Or, à terme, je souhaite porter ma bibliothèque sur un maximum d'architectures
différentes. Donc, si de bonnes âmes parmis vous peuvent m'indiquer l'équivalent
de la macro suivante sur d'autre machines, je les en remercie.

#ifdef __alpha
#define RET_ADDR (asm("mov %ra, %v0"))
#else
#error "la macro n'est pas definie pour cette architecture"
#endif

Gilles.


Avatar
Manu
gilles civario wrote:

#ifdef __alpha
#define RET_ADDR (asm("mov %ra, %v0"))
#else
#error "la macro n'est pas definie pour cette architecture"
#endif


Sur SPARC je crois que tu n'auras pas de mal, par contre sur x86 si
l'exécutable a été optimisé et que le registre ebp n'est pas utilisé
comme base pour le calcul pour les accès aux variables et paramètres de
la fonction, tu n'as aucun moyen de retrouver facilement l'adresse de
retour de ta fonction.
Cela correspond à l'option -fomit-frame-pointer de GCC, si vous utilisez
GCC.
Personellement j'utilise la fonction backtrace de la libc. Mais je suis
interessé par une méthode qui serait un peu plus portable ou du moins,
moins dépendente de la libc.
Serait-il possible de trouver des bibliothèques séparées qui ferait se
boulot ?