Seuls les membres ayant 30 points peuvent parler sur le chat.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » liblog, une lib pour débugger efficacement
MilangHors ligneMembrePoints: 325 Défis: 2 Message

liblog, une lib pour débugger efficacement

Posté le 18/09/2019 17:33

Je vous présente une lib de log simple d'utilisation basée sur gint. Si vous n'avez pas gint, allez voir de ce côté ci : gint, un noyau pour développer des add-ins
L'utilisation se rapproche fortement de printf, on envoie juste une chaine de caractères et c'est tout !

On peut si besoin afficher ce log en cas d'erreur, ou simplement pour consulter l'état d'éxécution du programme à un moment donné. Le reste du temps, ce log est invisible, mais néanmoins stocké. La lib fournit notamment la possibilité d'afficher le log en cas d'exception (system error), avec la possibilité de faire défiler le continu avec les flèches.

En plus, la librairie est construite pour être multiplateforme, donc elle fonctionne aussi bien sur les fx9860g que les fxcg50. . En voici un exemple sur la famille des fx9860g :

Installation
clone
Tout d'abord, clonez le dépot gitea.
git clone https://gitea.planet-casio.com/Milang/liblog.git

configure
Au choix selon la famille de calculatrices ciblée:
./configure --fx9860g
./configure --fxcg50

make && make install
Taper ensuite quelque soit le modèle :
make
make install


La compatibilité avec fxcg50 reste toutefois à tester, mais je n'ai pas le matériel pour Il faut noter également que la librairie peut être installée simultanément pour les deux plateformes, il suffit juste de l'installer 2 fois, une fois par plateforme.

Utilisation
Configuration
Dans le fichier project.cfg du projet, modifier la ligne suivante
LDFLAGS =

Il suffit d'ajouter 2 nouveaux flags, comme ça
LDFLAGS = -llog-<fx/cg> -lgint-<fx/cg>
exemple pour les fx9860g : LDFLAGS = -llog-fx -lgint-fx
Voyons le code source, mainenant
D'abord, il faut inclure le header de liblog
#include <liblog.h>


Fonctions
Écrire dans le log est très simple :
On utilise la fonction ll_send("Votre message de debug\n")
Le \n sert à revenir à la ligne, mais vous pouvez afficher plusieurs messages à la suite, comme dans cet exemple :
ll_send("Bonjour,");
ll_send(" ceci est un log.\n");
ll_send("Pratique, non ?");

Ce code donnerait le log suivant :
Bonjour, ceci est un log.
Pratique, non ?

Cependant, le log est invisible et il faut l'afficher manuellement.
Afficher le log peut être utile pour le débug, notamment en cas d'exception.
Il suffira de taper la commande suivante :
ll_display();
// getkey(); si vous voulez mettre le programme en pause pour lire

Et maintenant nous arrivons probablement à la partie la plus intéressante, la fonction de gestion des exceptions ! Elle s'active avec cette fonction, ll_set_panic() En cas d'exception (System Error), elle vous affichera le log, et surtout vous laissera la possibilité de scroll et de remonter l'historique afin de voir qu'est ce qui a planté.

Enfin, la fonction ll_pause() fait la même chose que lors d'une panic, mais laisse la possibilité de continuer l'exécution du programme avec "EXIT"



Voilà, je vous laisse essayer, et vous pouvez poser vos questions sur ce topic si vous n'avez pas bien compris quelque chose . La lib est sous la GNU General Public License 3



Pages : Précédente1, 2
MilangHors ligneMembrePoints: 325 Défis: 2 Message

Citer : Posté le 21/09/2019 11:01 | #


Tu peux essayer
Elle marche avec le scrolling sur ma g35+E.
Elle marche sur l'émulateur du sdk, à l'exception du panic mais cela est du au sdk qui a un comportement différent en cas de crash

Ajouté le 21/09/2019 à 12:51 :
Bon, j'ai ajouté la fonction ll_pause() qui permet de suspendre l’exécution du programme, avoir la possibilité d'inspecter le log et reprendre l’exécution ensuite

De plus, à la suite d'une suggestion de @Kirafi, Il est possible d'envoyer plusieurs messages sur une seule ligne, et pour finir une ligne, on ajoute '\n'

