Je me pose la question de savoir si il est possible, depuis une
fonction quelconque, de retrouver l'adresse de l'objet qui a appel=E9
cette fonction. Par exemple, dans le code suivant :
void bar() {
// ... some magic code ...
}
class A {
public:
void foo() {bar();}
};
int main(int argc, char** argv) {
A a;
a.foo();
return 0;
}
je voudrais que bar() soit capable de m'=E9crire un truc du genre
"caller address: 0x1234abcd", o=F9 0x1234abcd est l'adresse de 'a' (i.e.
ce que me sortirait un "cout << this << endl;" depuis n'importe quelle
fonction de A).
Une contrainte forte (sinon la solution est triviale !), c'est que je
ne veux surtout pas modifier la signature de bar(), ni imposer
d'autres contraintes (ou alors le moins possible ?) sur A.
Bon, avant d'en dire plus, quelques pr=E9cisions :
- d'abord, c'est pas un vrai cas d'usage, c'est principalement pour
satisfaire ma curiosit=E9 (pas la peine de me dire que c'est du code pas
propre et tout, quoi :-) ) ;
- ensuite, j'utilise g++/Linux et une solution sp=E9cifique =E0 g++ (ce
qui me semble in=E9vitable, au moins sur la piste o=F9 je suis parti de
manipulation de la pile d'appel...) m'ira tr=E8s bien ;
- finalement, je suis bien conscient que rien ne me dit que bar() est
appel=E9e depuis un objet et qu'il y a sans doute plein d'autres cas
plus compliqu=E9s, mais pour la discussion on dira que =E7a n'est pas pire
que mon exemple...
J'ai trouv=E9 les fonctions backtrace(), backtrace_symbols() de g++ qui
me permettent d'inspecter la pile d'appels, ce qui est d=E9j=E0 =E7a. En
m'inspirant, par exemple, du code ici :
http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-=
my-gcc-c-app-crashes
j'arrive facilement =E0 faire en sorte que bar() =E9crive "caller:
A::foo()".
Je me dis que je devrais pouvoir aller plus loin et exploiter
l'adresse de retour qui est fournie par backtrace() (ce qui doit =EAtre
la m=EAme que __builtin_return_address, je suppose ?) pour essayer de
retrouver le pointeur "this", vu qu'il doit =EAtre quelque part dans les
arguments de A::foo() (en dernier avec g++, je crois - mais vu que
A::foo() n'a pas d'arguments, =E7a doit aussi =EAtre le premier ici...).
Je n'y connais pas grand chose en compilation, assembleur... et j'ai
beaucoup de mal =E0 suivre ce que j'arrive =E0 trouver sur internet =E0
propos de esp, esb et autres registres, mais il me semble bien
qu'autour de la __builtin_return_address ou de la
__builtin_frame_address, il doit y avoir l'adresse des param=E8tres de
la fonction, non ?
Malheureusement, j'ai essay=E9 d'afficher la valeur de 'this', ainsi que
les valeurs du pointeur fourni par backtrace() plus ou moins de 0 =E0
100, pour la frame courante, la frame parente, en d=E9r=E9f=E9ren=E7ant deu=
x
fois (si le pointeur indique l'adresse d'un registre qui lui-m=EAme
contient l'adresse de 'this' ?)... Mais toutes les tortures auxquelles
j'ai pu penser n'ont jamais r=E9ussies =E0 faire avouer =E0 ce pointeur la
valeur de 'this'. Zut, peste et crotte, me voila bien emb=EAt=E9 !
Donc, est-ce que quelqu'un =E0 une id=E9e de si, et comment, je peux
exploiter cette adresse pour retrouver les arguments d'une fonction
quelconque dans la pile, et en particulier 'this' ? Ou est-ce que
quelqu'un =E0 une id=E9e de comment faire ce que je demande (si c'est
possible...) ?
Je me pose la question de savoir si il est possible, depuis une fonction quelconque, de retrouver l'adresse de l'objet qui a appelé cette fonction.
Je vois que ma question soulève un enthousiasme indescriptible :-)
Bon, je n'ai pas trouvé la réponse, mais quelqu'un m'a indiqué getcontext() comme une piste possible. Apparemment, le programme suivant : http://alephnull.com/backtrace.html (code source téléchargeable en remplaçant html par c) fait plus ou moins ce que je veux, en utilisant getcontext(). Mais d'une part je n'arrive pas à tester ce programme (il est écrit pour une architecture 32 bits et je suis sur une machine 64 bits, ajouter - m32 à la compilation marche mais plante à l'execution), et d'autre part je ne comprends pas les détails du code.
Tant pis, j'irais voir ailleurs si je trouve d'autres pistes... ou pas (je ne vais pas non plus y passer ma vie). -- Rémi
On Nov 1, 3:23 pm, Rémi Moyen <rmo...@gmail.com> wrote:
Je me pose la question de savoir si il est possible, depuis une
fonction quelconque, de retrouver l'adresse de l'objet qui a appelé
cette fonction.
Je vois que ma question soulève un enthousiasme indescriptible :-)
Bon, je n'ai pas trouvé la réponse, mais quelqu'un m'a indiqué
getcontext() comme une piste possible. Apparemment, le programme
suivant :
http://alephnull.com/backtrace.html (code source téléchargeable en
remplaçant html par c)
fait plus ou moins ce que je veux, en utilisant getcontext(). Mais
d'une part je n'arrive pas à tester ce programme (il est écrit pour
une architecture 32 bits et je suis sur une machine 64 bits, ajouter -
m32 à la compilation marche mais plante à l'execution), et d'autre
part je ne comprends pas les détails du code.
Tant pis, j'irais voir ailleurs si je trouve d'autres pistes... ou pas
(je ne vais pas non plus y passer ma vie).
--
Rémi
Je me pose la question de savoir si il est possible, depuis une fonction quelconque, de retrouver l'adresse de l'objet qui a appelé cette fonction.
Je vois que ma question soulève un enthousiasme indescriptible :-)
Bon, je n'ai pas trouvé la réponse, mais quelqu'un m'a indiqué getcontext() comme une piste possible. Apparemment, le programme suivant : http://alephnull.com/backtrace.html (code source téléchargeable en remplaçant html par c) fait plus ou moins ce que je veux, en utilisant getcontext(). Mais d'une part je n'arrive pas à tester ce programme (il est écrit pour une architecture 32 bits et je suis sur une machine 64 bits, ajouter - m32 à la compilation marche mais plante à l'execution), et d'autre part je ne comprends pas les détails du code.
Tant pis, j'irais voir ailleurs si je trouve d'autres pistes... ou pas (je ne vais pas non plus y passer ma vie). -- Rémi
ZarkXe
Bonjour Rémi,
Pour résoudre ton problème, tu a besoin de te plonger dans de l'assembleur s'il n’existe aucune libraire (Je n'est pas rechercher).
La solution que je te propose est adaptable en C/C++ et peu importe l'architecture. Il suffit de modifier le code assembleur.
Pour les explication suivant, je vais utiliser le compilateur g++ et une architecture x86-64.
Dans les deux solution proposée, l’adresse retour sera dans le registre rsi. Ceci me permet de l’afficher avec printf.
0x00. La première solution :
------------------------------
C'est une solution simple mais qui n'est pas aplicable dans tout les cas de figure sur tout quand il y a des variable local. Car le nombre d’argument empiler peut variée.
int main(int argc, char** argv) { A a; a.foo(); return 0; } -----------------------%<-----------------------------------------------
0x01 La seconde solution
--------------------------
C'est une solution générale qui peut s'impliquer même si la pile bouge. Typiquement lors d’ajout des variables local qui est tout le temps le cas. Cette solution repose sur le mécanisme de sauvegarde du haut de la pile dans %rbp. Donc à partir de %rbp on peut calculer ou ce trouve l'adresse de retour.
int main(int argc, char** argv) { A a; a.foo(); return 0; } -----------------------%<-----------------------------------------------
Nous avons vu que dans les deux cas de figure, je parlais qu'on avait l'adresse de retour dans le RSI. A partire de l'adresse de retour nous pouvons en déduire l'adresse de l'appelant. Pour cela il suffit explorer le code assembleur.
0x02 Extraire du code assembleur.
La fonction _Z3barv correspond a la fonction bar(). La fonction _ZN1A3fooEv correspond a la fonction foo().
Je me pose la question de savoir si il est possible, depuis une fonction quelconque, de retrouver l'adresse de l'objet qui a appelé cette fonction.
Je vois que ma question soulève un enthousiasme indescriptible :-)
Bon, je n'ai pas trouvé la réponse, mais quelqu'un m'a indiqué getcontext() comme une piste possible. Apparemment, le programme suivant : http://alephnull.com/backtrace.html (code source téléchargeable en remplaçant html par c) fait plus ou moins ce que je veux, en utilisant getcontext(). Mais d'une part je n'arrive pas à tester ce programme (il est écrit pour une architecture 32 bits et je suis sur une machine 64 bits, ajouter - m32 à la compilation marche mais plante à l'execution), et d'autre part je ne comprends pas les détails du code.
Tant pis, j'irais voir ailleurs si je trouve d'autres pistes... ou pas (je ne vais pas non plus y passer ma vie). -- Rémi
Bonjour Rémi,
Pour résoudre ton problème, tu a besoin de te plonger dans de
l'assembleur s'il n’existe aucune libraire (Je n'est pas rechercher).
La solution que je te propose est adaptable en C/C++ et peu importe
l'architecture. Il suffit de modifier le code assembleur.
Pour les explication suivant, je vais utiliser le compilateur g++ et une
architecture x86-64.
Dans les deux solution proposée, l’adresse retour sera dans le registre
rsi. Ceci me permet de l’afficher avec printf.
0x00. La première solution :
------------------------------
C'est une solution simple mais qui n'est pas aplicable dans tout les cas
de figure sur tout quand il y a des variable local. Car le nombre
d’argument empiler peut variée.
int main(int argc, char** argv) {
A a;
a.foo();
return 0;
}
-----------------------%<-----------------------------------------------
0x01 La seconde solution
--------------------------
C'est une solution générale qui peut s'impliquer même si la pile bouge.
Typiquement lors d’ajout des variables local qui est tout le temps le
cas. Cette solution repose sur le mécanisme de sauvegarde du haut de la
pile dans %rbp. Donc à partir de %rbp on peut calculer ou ce trouve
l'adresse de retour.
int main(int argc, char** argv) {
A a;
a.foo();
return 0;
}
-----------------------%<-----------------------------------------------
Nous avons vu que dans les deux cas de figure, je parlais qu'on avait
l'adresse de retour dans le RSI. A partire de l'adresse de retour nous
pouvons en déduire l'adresse de l'appelant. Pour cela il suffit explorer
le code assembleur.
0x02 Extraire du code assembleur.
La fonction _Z3barv correspond a la fonction bar().
La fonction _ZN1A3fooEv correspond a la fonction foo().
On Nov 1, 3:23 pm, Rémi Moyen <rmo...@gmail.com> wrote:
Je me pose la question de savoir si il est possible, depuis une
fonction quelconque, de retrouver l'adresse de l'objet qui a appelé
cette fonction.
Je vois que ma question soulève un enthousiasme indescriptible :-)
Bon, je n'ai pas trouvé la réponse, mais quelqu'un m'a indiqué
getcontext() comme une piste possible. Apparemment, le programme
suivant :
http://alephnull.com/backtrace.html (code source téléchargeable en
remplaçant html par c)
fait plus ou moins ce que je veux, en utilisant getcontext(). Mais
d'une part je n'arrive pas à tester ce programme (il est écrit pour
une architecture 32 bits et je suis sur une machine 64 bits, ajouter -
m32 à la compilation marche mais plante à l'execution), et d'autre
part je ne comprends pas les détails du code.
Tant pis, j'irais voir ailleurs si je trouve d'autres pistes... ou pas
(je ne vais pas non plus y passer ma vie).
--
Rémi
Pour résoudre ton problème, tu a besoin de te plonger dans de l'assembleur s'il n’existe aucune libraire (Je n'est pas rechercher).
La solution que je te propose est adaptable en C/C++ et peu importe l'architecture. Il suffit de modifier le code assembleur.
Pour les explication suivant, je vais utiliser le compilateur g++ et une architecture x86-64.
Dans les deux solution proposée, l’adresse retour sera dans le registre rsi. Ceci me permet de l’afficher avec printf.
0x00. La première solution :
------------------------------
C'est une solution simple mais qui n'est pas aplicable dans tout les cas de figure sur tout quand il y a des variable local. Car le nombre d’argument empiler peut variée.
int main(int argc, char** argv) { A a; a.foo(); return 0; } -----------------------%<-----------------------------------------------
0x01 La seconde solution
--------------------------
C'est une solution générale qui peut s'impliquer même si la pile bouge. Typiquement lors d’ajout des variables local qui est tout le temps le cas. Cette solution repose sur le mécanisme de sauvegarde du haut de la pile dans %rbp. Donc à partir de %rbp on peut calculer ou ce trouve l'adresse de retour.
int main(int argc, char** argv) { A a; a.foo(); return 0; } -----------------------%<-----------------------------------------------
Nous avons vu que dans les deux cas de figure, je parlais qu'on avait l'adresse de retour dans le RSI. A partire de l'adresse de retour nous pouvons en déduire l'adresse de l'appelant. Pour cela il suffit explorer le code assembleur.
0x02 Extraire du code assembleur.
La fonction _Z3barv correspond a la fonction bar(). La fonction _ZN1A3fooEv correspond a la fonction foo().
Je me pose la question de savoir si il est possible, depuis une fonction quelconque, de retrouver l'adresse de l'objet qui a appelé cette fonction.
Je vois que ma question soulève un enthousiasme indescriptible :-)
Bon, je n'ai pas trouvé la réponse, mais quelqu'un m'a indiqué getcontext() comme une piste possible. Apparemment, le programme suivant : http://alephnull.com/backtrace.html (code source téléchargeable en remplaçant html par c) fait plus ou moins ce que je veux, en utilisant getcontext(). Mais d'une part je n'arrive pas à tester ce programme (il est écrit pour une architecture 32 bits et je suis sur une machine 64 bits, ajouter - m32 à la compilation marche mais plante à l'execution), et d'autre part je ne comprends pas les détails du code.
Tant pis, j'irais voir ailleurs si je trouve d'autres pistes... ou pas (je ne vais pas non plus y passer ma vie). -- Rémi
Alain Ketterlin
ZarkXe writes:
La solution que je te propose est adaptable en C/C++ et peu importe l'architecture. Il suffit de modifier le code assembleur.
Pour résoudre ton problème, tu a besoin de te plonger dans de l'assembleur s'il nexiste aucune libraire (Je n'est pas rechercher).
Argh. Je n'ai jamais appris l'assembleur, sauf sur le tas et de manière très très partielle... Bon, merci quand même pour ta répo nse, j'essaie de décortiquer tout ça à tête reposée. Je reviendrais pe ut- être poser des questions... -- Rémi
On Nov 5, 1:21 pm, ZarkXe <zar...@example.invalid> wrote:
Bonjour Rémi,
Pour résoudre ton problème, tu a besoin de te plonger dans de
l'assembleur s'il nexiste aucune libraire (Je n'est pas rechercher).
Argh. Je n'ai jamais appris l'assembleur, sauf sur le tas et de
manière très très partielle... Bon, merci quand même pour ta répo nse,
j'essaie de décortiquer tout ça à tête reposée. Je reviendrais pe ut-
être poser des questions...
--
Rémi
Pour résoudre ton problème, tu a besoin de te plonger dans de l'assembleur s'il nexiste aucune libraire (Je n'est pas rechercher).
Argh. Je n'ai jamais appris l'assembleur, sauf sur le tas et de manière très très partielle... Bon, merci quand même pour ta répo nse, j'essaie de décortiquer tout ça à tête reposée. Je reviendrais pe ut- être poser des questions... -- Rémi
Rémi Moyen
> [...] Cette solution repose sur le mécanisme de sauvegarde du haut de > la pile dans %rbp.
Qui n'est en général pas fait, sauf cas particulier.
Compile ton code avec -O1 (ou n'importe quoi sauf le -O0 par defaut) et tes programmes ne fonctionnent plus.
Je vais sans doute dire une bêtise, mais j'avais vaguement eu l'impression que backtrace() et/ou get_context() permettaient justement de récupérer cette addresse de manière relativement robuste (avec g++, en tout cas) ?
>>> Je me pose la question de savoir si il est possible, depuis une >>> fonction quelconque, de retrouver l'adresse de l'objet qui a appelé >>> cette fonction.
Je ne suis pas sûr de ce que tu entends par objet, mais tu peux regarde r tu coté de backtrace() dans la glibc.
Ben c'est ce que j'avais essayé, justement (cf. mon premier message), mais autant je n'ai aucun problème à récupérer les fonctions appel ées, autant je n'arrive absolument pas à récupérer les arguments de ces fonctions.
(et dans le cas qui m'intéresse, en C++, il me semble que l'objet -- le pointeur 'this', disons -- dont une méthode est appelée est passé en interne en argument de la fonction, donc arriver à récupérer tous les arguments m'avancerait déjà pas mal)
Typiquement, c'est le genre de choses pour lesquelles il n'existe pas de solution générale (comme le précise le man de getcontext()). Sans l 'aide du compilateur, tu as peu d'espoir d'obtenir quelque chose d'utile.
Déjà, comme je le disais plus haut, je ne cherche pas vraiment quelque chose d'utile. C'est plus de la curiosité qu'autre chose. Et sinon, je pense que je suis perdu dans les (quelques) docs que j'arrive à trouver vu que je ne capte pas grand chose dès que quelqu'un parle d'assembleur...
Enfin bon, merci pour tes remarques ! -- Rémi
> [...] Cette solution repose sur le mécanisme de sauvegarde du haut de
> la pile dans %rbp.
Qui n'est en général pas fait, sauf cas particulier.
Compile ton code avec -O1 (ou n'importe quoi sauf le -O0 par defaut) et
tes programmes ne fonctionnent plus.
Je vais sans doute dire une bêtise, mais j'avais vaguement eu
l'impression que backtrace() et/ou get_context() permettaient
justement de récupérer cette addresse de manière relativement robuste
(avec g++, en tout cas) ?
>>> Je me pose la question de savoir si il est possible, depuis une
>>> fonction quelconque, de retrouver l'adresse de l'objet qui a appelé
>>> cette fonction.
Je ne suis pas sûr de ce que tu entends par objet, mais tu peux regarde r
tu coté de backtrace() dans la glibc.
Ben c'est ce que j'avais essayé, justement (cf. mon premier message),
mais autant je n'ai aucun problème à récupérer les fonctions appel ées,
autant je n'arrive absolument pas à récupérer les arguments de ces
fonctions.
(et dans le cas qui m'intéresse, en C++, il me semble que l'objet --
le pointeur 'this', disons -- dont une méthode est appelée est passé
en interne en argument de la fonction, donc arriver à récupérer tous
les arguments m'avancerait déjà pas mal)
Typiquement, c'est le genre de choses pour lesquelles il n'existe pas de
solution générale (comme le précise le man de getcontext()). Sans l 'aide
du compilateur, tu as peu d'espoir d'obtenir quelque chose d'utile.
Déjà, comme je le disais plus haut, je ne cherche pas vraiment quelque
chose d'utile. C'est plus de la curiosité qu'autre chose. Et sinon, je
pense que je suis perdu dans les (quelques) docs que j'arrive à
trouver vu que je ne capte pas grand chose dès que quelqu'un parle
d'assembleur...
> [...] Cette solution repose sur le mécanisme de sauvegarde du haut de > la pile dans %rbp.
Qui n'est en général pas fait, sauf cas particulier.
Compile ton code avec -O1 (ou n'importe quoi sauf le -O0 par defaut) et tes programmes ne fonctionnent plus.
Je vais sans doute dire une bêtise, mais j'avais vaguement eu l'impression que backtrace() et/ou get_context() permettaient justement de récupérer cette addresse de manière relativement robuste (avec g++, en tout cas) ?
>>> Je me pose la question de savoir si il est possible, depuis une >>> fonction quelconque, de retrouver l'adresse de l'objet qui a appelé >>> cette fonction.
Je ne suis pas sûr de ce que tu entends par objet, mais tu peux regarde r tu coté de backtrace() dans la glibc.
Ben c'est ce que j'avais essayé, justement (cf. mon premier message), mais autant je n'ai aucun problème à récupérer les fonctions appel ées, autant je n'arrive absolument pas à récupérer les arguments de ces fonctions.
(et dans le cas qui m'intéresse, en C++, il me semble que l'objet -- le pointeur 'this', disons -- dont une méthode est appelée est passé en interne en argument de la fonction, donc arriver à récupérer tous les arguments m'avancerait déjà pas mal)
Typiquement, c'est le genre de choses pour lesquelles il n'existe pas de solution générale (comme le précise le man de getcontext()). Sans l 'aide du compilateur, tu as peu d'espoir d'obtenir quelque chose d'utile.
Déjà, comme je le disais plus haut, je ne cherche pas vraiment quelque chose d'utile. C'est plus de la curiosité qu'autre chose. Et sinon, je pense que je suis perdu dans les (quelques) docs que j'arrive à trouver vu que je ne capte pas grand chose dès que quelqu'un parle d'assembleur...
Oui et non. En fait, retrouver où sur la pile est la position de l'adresse de retour de l'appelante repose sur des conventions. Voilà ce que dit la doc de backtrace() :
| These functions make some assumptions about how a function's return | address is stored on the stack. Note the following: | * Omission of the frame pointers (as implied by any of gcc(1)'s | nonzero optimization levels) may cause these assumptions to be vioâ | lated. | * Inlined functions do not have stack frames. | * Tail-call optimization causes one stack frame to replace another.
Oui et non. En fait, retrouver où sur la pile est la position de
l'adresse de retour de l'appelante repose sur des conventions. Voilà ce
que dit la doc de backtrace() :
| These functions make some assumptions about how a function's return
| address is stored on the stack. Note the following:
| * Omission of the frame pointers (as implied by any of gcc(1)'s
| nonzero optimization levels) may cause these assumptions to be vioâ
| lated.
| * Inlined functions do not have stack frames.
| * Tail-call optimization causes one stack frame to replace another.
Oui et non. En fait, retrouver où sur la pile est la position de l'adresse de retour de l'appelante repose sur des conventions. Voilà ce que dit la doc de backtrace() :
| These functions make some assumptions about how a function's return | address is stored on the stack. Note the following: | * Omission of the frame pointers (as implied by any of gcc(1)'s | nonzero optimization levels) may cause these assumptions to be vioâ | lated. | * Inlined functions do not have stack frames. | * Tail-call optimization causes one stack frame to replace another.
Je me pose la question de savoir si il est possible, depuis une fonction quelconque, de retrouver l'adresse de l'objet qui a appelé cette fonction.
Hmm, utiliser le débuggueur est-il autorisé ?
Pascal J. Bourguignon
Marc writes:
Rémi Moyen wrote:
Je me pose la question de savoir si il est possible, depuis une fonction quelconque, de retrouver l'adresse de l'objet qui a appelé cette fonction.
Hmm, utiliser le débuggueur est-il autorisé ?
En effet, il sera surement plus facile d'implémenter la fonctionalité voulue, si on a un exécutable compilé avec les options et informations de deboguage. cf. eg. http://dwarfstd.org/doc/dwarf-2.0.0.pdf
Dans le cas d'un exécutable compilé sans option de déboguage, ou pire, avec des optimizations activée, le problème peut être insoluble, car le compilateur peut générer le code de telle manière que l'information voulue aie été détruite.
Je me pose la question de savoir si il est possible, depuis une
fonction quelconque, de retrouver l'adresse de l'objet qui a appelé
cette fonction.
Hmm, utiliser le débuggueur est-il autorisé ?
En effet, il sera surement plus facile d'implémenter la fonctionalité
voulue, si on a un exécutable compilé avec les options et informations
de deboguage. cf. eg. http://dwarfstd.org/doc/dwarf-2.0.0.pdf
Dans le cas d'un exécutable compilé sans option de déboguage, ou pire,
avec des optimizations activée, le problème peut être insoluble, car le
compilateur peut générer le code de telle manière que l'information
voulue aie été détruite.
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Je me pose la question de savoir si il est possible, depuis une fonction quelconque, de retrouver l'adresse de l'objet qui a appelé cette fonction.
Hmm, utiliser le débuggueur est-il autorisé ?
En effet, il sera surement plus facile d'implémenter la fonctionalité voulue, si on a un exécutable compilé avec les options et informations de deboguage. cf. eg. http://dwarfstd.org/doc/dwarf-2.0.0.pdf
Dans le cas d'un exécutable compilé sans option de déboguage, ou pire, avec des optimizations activée, le problème peut être insoluble, car le compilateur peut générer le code de telle manière que l'information voulue aie été détruite.
Rémi Moyen wrote: > Je me pose la question de savoir si il est possible, depuis une > fonction quelconque, de retrouver l'adresse de l'objet qui a appelé > cette fonction.
Hmm, utiliser le débuggueur est-il autorisé ?
Ben en fait je me demandais comment faire sans débuggueur, en me disant que justement, si le débuggueur y arrive, c'est que c'est faisable.
Mais il est clair (je l'ai déjà dit) que je ne m'attends pas à une solution standard, portable ou même robuste. Disons que je voulais savoir si c'était quelque chose de faisable relativement facilement, juste pour voir comment ça marche, ou si c'était impossible à faire sans tomber dans l'usine à gaz (typiquement ce que font les débuggueurs...). En gros, est-ce qu'avec une version de g++, une machine particulière, un jeu d'options de compilations bien choisies, je pouvais récupérer un pointeur via backtrace ou un truc de ce genre, faire une paire de cast et obtenir quelque chose.
Les diverses réponses me montrent que ça n'est pas si simple, ok. J'oublie, ma curiosité est plus ou moins satisfaite. -- Rémi
On Nov 7, 11:24 pm, Marc <marc.gli...@gmail.com> wrote:
Rémi Moyen wrote:
> Je me pose la question de savoir si il est possible, depuis une
> fonction quelconque, de retrouver l'adresse de l'objet qui a appelé
> cette fonction.
Hmm, utiliser le débuggueur est-il autorisé ?
Ben en fait je me demandais comment faire sans débuggueur, en me
disant que justement, si le débuggueur y arrive, c'est que c'est
faisable.
Mais il est clair (je l'ai déjà dit) que je ne m'attends pas à une
solution standard, portable ou même robuste. Disons que je voulais
savoir si c'était quelque chose de faisable relativement facilement,
juste pour voir comment ça marche, ou si c'était impossible à faire
sans tomber dans l'usine à gaz (typiquement ce que font les
débuggueurs...). En gros, est-ce qu'avec une version de g++, une
machine particulière, un jeu d'options de compilations bien choisies,
je pouvais récupérer un pointeur via backtrace ou un truc de ce genre,
faire une paire de cast et obtenir quelque chose.
Les diverses réponses me montrent que ça n'est pas si simple, ok.
J'oublie, ma curiosité est plus ou moins satisfaite.
--
Rémi
Rémi Moyen wrote: > Je me pose la question de savoir si il est possible, depuis une > fonction quelconque, de retrouver l'adresse de l'objet qui a appelé > cette fonction.
Hmm, utiliser le débuggueur est-il autorisé ?
Ben en fait je me demandais comment faire sans débuggueur, en me disant que justement, si le débuggueur y arrive, c'est que c'est faisable.
Mais il est clair (je l'ai déjà dit) que je ne m'attends pas à une solution standard, portable ou même robuste. Disons que je voulais savoir si c'était quelque chose de faisable relativement facilement, juste pour voir comment ça marche, ou si c'était impossible à faire sans tomber dans l'usine à gaz (typiquement ce que font les débuggueurs...). En gros, est-ce qu'avec une version de g++, une machine particulière, un jeu d'options de compilations bien choisies, je pouvais récupérer un pointeur via backtrace ou un truc de ce genre, faire une paire de cast et obtenir quelque chose.
Les diverses réponses me montrent que ça n'est pas si simple, ok. J'oublie, ma curiosité est plus ou moins satisfaite. -- Rémi
Rémi Moyen
On Nov 7, 6:04 pm, Alain Ketterlin wrote:
Pour les arguments, oublie. Selon le compilo, l'ABI, etc. ils seront placés soit dans des registres, soit dans la pile (soit dans les deux).
Bah c'est sûr que je n'aurais jamais un truc générique ni même robuste. Mais pour un compilateur, un jeu d'options, est-ce qu'il n'y a pas une certaine logique ? Je parlais aussi de 'this' parce que d'une part c'est celui qui m'a gratouillé le cerveau en premier, mais aussi d'autre part parce que j'imagine (peut-être à tort ?) qu'il doit être traité de la même manière dans toutes les fonctions (pour un compilateur, options, etc. spécifique, toujours). Ça me semble un peu plus constant que des arguments qui effectivement ne sont pas forcément toujours stockés de la même manière.
Oui, this est un argument comme un autre, et comme c'est un pointeur, il peut finir dans un registre. Mais ce qu'il devient après... Typiquement , si m.f() appelle n.g(), l'adresse de m est passée dans un registre à f(), mais elle est ensuite sauvegardée sur la pile (si nécessaire) puisque le registre doit servir à passer l'adresse de n à g(). Etc.
Ah, donc si je suis dans g() je dois pouvoir retrouver où est le 'this' courant (n), mais même en jouant avec la backtrace, il n'est pas évident que le 'this' dans f() soit à un endroit prédictible... ok, je n'avais pas pensé à ça...
J'aime bien "Smashing The Stack For Fun And Profit", àhttp://insecure.o rg/stf/smashstack.html
Ça a l'air bien, ça ! Merci pour l'adresse, je stocke dans un coin. Il va me falloir du temps pour le digérer (surtout que tout ça n'est que de la curiosité générique, donc ça n'est pas du tout ma priorité. ..). -- Rémi
On Nov 7, 6:04 pm, Alain Ketterlin <al...@dpt-info.u-strasbg.fr>
wrote:
Pour les arguments, oublie. Selon le compilo, l'ABI, etc. ils seront
placés soit dans des registres, soit dans la pile (soit dans les deux).
Bah c'est sûr que je n'aurais jamais un truc générique ni même
robuste. Mais pour un compilateur, un jeu d'options, est-ce qu'il n'y
a pas une certaine logique ? Je parlais aussi de 'this' parce que
d'une part c'est celui qui m'a gratouillé le cerveau en premier, mais
aussi d'autre part parce que j'imagine (peut-être à tort ?) qu'il doit
être traité de la même manière dans toutes les fonctions (pour un
compilateur, options, etc. spécifique, toujours). Ça me semble un peu
plus constant que des arguments qui effectivement ne sont pas
forcément toujours stockés de la même manière.
Oui, this est un argument comme un autre, et comme c'est un pointeur, il
peut finir dans un registre. Mais ce qu'il devient après... Typiquement ,
si m.f() appelle n.g(), l'adresse de m est passée dans un registre à
f(), mais elle est ensuite sauvegardée sur la pile (si nécessaire)
puisque le registre doit servir à passer l'adresse de n à g(). Etc.
Ah, donc si je suis dans g() je dois pouvoir retrouver où est le
'this' courant (n), mais même en jouant avec la backtrace, il n'est
pas évident que le 'this' dans f() soit à un endroit prédictible...
ok, je n'avais pas pensé à ça...
J'aime bien "Smashing The Stack For Fun And Profit", àhttp://insecure.o rg/stf/smashstack.html
Ça a l'air bien, ça ! Merci pour l'adresse, je stocke dans un coin. Il
va me falloir du temps pour le digérer (surtout que tout ça n'est que
de la curiosité générique, donc ça n'est pas du tout ma priorité. ..).
--
Rémi
Pour les arguments, oublie. Selon le compilo, l'ABI, etc. ils seront placés soit dans des registres, soit dans la pile (soit dans les deux).
Bah c'est sûr que je n'aurais jamais un truc générique ni même robuste. Mais pour un compilateur, un jeu d'options, est-ce qu'il n'y a pas une certaine logique ? Je parlais aussi de 'this' parce que d'une part c'est celui qui m'a gratouillé le cerveau en premier, mais aussi d'autre part parce que j'imagine (peut-être à tort ?) qu'il doit être traité de la même manière dans toutes les fonctions (pour un compilateur, options, etc. spécifique, toujours). Ça me semble un peu plus constant que des arguments qui effectivement ne sont pas forcément toujours stockés de la même manière.
Oui, this est un argument comme un autre, et comme c'est un pointeur, il peut finir dans un registre. Mais ce qu'il devient après... Typiquement , si m.f() appelle n.g(), l'adresse de m est passée dans un registre à f(), mais elle est ensuite sauvegardée sur la pile (si nécessaire) puisque le registre doit servir à passer l'adresse de n à g(). Etc.
Ah, donc si je suis dans g() je dois pouvoir retrouver où est le 'this' courant (n), mais même en jouant avec la backtrace, il n'est pas évident que le 'this' dans f() soit à un endroit prédictible... ok, je n'avais pas pensé à ça...
J'aime bien "Smashing The Stack For Fun And Profit", àhttp://insecure.o rg/stf/smashstack.html
Ça a l'air bien, ça ! Merci pour l'adresse, je stocke dans un coin. Il va me falloir du temps pour le digérer (surtout que tout ça n'est que de la curiosité générique, donc ça n'est pas du tout ma priorité. ..). -- Rémi