Journal : Auto-génération de code à la volée
Posté par Val1472 () le 22 juin 2007Je t'écris pour te poser une question "technique", limite philosophique.
Suite à ce journal : http://linuxfr.org/~Montaigne/24628.html, je me suis demandé comment pourrait faire une application sous linux en user-space, pour auto-générer son code. Je cherchais une solution efficace et performante (en c par exemple).
La première solution à laquelle j'ai pensé est relativement sale : j'écris du code dans un .c (fwrite...), je le compile avec un appel à gcc (system...) sous forme de .so que j'ouvre avec dlopen.
En deuxième solution, je voyais "smasher" la stack de mon propre programme, mais là je trouve ça... inqualifiablement affreux.
Cher lecteur, connais-tu une solution à cet épineux problème ? A noter que je n'y vois pas d'intérêt pratique, c'est juste pour la culture.
Merci !
> Lire le journal (24 commentaires, moyenne: 3).
en Java
Ok, tu cherches une solution en C. Mais si jamais tu es intéressé, c'est possible en java.
Au delà des solutions de script, tu peux compiler une classe à partir d'une chaîne de caractère et la charger par la suite. Un exemple :
http://www.javaworld.com/javatips/jw-javatip131.html
Bon courage pour la suite :-)
Les gouts et les couleurs
Tu trouves sale la solution qui consiste à écrire du code C dans un fichier et à le faire compiler.
Nous n'avons pas les mêmes gouts.
Le développement en C est maitrisé et connu; maintenable, on trouve des compilateurs pour pratiquement toutes les architectures.
Je trouve particulièrement sale un mécanisme qui génèrerait directement du code binaire en mémoire; qui devrait être exécuter. Ca oblige à jouer avec les segments de données et de code; à contourner le résolveur de lien; a mettre tout un tas d'artifice qui vont être propre à l'architecture et à l'OS, sans garantie même d'une version à l'autre.
En plus de cela, ça oblige à intégrer au minimum un assembleur et un résolveur de liens directement dans ton programme, tache qui sera mal fait par rapport à un assembleur maintenu.
Bref, une vrai usine à gaz.
-
[^]Re: Les gouts et les couleurs
-
[^]Re: Les gouts et les couleurs
Posté par Étienne Bersac (Jabber id, page perso, ) le 22/06/2007 à 14:23. (lien). Évalué à 2.Il faudrait juste une libgcc qui compile une chaîne de caractère et retourne un pointeur vers le ".so" :)
--
E Ultreïa !
a la volé...
ben, ca depends un peu de ce que tu veux faire...
si tu veux faire des choses assez simple et determiné, tu peu imaginer ton propre language et ta propre pile; ton programme ne serait qu'un interpreteur.
exemple typique : un emulateur de calculatrice (je pense a une hp par exemple).
imagine ton programme (un interpreteur d'un language simple tel que le RPN), il attends des evenements ou il interagit avec je ne sais quoi...
et quand il recoit certains evenement, il ponds dans la pile des instructions...
quand je parle de pile, je ne parle pas de la pile systeme, je parle d'une pile emulé par une classe en C par exemple avec des pop() drop() et companie.
et ensuite, il interprete les instructions de la pile (là c'est important d'avoir un language simple et determiné, voir specifique)
voilà, ca peut être un peu lourds, mais ce qui est bien c'est que l'execution du code à la volé se fait à l'interieur de l'interpreteur et sans bidouiller la stack "systeme"...
mais tout depends des actions que tu souhaite faire faire à to ncode generé à la volé (par exemple si c'est un truc hyper generaliste, il faudra definir sans doute pas mal d'instruction). c'est pas utilisable dans toutes sorte de situation, et demande pas mal de boulot.
-
[^]À la volée...
Posté par Christophe Chailloleau-Leclerc (Jabber id, page perso, ) le 22/06/2007 à 09:37. (lien). Évalué à 1.En embarquant un interpréteur d'un langage de script existant, sinon, que ce soit Perl , Python , Ruby , QtScript , ou autre...
-
[^]Re: À la volée...
Posté par Christophe Chailloleau-Leclerc (Jabber id, page perso, ) le 22/06/2007 à 09:40. (lien). Évalué à 2.Bon, c'était des liens que j'avais mis, vers des tutoriels / aides pour embarquer ces différents langages... Visiblement, Templeet n'aime pas les liens ?
Les voici :
Perl : http://perl.enstimac.fr/DocFr/perlembed.html
Python : http://www.python.org/doc/ext/embedding.html
Ruby : http://www.sourcepole.ch/2004/1/21/embedding-ruby-in-c
QtScript : http://doc.trolltech.com/4.3/qtscript.html
Ok... Je vois... Les liens sont "découverts" automatiquement, il ne faut pas mettre les balises... J'essayerais de m'en rappeler ;-)-
[^]Re: À la volée...
Posté par Gabriel Linder () le 22/06/2007 à 10:40. (lien). Évalué à 3.Il manque Lua, simple et léger : http://www.lua.org/about.html
-
[^]Re: À la volée...
Posté par baud123 (Jabber id, page perso, ) le 22/06/2007 à 11:10. (lien). Évalué à 1.il est tout de même préconisé de prendre l'habitude d'encadrer les liens de crochets [ ], ce qui évite que la ponctuation (point, virgule, parenthèse, ...) soit embarquée dans le lien.
Plus d'éléments sur http://wiki.eagle-usb.org/wakka.php?wiki=SuggestionsLecteurL(...)
-
[^]Re: À la volée...
-
-
Si j'étais un vrai homme ...
Si j'étais un vrai homme, voilà ce que je ferais a ta place :
Je bidouillerais gcc pour qu'il puisse avoir ses entrées sorties directement en mémoire, c'est a dire par exemple, de lui passez une chaine de caratère et qu'il te retourne un pointeur sur le code compilé écrit sur le tas (pas la peine d'aller péter ta pile :) ).
Le top du top serait d'avoir le code compilé en flux continu, avec une callback appelée a chaque fois qu'un sous arbre de l'arbre de compilation est terminé (par exemple, pour chaque fonction, lorsque tout est défini bien sûr). La blague c'est le link, qui sera ultra funky mais y'a vraiment moyen de se marrer.
Bon le truc c'est que les segments de code sont en lecture seule, et qu'à l'avenir en se verra de plus en plus souvent interdire l'exécution sur la pile (tant mieux) et sur le tas (un peu plus balot, mais c'est bien quand même). L'avantage de dlopen() et consorts, c'est que ca passe par des privilèges noyaux pour rajouter des segments de code.
(bon j'espère que j'ai pas dit de bêtises, mais je crois que non)
Pour ma part, entre un appel a gcc ou de l'écriture de code en mémoire, et même en général en informatique, la philosophie qui convient est "tu peux faire ce que tu veux, a partir du moment que tu le maîtrise et que tu peux le justifier, honnêtement"
-
[^]Re: Si j'étais un vrai homme ...
Posté par alenvers () le 22/06/2007 à 11:43. (lien). Évalué à 2.Y a plus simple : un ramdisk ;-) et le reste c'est comme il l'a décrit.
-
[^]Re: Si j'étais un vrai homme ...
Posté par Matthieu Moy (page perso, ) le 22/06/2007 à 13:47. (lien). Évalué à 2.Mouais, sauf que ce qu'il y a sur le disque, c'est quand même pas tout à fait la même chose que ce que tu trouves en mémoire. Il y a toute la partie relogement et édition de lien qui manque. Et un binaire déjà relogé, sur un RAMdisk, ça serait quand même une bête étrange ...
-
Mouais
Générer du code dynamiquement est crade et dangereux, un programme utilisant ceci subira un kill sauvage et bien mérité sur un kernel PaX[1]/Grsecurity[2] configuré correctement. Après on peut bien autoriser l'exécution de tels programmes avec paxctl, mais bon...
Sinon il reste la possibilité de t'interfacer avec un interpréteur de script, comme dit plus haut.
[1] : http://pax.grsecurity.net/
[2] : http://www.grsecurity.net/
-
[^]Re: Mouais
Posté par alenvers () le 22/06/2007 à 11:47. (lien). Évalué à 7.>Générer du code dynamiquement est crade et dangereux,
Non. Lisp et d'autres langages sont prévus pour ça.
Et comme tout le monde le sait, tout programme un tant soit peu évolué possède un interpréteur/compilateur lisp embarqué mais en moins bien.
dynamique
Je suis pas sûr d'avoir tout compris mais j'ai l'intuition que libffi peut aider.
http://sourceware.org/libffi/
Free Softwares Users Group Arlon (Sud Luxembourg, Belgique)
pertinent, e adj. Approprié ; qui se rapporte exactement à ce dont il est question.
Scheme
Tu codes en Scheme, ou Perl, tu utilises une quasiquotation (ou une chaine de caracteres), quelques macros, et un eval.
Bon, c'est pas très hype car ca marche depuis avant ta naissance. Néanmoins, si tu remplaces les S-expressions par du XML, ca fait tout de suite vachement plus cool, et ca marche aussi bien.
tcc
As tu pensé à tcc qui est capable je crois de compiler à la volée du code C ? Par contre je crois qu'il reste des bugs...
Il y a un module pour le langage lua qui l'utilise
désolée, pas le temps de développer
-
[^]Re: tcc
Posté par Mildred (Jabber id, page perso, ) le 22/06/2007 à 18:18. (lien). Évalué à 6.http://fabrice.bellard.free.fr/tcc/
The libtcc library enables you to use TCC as a backend for dynamic code generation.
Read the `libtcc.h' to have an overview of the API. Read `libtcc_test.c' to have a very simple example.
The idea consists in giving a C string containing the program you want to compile directly to libtcc. Then you can access to any global symbol (function or variable) defined.
L'exemple : http://cvs.savannah.gnu.org/viewvc/tinycc/tinycc/libtcc_test(...)
-
[+] [^]Re: tcc
Posté par Mildred (Jabber id, page perso, ) le 22/06/2007 à 21:32. (lien). Évalué à -2.http://fabrice.bellard.free.fr/tcc/
The libtcc library enables you to use TCC as a backend for dynamic code generation.
Read the `libtcc.h' to have an overview of the API. Read `libtcc_test.c' to have a very simple example.
The idea consists in giving a C string containing the program you want to compile directly to libtcc. Then you can access to any global symbol (function or variable) defined.
L'exemple : http://cvs.savannah.gnu.org/viewvc/tinycc/tinycc/libtcc_test(...)
Gnu Lightning
Suivant ce que tu veut faire, il y a gnu lightning qui existe depuis pas mal de temps et réponds à une moitié du problème (pseudo asm -> binaire -> exec).
Reste à faire un parser pour produire du code dans leur format.
http://www.gnu.org/software/lightning/lightning.html
Cela dit, pourquoi tu veut compiler le code à la volée? Ce serait plus simple de prendre un truc comme lua, que tu peut binder assez facilement avec du c.
-
[^]Re: Gnu Lightning
Posté par Val1472 () le 25/06/2007 à 10:48. (lien). Évalué à 1.Merci PenPen. Je ne connaissais pas cette librairie. C'est exactement le genre de choses que je recherchais. :)
J'ai un mauvais à priori concernant les performances d'une solution qui embarque du lua, du python ou du script en règle générale. Ca reste qu'un à priori. Un jour, je prendrais le temps de faire des benchs pour me faire une idée plus précise.-
[^]Re: Gnu Lightning
Posté par briaeros007 () le 26/06/2007 à 20:15. (lien). Évalué à 2.ben le script ca permet de gagner du temps ... sur les parties non critiques (exemple pour python : parser une conf puis l'injecter dans du C ;))
(temps de code).
Ensuite si ta fonction est appelé 15 millions de fois en une seconde, oui il est preferable de bien l'optimiser celle la;)--
Subete ga wakatta toki…watashi ga anta wo korosu.
-
lex et yacc
C'est pas comme ça qu'on fait normalement ?

Les journaux sont destinés à des informations qui ne sont pas suffisamment intéressantes
pour être validées en dépêche (sinon n'hésitez pas à proposer votre information en
dépêche), qui sont sans rapport avec Linux ou le libre, ou simplement pour donner votre
avis. Si vous désirez poser une question, merci d'utiliser 

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.
Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.