Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » gint : un noyau pour développer des add-ins
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

gint : un noyau pour développer des add-ins

Posté le 20/02/2015 17:30

Ce topic fait partie de la série de topics du fxSDK.

En plus des options de programmation intégrée comme le Basic Casio ou Python, la plupart des calculatrices Casio supportent des add-ins, des programmes natifs très polyvalents avec d'excellentes performances. Les add-ins sont généralement programmés en C/C++ avec l'aide d'un ensemble d'outils appelé SDK.

Plusieurs SDK ont été utilisés par la communauté avec le temps. D'abord le fx-9860G SDK de Casio avec fxlib pour Graph monochromes (plus maintenu depuis longtemps). Puis le PrizmSDK avec libfxcg pour Prizm et Graph 90+E (encore un peu actif sur Cemetech). Et plus récemment celui que je maintiens, le fxSDK, dont gint est le composant principal.

gint est un unikernel, ce qui veut dire qu'il embarque essentiellement un OS indépendant dans les add-ins au lieu d'utiliser les fonctions de l'OS de Casio. Ça lui permet beaucoup de finesse sur le contrôle du matériel, notamment la mémoire, le clavier, l'écran et les horloges ; mais aussi de meilleures performances sur le dessin, les drivers et la gestion des interruptions, plus des choses entièrement nouvelles comme le moteur de gris sur Graph monochromes.

Les sources de gint sont sur la forge de Planète Casio : dépôt Gitea Lephenixnoir/gint

Aperçu des fonctionnalités

Les fonctionnalités phares de gint (avec le fxSDK) incluent :

  • Toutes vos images et polices converties automatiquement depuis le PNG, sans code à copier (via fxconv)
  • Un contrôle détaillé du clavier, avec un GetKey() personnalisable et un système d'événements à la SDL
  • Une bibliothèque standard C plus fournie que celle de Casio (voir fxlibc), et la majorité de la bibliothèque C++
  • Plein de raccourcis pratiques, comme pour afficher la valeur d'une variable : dprint(1,1,"x=%d",x)
  • Des fonctions de dessin, d'images et de texte optimisées à la main et super rapides, surtout sur Graph 90+E
  • Des timers très précis (60 ns / 30 µs selon les cas, au lieu des 25 ms de l'OS), indispensables pour les jeux
  • Captures d'écran et capture vidéo des add-ins par USB, en temps réel (via fxlink)

Avec quelques mentions spéciales sur les Graph monochromes :
Un moteur de gris pour faire des jeux en 4 couleurs !
La compatibilité SH3, SH4 et Graph 35+E II, avec un seul fichier g1a
Une API Unix/POSIX et standard C pour accéder au système de fichiers (Graph 35+E II seulement)

Et quelques mentions spéciales sur les Graph 90+E :
Une nouvelle police de texte, plus lisible et économe en espace
Le dessin en plein écran, sans les bordures blanches et la barre de statut !
Un driver écran capable de triple-buffering
Une API Unix/POSIX et standard C pour accéder au système de fichiers

Galerie d'add-ins et de photos

Voici quelques photos et add-ins réalisés avec gint au cours des années !



Arena (2016)Plague (2021)



Rogue Life (2021)



Momento (2021)



Communication avec le PC (cliquez pour agrandir)


Utiliser gint pour développer des add-ins

Les instructions pour installer et utiliser gint sont données dans les divers tutoriels recensés dans le topic du fxSDK. Il y a différentes méthodes de la plus automatique (GiteaPC) à la plus manuelle (compilation/installation de chaque dépôt). Le fxSDK est compatible avec Linux, Mac OS, et marche aussi sous Windows avec l'aide de WSL, donc normalement tout le monde est couvert

Notez en particulier qu'il y a des tutoriels de développement qui couvrent les bases ; tout le reste est expliqué dans les en-têtes (fichiers .h) de la bibliothèque que vous pouvez consulter en ligne, ou dans les ajouts aux changelogs ci-dessous.

Changelog et informations techniques

Pour tester les fonctionnalités et la compatibilité de gint, j'utilise un add-in de test appelé gintctl (dépôt Gitea Lephenixnoir/gintctl). Il contient aussi une poignée d'utilitaires d'ordre général.

Ci-dessous se trouve la liste des posts indiquant les nouvelles versions de gint, et des liens vers des instructions/tutoriels supplémentaires qui accompagnent ces versions.

VersionDateInfos supplémentaires
gint 2.10.02 Avril 2023
gint 2.9.021 Août 2022
gint 2.8.017 Mai 2022Effets dynamiques sur les imagesAPI de manipulations d'images
Overclock intégré
gint 2.7.119 Mars 2022Tutoriel capture des flux standards
gint 2.7.031 Décembre 2021
gint 2.6.029 Août 2021Tutoriel de capture vidéo par USB
gint 2.5.28 Juin 2021
gint 2.5.12 Juin 2021
gint 2.5.026 Mai 2021Intégration de fxlibc (dépôt) — Tutoriel de communication par USB
gint 2.4.027 Avril 2021Api GINT_CALL() pour les callbacks
gint 2.3.12 Février 2021
gint 2.3.029 Janvier 2021
gint 2.2.112 Janvier 2021
gint 2.2.011 Janvier 2021
gint 2.1.116 Septembre 2020
gint 2.1.021 Août 2020Polices UnicodeNouvelle API du moteur de gris
gint 2.0.3-beta10 Juillet 2020Modifications de l'API timer
gint 2.0.2-beta17 Juin 2020
gint 2.0.1-beta1er Juin 2020

Anecdotes et bugs pétés

Ô amateurs de bas niveau, j'espère que vous ne tomberez pas dans les mêmes pièges que moi.


TODO list pour les prochaines versions (2023-04-03)

gint 2.11
  1. Changements de contextes CPU. À reprendre du prototype de threading de Yatis pour permettre l'implémentation d'un véritable ordonnanceur. Demandé par si pour faire du threading Java.
  2. Applications USB. Ajouter le support de descripteurs de fichiers USB. Potentiellement pousser jusqu'à avoir GDB pour debugger.
  3. Support de scanf() dans la fxlibc. Codé par SlyVTT, plus qu'à nettoyer et fusionner.

Non classé

  • Regarder du côté serial (plus facile que l'USB) pour la communication inter-calculatrices (multijoueur) et ultimement l'audio (libsnd de TSWilliamson).
  • Un système pour recompiler des add-ins mono sur la Graph 90+E avec une adaptation automatique.
  • Support des fichiers en RAM pour pouvoir utiliser l'API haut-niveau sur tous les modèles et éviter la lenteur de BFile à l'écriture quand on a assez de RAM.



Précédente 1, 2, 3 ··· 10 ··· 20 ··· 30 ··· 40 ··· 50 ··· 60 ··· 70, 71, 72, 73, 74
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

Citer : Posté le 10/04/2024 19:37 | # | Fichier joint


Ce post sera dans les notes de publication de gint 2.11. @RDP
La fonctionnalité est actuellement disponible sur les branches dev du fxSDK et de gint.


Support élémentaire du debuggage à distance

Grâce à une contribution de Redoste (gint#27), nous avons maintenant la possibilité de debugger les add-ins gint à distance en utilisant GDB.

Pour l'instant fxlink est nécessaire donc le debuggage à distance n'est pas possible sous Windows/WSL.

Installation

Il vous faura mettre à jour gint ainsi que le fxSDK, et installer le nouveau dépôt Lephenixnoir/sh-elf-gdb qui fournit GDB pour la calculatrice.

% giteapc install -u
% giteapc install Lephenixnoir/sh-elf-gdb

Note: Pour ceux qui ont déjà sh-elf-gdb parce qu'ils m'ont aidé à tester, je vous conseille de le désinstaller puis réinstaller : j'ai depuis ajouté un patch qui évite une erreur bizarre quand on debugge depuis Add-In Push.

Utilisation sur la calculatrice

Pour que le debugger soit utile il faut compiler avec les infos de debug activées, c'est à dire avec l'option -g. C'est fait par défaut dans les nouveaux projets avec la nouvelle version du fxSDK, mais pour les projets existants il faut l'ajouter manuellement dans le target_compile_options() de CMakeLists.txt :

target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -g)

Le debugger démarre automatiquement lorsqu'une exception se produit après que vous ayez appelé la fonction gdb_start_on_exception(), typiquement au début de votre main(). L'appel de cette fonction est ce qui cause l'inclusion du code approprié dans votre add-in.

#include <gint/gdb.h>

int main(void)
{
    gdb_start_on_exception();
    /* ... */
}

Ce démarrage automatique est très utile si un crash se produit mais que vous ne l'attendiez pas : lorsque vous voyez le crash, vous pouvez brancher la calculatrice et commencer à debugger.

Par contre, ça ne permet pas de préconfigurer le programme (e.g. pour mettre des breakpoints avant de commencer l'exécution). Pour ça, vous pouvez simplement créer une exception passagère avec trapa au début de main().

int main(void)
{
    gdb_start_on_exception();
    /* Forcer une exception pour ajouter un breakpoint */
    __asm__("trapa #42");

    /* ... */
}

Indicateurs visuels du processus de debuggage à distance

Pour ne pas se perdre (et diagnostiquer tout potentiel bug avec le système), le debugger à distance affiche des icônes en haut à droite de l'écran.


De haut en bas :
  • Bleu/cercle : travail en cours. S'affiche après un crash quand la connection à GDB n'est pas encore faite. S'affiche aussi durant le traitement des commandes, mais si brièvement qu'on ne le voit pas.
  • Rouge/croix : erreur dans le système de debuggage. Si ça s'affiche, faites-moi signe.
  • Violet/double flèche : en attente de communication. Généralement on ne voit que ça.
  • Gris/trois points : inactif, en attente de travail.

Le plus important est que lorsque le debuggage à distance avec GDB est activé, il n'y a plus d'écran System ERROR. Et donc un crash se verra uniquement à la présence d'un indicateur visuel en haut à droite de l'écran. Ils sont petits surtout sur la Graph 90+E donc faites attention.

Utilisation sur le PC

Avant ou après que la calculatrice n'initie la connexion à GDB du fait d'un crash, lancez GDB sur l'ordinateur à l'aide du wrapper fxsdk gdb.

% fxsdk gdb build-cg/myaddin

Les arguments de fxsdk gdb sont les mêmes que ceux de la commande gdb classique, et en particulier vous devez spécifier le nom du fichier ELF que vous êtes en train d'exécuter sur la calculatrice. Typiquement c'est build-*/myaddin. Attention à bien sélectionner build-cg-push si vous envoyez votre add-in avec Add-In Push parce que ce n'est pas le même ELF.

La différence entre fxsdk gdb et sh-elf-gdb directement est que le premier démarre automatiquement un bridge qui permet de communiquer avec la calculatrice et lance ensuite GDB en mode debuggage à distance. (L'option --bridge-only permet de ne démarrer que le bridge, si vous connaissez bien GDB et que vous voulez voir passer les paquets échangés.)

En gros c'est tout ce qu'il y a à faire, mais pour ne pas vous laisser sans détail sur GDB voilà quand même quelques explications de base sur son utilisation.

Exemples d'utilisation

Je pars du programme suivant, qui a pour bug évident qu'un pointeur invalide s'est retrouvé dans le tableau avec la liste des entrées du menu.

#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/gdb.h>

void draw_menu(void)
{
     const char *entries[5] = {
          "Play", "Settings", "Credits", "Quit", (char *)0x14141414
     };
     for(int i = 0; i < 5; i++)
          dtext(4, 4+12*i, C_BLACK, entries[i]);
}

int main(void)
{
     gdb_start_on_exception();

     dclear(C_WHITE);
     draw_menu();
     dupdate();

     getkey();
     return 0;
}

J'ai remarqué un crash tout à l'heure donc j'ai rajouté l'include ainsi que l'appel à la fonction gdb_start_on_exception() au début du programme. Je le lance sur ma Graph 90+E, et j'obtiens la pastille bleue. Je lance donc GDB sur le PC :

% fxsdk gdb build-cg-push/myaddin
[19:26] calculators: waiting for calculator to connect...
[19:26] calculators 001:103: successfully claimed interface!
[19:26] socket: waiting for client on  "/tmp/fxsdk-gdb-bridge-001-103.socket"...
Reading symbols from build-cg-push/myaddin...
The target architecture is set to "sh4al-dsp".
Remote debugging using /tmp/fxsdk-gdb-bridge-001-103.socket
0x8c202ecc in dtext_utf8_next (str_pointer=0x8c1dff40) at /home/el/Projects/gint/src/render/topti.c:59
59        uint8_t lead = *str++;
(gdb)

Les quelques messages commençant par "[19:26]" sont affichés par le bridge qui gère la connexion à la calculatrice, le reste est ensuite affiché par GDB. La partie qui nous intéresse commence à 0x8c202ecc, elle nous indique :
  • À quel endroit on est du programme (la fonction dtext_utf8_next)
  • Les paramètres avec lesquels cette fonction a été appelée (str_pointer=0x8c1dff40)
  • Dans quel fichier source cette fonction se trouve (src/render/topti.c ligne 59 dans gint)
  • La ligne de code où l'erreur se produit (uint8_t lead = *str++;)

Et ensuite le prompt, "(gdb)". Clairement le crash s'est produit dans une fonction de gint, mais ce n'est pas forcément un bug dans gint ; on a peut-être mal appelé une fonction. La commande backtrace (raccourci "bt") affiche la série d'appels par laquelle on est arrivés au niveau du crash.

(gdb) bt
#0  0x8c202ecc in dtext_utf8_next (str_pointer=0x8c1dff40) at /home/el/Projects/gint/src/render/topti.c:59
#1  0x8c20347c in topti_render (size=-1, bg=-1, fg=0, f=0x8c20d2b0, str_char=0x14141414 <error: Cannot access memory at address 0x14141414>, y=52, x=4) at /home/el/Projects/gint/src/render-cg/topti.c:84
#2  dtext_opt (x=4, y=<optimized out>, fg=0, bg=-1, halign=0, valign=0, str=0x14141414 <error: Cannot access memory at address 0x14141414>, size=-1) at /home/el/Projects/gint/src/render-cg/topti.c:140
#3  0x8c202df2 in dtext (x=<optimized out>, y=<optimized out>, fg=<optimized out>, str=<optimized out>) at /home/el/Projects/gint/src/render/dtext.c:6
#4  0x8c200264 in draw_menu () at /home/el/Programs/tmp/gint-remote-debugging-example/src/main.c:12
#5  0x8c2002c4 in main () at /home/el/Programs/tmp/gint-remote-debugging-example/src/main.c:20

Vous pouvez voir pour chaque fonction son nom, ses paramètres, et le fichier source associé, et on remonte jusqu'à main() et draw_menu(), les fonctions de notre programme source.

Notez que pas mal de paramètres sont "<optimized out>" : c'est le résultat du fait que le compilateur a optimisé le programme et donc certaines variables ont sauté, et certains bouts de code auront sauté aussi d'ailleurs. Ça vous complique un peu la tâche. Si vous y tenez vous pouvez compiler avec -O0 ce qui vous donnera des informations de debug de meilleure qualité, par contre la taille de l'add-in et les perfs vont en prendre un sacré coup.

Plus important encore, vous remarquez qu'il y a un paramètre pour lequel il est écrit <error: Cannot access memory at address 0x14141414>, et ça déjà ça nous révèle qu'on a un pointeur invalide qui se balade dans le programme.

Ça se verra encore mieux si on inspecte les variables locales de la fonction dtext_utf8_next() qui a planté avec la commande info locals.

(gdb) info locals
str = 0x14141415 <error: Cannot access memory at address 0x14141415>
lead = <optimized out>
n2 = <optimized out>
n3 = 253 '\375'
n4 = <optimized out>

Vous ne connaissez pas forcément le code de cette fonction interne de gint mais on peut se douter que str est une chaîne de caractères. Et le pointeur est bien invalide : vous pouvez le vérifier en essayant d'afficher ses contenus avec la commande print qui peut afficher à peu près n'importe quelle expression C.

(gdb) print *str
Cannot access memory at address 0x14141415

J'en profite pour mentionner que les expressions qu'on évalue sont interprétées dans le contexte de la fonction dtext_utf8_next(). Pour inspecter les variables locales d'une autre fonction listée par bt et faire des calculs sur les valeurs associées, il faut d'abord sélectionner la fonction avec la commande frame suivi du numéro affiché par bt (par exemple frame 3 pour monter dans la fonction dtext()).

Normalement à ce stade on irait plutôt essayer de comprendre d'où le pointeur vient, mais pour s'amuser un peu et montrer les fonctionnalités cool implémentées par Redoste supposons qu'on veut continuer l'exécution en contournant l'erreur. On peut aller chercher l'instruction exacte qui a planté en affichant le code autour de la valeur $pc (x c'est "examine" pour regarder la mémoire, 3i demande 3 instructions, et pc est l'adresse de l'instruction qui a planté).

(gdb) x/3i $pc
=> 0x8c202ecc <dtext_utf8_next+6>:  mov.b @r6+,r1
   0x8c202ece <dtext_utf8_next+8>:  extu.b   r1,r1
   0x8c202ed0 <dtext_utf8_next+10>: mov   r1,r0

Ici c'est donc r6 qui contient le pointeur invalide, ce qu'on peut confirmer avec info registers.

(gdb) info registers
r0             0xb                 11
r1             0x0                 0
(...)
r6             0x14141414          336860180
(...)
r15            0x8c1dff10          0x8c1dff10
pc             0x8c202ecc          0x8c202ecc <dtext_utf8_next+6>
pr             0x8c20347c          0x8c20347c <dtext_opt+212>
(...)

Pour contourner l'erreur d'accès mémoire, je peux assigner une valeur factice à r1 (un caractère de fin de chaîne, donc la valeur 0) puis placer pc sur l'instruction d'après :

(gdb) set $r1 = 0
(gdb) set $pc = 0x8c202ece

Ensuite je continue l'exécution. Ici on ne peut pas utiliser la commande continue habituelle parce que sinon GDB enverrait à l'add-in la segfault qu'il était sur le point de se prendre (et le programme s'arrêterait, vous ramenant au menu principal). Il faut être plus explicite et demander de continuer sans signal avec la commande signal 0.

(gdb) signal 0
Continuing with no signal.

Le programme continue et se termine normalement. Voilà pour une première démo.

Maintenant, je recommence mais cette fois je vous montre comment on peut insérer un breakpoint et surveiller l'exécution avant que le bug ne se produise pour voir où ça part en vrille. D'abord on va forcer un arrêt avant que le bug ne se produise en ajoutant un petit trapa dans main() :

int main(void)
{
     gdb_start_on_exception();
     __asm__("trapa #42");

     dclear(C_WHITE);
     draw_menu();
     /* ... */
}

Et cette fois le programme a une erreur dès l'entrée dans main(), ce qu'on voit dans GDB.

% fxsdk gdb build-cg-push/myaddin
[23:18] calculators: waiting for calculator to connect...
[23:18] calculators 001:024: successfully claimed interface!
[23:18] socket: waiting for client on "/tmp/fxsdk-gdb-bridge-001-024.socket"...
Reading symbols from build-cg-push/myaddin...
The target architecture is set to "sh4al-dsp".
Remote debugging using /tmp/fxsdk-gdb-bridge-001-024.socket
main () at /home/el/Programs/tmp/gint-remote-debugging-example/src/main.c:20
20        dclear(C_WHITE);

On place alors un breakpoint. La commande habituelle pour faire ça dans GDB est break (raccourci "b"), mais ça vous donne un "breakpoint logiciel", et sans rentrer dans les détails on ne supporte que les "breakpoints matériels". Donc il faut utiliser la commande hbreak (raccourci "hb") à la place. Attention, si vous utilisez b ça risque de ne pas vous donner d'erreur (sur Graph 90+E avec Add-In Push) mais le breakpoint ne marchera pas.

(gdb) hb dtext
Hardware assisted breakpoint 1 at 0x8c202ddc: file
/home/el/Projects/gint/src/render/dtext.c, line 6.
(gdb) c
Continuing.

Breakpoint 1, dtext (x=4, y=4, fg=0, str=0x8c20c0d0 "Play") at /home/el/Projects/gint/src/render/dtext.c:6
6        dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, str);

En spécifiant hb dtext j'indique à GDB que je veux m'arrêter chaque fois qu'on rentre dans la fonction dtext(). Une fois le breakpoint placé je reprends l'exécution avec la commande continue (raccourci "c").

Le programme s'arrête ensuite puisque le breakpoint est atteint, et vous pouvez voir aux paramètres qu'on est dans le premier appel, sur le point d'afficher le texte "Play". Je continue encore, et en spécifiant 4 en paramètre à continue j'indique que je veux sauter les 3 prochaines occurrences de ce breakpoint.

(gdb) c 4
Will ignore next 3 crossings of breakpoint 1.  Continuing.

Breakpoint 1, dtext (x=4, y=52, fg=0, str=0x14141414 <error: Cannot access memory at address 0x14141414>)
     at /home/el/Projects/gint/src/render/dtext.c:6
6        dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, str);

Avec ça je me retrouve à l'arrêt au début de l'exécution du dtext() fatidique qui va nous créer le crash ; vous pouvez voir qu'on retrouve le pointeur invalide dans le paramètre str. Notez qu'à ce stade la segfault ne s'est pas encore produite !

Pour progresser plus lentement dans l'exécution, on peut utiliser la commande step (raccourci "s") pour avancer une ligne de code à la fois. Ici j'exécute la commande plusieurs fois à la suite, et vous pouvez voir qu'on descend dans les fonctions de rendu de texte de gint doucement mais sûrement.

(gdb) s
dtext_opt (x=4, y=52, fg=0, bg=-1, halign=0, valign=0, str=0x14141414 <error: Cannot access memory at address 0x14141414>, size=-1)
     at /home/el/Projects/gint/src/render-cg/topti.c:129
129        if(halign != DTEXT_LEFT || valign != DTEXT_TOP)
(gdb) s
140        topti_render(x, y, str, topti_font, fg, bg, size);
(gdb) s
topti_render (size=<optimized out>, bg=<optimized out>, fg=<optimized out>, f=<optimized out>, str_char=<optimized out>,
     y=<optimized out>, x=<optimized out>) at /home/el/Projects/gint/src/render-cg/topti.c:140
140        topti_render(x, y, str, topti_font, fg, bg, size);
(gdb) s
63        if(x >= dwindow.right || y >= dwindow.bottom) return;
(gdb) s
64        if(y + height <= dwindow.top) return;

Je vous passe quelques étapes parce qu'il y a encore pas mal de lignes avant qu'on atteigne le crash ; je continue sans m'arrêter avec continue.

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x8c202ecc in dtext_utf8_next (str_pointer=0x8c1dff40) at /home/el/Projects/gint/src/render/topti.c:59
59        uint8_t lead = *str++;

Et là on retrouve le crash. Vous pouvez voir que cette fois il y a un message "Program received... Segmentation fault". Pour des raisons techniques ce message n'est pas affiché au tout premier arrêt quand vous lancez fxsdk gdb, mais vous pouvez connaître la raison de l'arrêt avec info program.

Dans tous les cas, on a bien compris d'où vient le bug maintenant, donc on peut arrêter le programme. On pourrait continue à ce stade, auquel cas GDB enverrait la segfault à l'add-in qui s'arrêterait tout seul (retour au menu), mais on peut aussi utiliser la commande kill (raccourci "k") qui est plus explicite et produit le même effet. Vous pouvez vous en servir pour quitter l'add-in à tout moment pendant une session de debuggage.

(gdb) k
Kill the program being debugged? (y or n) y
[Inferior 1 (Remote target) killed]
(gdb) %

Limitations

Les seules choses qui ont été testées sont les suivantes :

  • Lecture et écriture dans les registres et dans la mémoire ;
  • Breakpoints matériels et signaux usuels ;
  • Exécution pas-à-pas.

Les breakpoints logiciels ne sont pas supportés pour l'instant donc pour mettre un breakpoint sur une fonction en RAM il faut nécessairement utiliser la commande hbreak et non break. On ne supporte qu'un ou deux breakpoints selon les cas, et on ne le dit pas vraiment à GDB, donc si vous en mettez plus ils risquent de ne pas marcher sans raison (i.e. le programme passe sur un breakpoint mais il ne s'arrête pas pour communiquer avec le debugger).

Normalement il ne doit pas y avoir de cas où le programme freeze et vous n'avez pas le contrôle sur le debugger pour pouvoir le kill. Si ça se produit (et que c'est pas une boucle infinie dans votre code) faites-moi signe.

Voilà voilà, enjoy! o/
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Parisse Hors ligne Membre Points: 492 Défis: 0 Message

Citer : Posté le 10/04/2024 20:07 | #


Ca donne envie de faire passer KhiCAS du prizmsdk vers gint ... si Casio revient sur la fermeture de ses prochaines calcs.
Est-ce qu'on peut appeler une fonction/méthode sur la calc depuis la console de gdb? Par exemple, si j'ai une variable g de type giac::gen qui a une méthode dbgprint(), puis-je écrire p g.dbgprint()? (je n'ai pas réussi à faire marcher ce genre de choses en utilisant gdb sur l'émulateur casio avec la dll patchée pour le support gdb).
Potter360 Hors ligne Rédacteur Points: 1242 Défis: 2 Message

Citer : Posté le 11/04/2024 07:54 | #


Excellent ! C’est vraiment cool de voir ce genre d’avancées sur gint, et vraiment utile
Bravo !!

Petit détail : est ce que ça ne serait pas plus simple d’ajouter une macro du genre gdb_breakpoint() qui appelle elle-même le trapa ? Peut-être plus explicite
Globalement, coder. Mal, mais coder.
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

Citer : Posté le 11/04/2024 09:10 | #


Parisse a écrit :
Ca donne envie de faire passer KhiCAS du prizmsdk vers gint ... si Casio revient sur la fermeture de ses prochaines calcs.

On croise les doigts.

Est-ce qu'on peut appeler une fonction/méthode sur la calc depuis la console de gdb? Par exemple, si j'ai une variable g de type giac::gen qui a une méthode dbgprint(), puis-je écrire p g.dbgprint()? (je n'ai pas réussi à faire marcher ce genre de choses en utilisant gdb sur l'émulateur casio avec la dll patchée pour le support gdb).

Ah ça c'est une bonne question ! Je n'y avais pas pensé. On peut exécuter du code oui (genre appeler une fonction), je vais voir ce soir si on peut renvoyer du texte à GDB.

Potter360 a écrit :
Petit détail : est ce que ça ne serait pas plus simple d’ajouter une macro du genre gdb_breakpoint() qui appelle elle-même le trapa ? Peut-être plus explicite

Pour l'instant je l'ai pas fait parce que c'est pas la façon "propre" de faire ; en principe GDB devrait avoir la main avant que le programme se lance quand on veut ajouter des breakpoints. En attendant de voir si je peux faire marcher ça proprement je préfère laisser ce "hack" visible.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Parisse Hors ligne Membre Points: 492 Défis: 0 Message

Citer : Posté le 11/04/2024 10:02 | #


Lephenixnoir a écrit :

Est-ce qu'on peut appeler une fonction/méthode sur la calc depuis la console de gdb? Par exemple, si j'ai une variable g de type giac::gen qui a une méthode dbgprint(), puis-je écrire p g.dbgprint()? (je n'ai pas réussi à faire marcher ce genre de choses en utilisant gdb sur l'émulateur casio avec la dll patchée pour le support gdb).

Ah ça c'est une bonne question ! Je n'y avais pas pensé. On peut exécuter du code oui (genre appeler une fonction), je vais voir ce soir si on peut renvoyer du texte à GDB..

C'est très utile pour moi, car l'affichage par p d'une variable de type gen est peu infomative (sauf si c'est un petit entier), et j'ai une macro dans mon .gdbinit :
echo Defining v as print command for giac types\n
define v
print ($arg0).dbgprint()
end

qui me permet d'afficher un gen de manière user-friendly en tapant v g (par exemple a+b si g est un gen de type symbolique)
Ca peut intéresser n'importe quel projet qui a une structure avec une méthode dbgprint() pour l'afficher.
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

Citer : Posté le 11/04/2024 10:03 | #


Carrément, j'ai vraiment envie d'avoir cette possibilité maintenant. xD
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

Citer : Posté le 12/04/2024 09:08 | #


Update : ça progresse et ça va marcher je pense, j'arrive à rediriger stderr pour que ça affiche dans GDB. D'abord il faut demander à gint de rediriger soit stdout soit stderr soit les deux (ici juste stderr) :

gdb_start_on_exception();
gdb_redirect_streams(false, true);

Le second appel a pour effet que tout affichage dans stderr sera passé à la console GDB ensuite. Dans gintctl j'ai une fonction comme ceci :

void gintctl_gdb_dbgprint(void)
{
    fprintf(stderr, "debug=%d\n", 73);
}

Dans le log ci-dessous, je crée volontairement une erreur (avec le trapa #42) pour lancer GDB. Ensuite je fais mon appel, et le seul problème pour l'instant c'est que la calto ne s'arrête pas après l'appel (le breakpoint placé à la fin du call par GDB n'a pas dû marcher). Donc je quitte brutalement.

0x8c202c0e in gintctl_gint_gdb () at /home/el/Projects/gintctl/src/gint/gdb.c:95
95                __asm__("trapa #42");
(gdb) call gintctl_gdb_dbgprint()
debug=73
[Inferior 1 (Remote target) exited normally]
The program being debugged exited while in a function called from GDB.
Evaluation of the expression containing the function
(gintctl_gdb_dbgprint) will be abandoned.

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2312 Défis: 17 Message

Citer : Posté le 12/04/2024 12:01 | #


Désolé de pas trop être présent en ce moment, mais je suis avec attention les avancées du debug dans fxSDK/gint. Ca me fait ma détente de la journée de voir les trucs sympas qui avancent après mes journées de m__de du moment :D.

Bravo @Lephenixnoir et @Redoste, c'est vraiment un boulot fantastique que vous faites sur ce sujet qui va vraiment aider la communauté.



Ca va clairement révolutionner le game au niveau du développement car le debuf au printf() c'est bof au bout d'un moment !!! Ca offre des perspectives vraiment hyper intéressantes pour aller gratter dans les fonctions.
Je serai curieux de savoir si on sait "connecter" ça avec une IU (peut être directement dans VSCode d'ailleurs) afin de rendre le truc un peu plus convivial (j'avoue que GDB, je trouve un peu austère )

Encore une fois bravo à vous.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Parisse Hors ligne Membre Points: 492 Défis: 0 Message

Citer : Posté le 12/04/2024 12:35 | #


gdb tout seul c'est spartiate, mais gdb dans emacs je trouve ça génial!
Slyvtt Hors ligne Maître du Puzzle Points: 2312 Défis: 17 Message

Citer : Posté le 12/04/2024 13:59 | #


Merci Bernard, faudra que j'essaie, je n'ai jamais regardé emacs pour cet usage.
Quand j'étais plus jeune j'adorais DDD mais hélas ce frontend est tombé en désuétude faute de support actif. Je le trouvais vraiment top.

Je pensais à un truc, du coup on a une version des libs compilées avec -g pour pouvoir pousser le debug jusqu'aux fonctions de gint/fxlibc ou c'est pas la peine ?
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

Citer : Posté le 12/04/2024 14:02 | #


gint est compilé avec -g oui, sinon tu pourrais pas voir dtext_utf8_next() dans l'exemple.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2312 Défis: 17 Message

Citer : Posté le 12/04/2024 14:48 | #


Bein oui, j'suis con, effectivement

Bien vu
Un peu cérébralement surchargé le Sly en ce moment ...
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Parisse Hors ligne Membre Points: 492 Défis: 0 Message

Citer : Posté le 12/04/2024 18:21 | #


Les infos de débug ne prennent pas de place dans l'exécutable Casio, donc il n'y a pas trop de raison de ne pas les garder.
Sinon gdb dans emacs, ça reste très ligne de commande, pas du tout comme le debugger de visual studio (ddd si je me souviens bien c'était graphique mais on avait accès facilement à la console gdb). L'intérêt principal pour moi c'est de pouvoir relancer le prog avec les mêmes arguments juste en tapant r, faire du ligne à ligne avec n ou s, changer de frame avec f (et bt), taper des v noms de variables (ça c'est très difficile à réaliser dans les debugger graphiques sans console) et pouvoir modifier le source directement depuis la fenêtre de debug.
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

Citer : Posté le 12/04/2024 18:49 | #


Pour info pour l'instant run y'a pas et modifier les sources je doute que ça marche, mais sinon n/s/f/bt ça marche.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2312 Défis: 17 Message

Citer : Posté le 12/04/2024 19:37 | #


Je suis en train de faire le tuto, ça marche trop bien !!!
Franchement c'est la classe, bravo !!
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Parisse Hors ligne Membre Points: 492 Défis: 0 Message

Citer : Posté le 12/04/2024 20:25 | #


Lephenixnoir a écrit :
Pour info pour l'instant run y'a pas et modifier les sources je doute que ça marche, mais sinon n/s/f/bt ça marche.

ah oui, je parlais du code natif de Xcas sur PC, ou du simulateur Numworks.
Pour la Casio, vu que ça nécessite un changement de SDK pour KhiCAS, j'attends de voir si Casio remet les addins et de l'espace de stockage.
Lephenixnoir En ligne Administrateur Points: 24255 Défis: 170 Message

Citer : Posté le 13/04/2024 09:23 | #


Parisse a écrit :
Pour la Casio, vu que ça nécessite un changement de SDK pour KhiCAS, j'attends de voir si Casio remet les addins et de l'espace de stockage.

Naturellement... sans compter que gint prend un peu de place aussi ce qui reposerait la question de la taille. Tu m'as juste rappelé que je parlais jamais de run qui est une commande classique donc je voulais préciser.

Sinon j'ai progressé sur la question des appels type dbgprint(). Pour les add-ins classiques (chargés en ROM) ça marchait déjà très bien. Pour les add-ins en RAM (Add-in Push) j'avais le problème décrit dans ce message parce que GDB voulait mettre un breakpoint logiciel, i.e. en modifiant le code, et on ne le supportait pas encore. Finalement il suffit de purger les deux caches quand on modifie le code et de réajuster PC après un breakpoint logiciel pour que GDB comprenne bien où on est.

Du coup, ça marche !

0x8c202c0e in gintctl_gint_gdb () at /home/el/Projects/gintctl/src/gint/gdb.c:95
95                __asm__("trapa #42");
(gdb) call gintctl_gdb_dbgprint()
debug=73
(gdb)

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Parisse Hors ligne Membre Points: 492 Défis: 0 Message

Citer : Posté le 13/04/2024 13:53 | #


Lephenixnoir a écrit :
Parisse a écrit :
Pour la Casio, vu que ça nécessite un changement de SDK pour KhiCAS, j'attends de voir si Casio remet les addins et de l'espace de stockage.

Naturellement... sans compter que gint prend un peu de place aussi ce qui reposerait la question de la taille.

Oui, ça ne passerait pas avec l'addin version courte de KhiCAS où il ne reste que quelques centaines d'octets libres. Par contre avec la version longue en addin+overlay, ça ne causerait pas de soucis, sous réserve que l'espace de stockage revienne à une valeur décente sur la math+/fxcg100.


Du coup, ça marche !

Bravo! Je garde ça en mémoire, pour l'instant béni où Casio aura enfin la révélation et remettra les addins et au moins 8Mo d'espace en flash.
Précédente 1, 2, 3 ··· 10 ··· 20 ··· 30 ··· 40 ··· 50 ··· 60 ··· 70, 71, 72, 73, 74

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 46 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