J'utilise des interfaces Lua pour obtenir la prise en charge de Lua dans mon programme C #, le thread du travailleur va geler si l'utilisateur soumet le code comme celui-ci J'ai un moyen de détecter si une boucle infinie est En cours d'exécution, mais j'ai besoin d'une bonne façon de quitter la méthode de dostring du fil de travail. Des idées? P> EDIT: @Kikito, oui je déteigne quelque chose comme ça. Le problème que j'ai est que je ne trouve pas de manière propre de tuer la méthode de dostring, il ressemble à la classe principale des interfaces Lua (LUA) a des dépendances statiques, car si je fais EDIT: A Branche de fonctionnalité montrant mon code .Close
https://github.com/andersmalmgren/freepie/tree / détecter et récupérer-infite-lua-boucle p> p> lua.close (); code > Sur mon exemple, il fera avorter la méthode de dostre, mais la prochaine fois que je parle une classe Lua
New Lua (); Code> Il va crancer dire quelque chose sur la mémoire protectrice P>
6 Réponses :
Je suggère de la manipuler comme une autre erreur Lua. En d'autres termes, menacer le code ci-dessus comme si l'utilisateur venait de écrir
error("Script execution has been cancelled after stalling for too long")
Eh bien, vous ne pouvez pas le faire de cette façon, car la méthode de dosage est bloquée en faisant la boucle infinie. Je vais mettre à jour mon or orginal avec plus d'informations
Le problème est toujours que je ne trouve pas un moyen d'abandonner l'appel à dosage infini sans casser le moteur Lua pour tous les appels futurs
Je n'ai pas trouvé de moyen d'exécuter le code Lua de l'événement Hook avec le wrapper C #, vous avez trouvé un moyen?
Réglage des crochets n'est pas suffisant du tout em> pour éviter les déchets inattendus de ressources, sans parler d'abuser - voici un exemple simple (le temps est passé pendant la correspondance de modèle de chaîne, aucun crochet de débogage n'est appelé): < / p>
Le seul moyen fiable de forcer les contraintes de temps / de mémoire sur une pièce de code LUA consiste à exécuter l'interpréteur LUA dans un processus à part entière et à faire surveiller votre système d'exploitation. strong> p >
La bonne chose avec Lua est que vous n'aurez besoin d'aucune configuration de permission compliquée et dépendante du système d'exploitation pour Sandboxing: vous limitez-vous simplement la durée et la mémoire (raisonnables; sous Windows, il y a Objets de travail , Unix est ulimite - pertinent: Limitation de ressources Linux ), puis gardez des choses comme Os.execute, la moitié de la moitié du Io-bibliothèque et modules comme LuasCocket loin du Scriptter (assez facile). P>
Vous pouvez gérer presque tout (sauf la violation des délais / limites de mémoire) sans détremper votre interpréteur Lua: enveloppez simplement l'exécution du code fourni par l'utilisateur à l'intérieur d'un PCALL ; Si vous appelez des fonctions Lua-API qui pourraient vous échouer, vous devez les envelopper dans une fonction de PCALL, également (ou définir une fonction de panique Lua et la gérer de là). P>
[Je ne voulais pas que les gens se glisse sur ce fil supposent que Debug.Sethook est adéquat pour Sandboxing et Stackoverflow ne me laisserait pas commenter (encore)] p> s = ('a'): REP (20000): Match ('.- B') CODE> P>
Récupération des erreurs dans Code SandBoxed H2>
J'ai utilisé deux techniques pour résoudre ce problème. Le premier consiste à appeler la méthode DOFILE ou DOSTRING à l'intérieur d'une tâche distincte. De cette façon, vous pouvez abandonner le fil. Je ne connais aucune technique (disons d'un crochet) pour sortir de l'interprète. p>
Un autre moyen serait de configurer un AppDomain . En utilisant ceci, vous pouvez également définir des contraintes séparées (preuve et autorisation) voir
Qu'en est-il de la définition de la ligne de ligne avant em> exécuter le code Lua? Je ne sais pas, est-ce possible en C #, mais il est possible dans l'original C Lua. P>
Est-ce que votre détecteur de boucle est déjà exécuté dans une tâche C # différente? P>
Une partie importante consiste à ne pas réinitialiser cette variable (ni C # ou Lua) avant de vous assurer que vous êtes vraiment sûr de la finition de votre tâche, car l'utilisateur peut attraper votre erreur via
TerminAtelua Code> et lancez Lua Error (il devrait être possible). LI>
PCALT CODE> et essayer de le gérer. p>
Mettez la boucle Lua à l'intérieur d'une coroutine et à la fin de chaque boucle, utilisez simplement la déclaration de rendement NULL code> pour attendre un cadre (permettant au fil du travailleur d'être exécuté). P>
Vous pouvez le faire comme ceci, si vous souhaitez détecter si une boucle est toujours en marche. La sortie sera la suivante: P> Still running
Still running
Still running
Still running
Still running
Loop stopped running
Après 30 secondes de googling, j'ai découvert que Lua soutient les événements de crochet: «Il existe quatre types d'événements pouvant déclencher un crochet: les événements d'appel se produisent à chaque fois que Lua appelle une fonction; Les événements de retour se produisent chaque fois qu'une fonction retourne; Les événements de ligne se produisent lorsque Lua commence à exécuter une nouvelle ligne de code; et les événements comptent après un nombre donné d'instructions ». Voilà. Avec les instances d'interprète, j'ai utilisé une exception dans l'événement «Onsomething» qui est piégé par le fil appelé l'interprète. Je ne sais pas à propos de Lua, cependant.
Quelqu'un a une solution pour les interaces Lua pour C #?
La mise en œuvre de la LUA originale (écrite en C) devrait survivre à un
proche code> (c'est réentrant et l'état est complètement encapsulé). Si le C # on ne veut pas, déposez un bogue. (Vous aurez toujours un certain code dans le crash autrement, par exemple Extrêmement longues (décennies ou plus) Opérations de cordes , les crochets ne vous aideront pas avec cela.)
Désolé pour la réponse tardive, les vacances .. Le C # Wrapper n'est pas un projet très actif: / Mais déposera un problème, merci
J'ai fait une branche de fonctionnalité afin que vous puissiez tester le code ou voir si j'ai fait des erreurs github.com/andersmalmgren/freepie/tree/...