NinestarsHors ligneMembrePoints: 2254 Défis: 22 Message

Citer : Posté le 23/09/2019 18:39 | #


C'est formidable ta lib !
Pour le debug c'est vraiment top !!
Si on utilise des timers, est ce que cela met en pause les timers aussi quand on fait ll_pause() ?
MilangHors ligneMembrePoints: 325 Défis: 2 Message

Citer : Posté le 23/09/2019 19:08 | #


Ah, non, pas encore
Mais pour cela il faudrait également qu'elle restaure l'état des timers à la fin, ce qui doit être possible mais plus compliqué. En tous cas, je le mets sur ma TODO list
LephenixnoirEn ligneAdministrateurPoints: 16021 Défis: 140 Message

Citer : Posté le 23/09/2019 20:31 | #


C'est peut-être quelque chose à faire dans gint ça.
MilangHors ligneMembrePoints: 325 Défis: 2 Message

Citer : Posté le 29/09/2019 19:22 | #


J'ai un bug vraiment étrange
Alors voici une fonction d'affichage classique :

static void show_line(const log_line* l, int y)
{
    dtext(1, y, &l->text[0], C_BLACK, C_NONE);
}

void ll_display_custom(log_line* line)
{
    dfont(NULL);
    dclear(C_WHITE);
    for (int i=0; i<8; i++)
    {
#ifdef FX9860G
        show_line(line, 63 - 8*(i+1));
#endif
#ifdef FXCG50
        show_line(line, 224 - 13*(i+1));
#endif
        line=line->previous;
        if (!line)
            break;
    }
    dupdate();
}

void ll_pause()
{
    dclear(C_WHITE);
    log_line* line=current_line;
    while (1)
    {
        ll_display_custom(line);
        int key = getkey().key;
        if (key==KEY_UP)
        {
            log_line* linet=line->previous;
            if (linet)
                line=linet;
        }
        if (key==KEY_DOWN)
        {
            log_line* linet=line->next;
            if (linet)
                line=linet;
        }
        if (key==KEY_EXIT)
            break;
    }
}


Donc normalement la fonction ll_pause affiche le contenu du log à l'écran, et laisse ensuite l'utilisateur scroller jusqu'à ce qu'il presse <EXIT>

Cette fonction marche parfaitement dans le cas de figure suivant :
// des actions
                ll_pause();
// d'autres actions

Mais par contre n'affiche qu'un écran blanc dans le cas suivant :

if (event.key==KEY_F1 && event.type==KEYEV_DOWN)
{
ll_pause();
}

Cependant, le clavier est géré de la même façon, il faut appuyer sur <EXIT> pour sortir de la fonction, ce qui prouve qu'elle est bien lancée

Avez vous des pistes ? Je n'y comprends strictement rien, surtout au niveau de l'affichage .
LephenixnoirEn ligneAdministrateurPoints: 16021 Défis: 140 Message

Citer : Posté le 29/09/2019 19:26 | #


Est-ce que tu exécuterais pas ll_pause() dans une interruption dans le second cas ? La fonction dupdate() a besoin d'interruptions pour fonctionner correctement. Si c'est le cas, essaie dupdate_noint() qui est une gourouterie prévue pour ce cas précis.
MilangHors ligneMembrePoints: 325 Défis: 2 Message

Citer : Posté le 29/09/2019 19:35 | #


L'exécuter dans une interruption ? c'est à dire en cas d'exception ?

Je ne comprends pas, je fais les tests dans le même thread de calcul, c'est juste que avec le if rien ne s'affiche

Ajouté le 29/09/2019 à 20:00 :
Ah j'ai une autre piste, c'est la surutilisation de ram
Quand on envoie au delà d'un certain seuil de données, plus rien ne s'affiche
LephenixnoirEn ligneAdministrateurPoints: 16021 Défis: 140 Message

Citer : Posté le 29/09/2019 20:17 | #


L'exécuter dans une interruption ? c'est à dire en cas d'exception ?

Ça ou dans le callback d'un timer.
Pages : Précédente1, 2

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2019 | Il y a 83 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd