Obligement - L'Amiga au maximum

Jeudi 05 juin 2025 - 15:17  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : C - Correction du bogue de la fonction drand48() de Lattice C
(Article écrit par Frédéric Mazué et extrait d'Amiga News Tech - mai 1991)


L'autre jour, poussé par une impulsion aussi soudaine qu'irrésistible, je décide de me promener incognito sur le serveur SGT FLAM. Et là qu'y vois-je ? La fonction drand48() du Lattice 5.04 serait déboguée ?

Secoué par ma compassion légendaire, mon sang ne fait qu'un tour, j'enfile ma rutilante combinaison de pourfendeur d'ignobles bogues gluants, m'arme de ma bombe gourouticide à la citronnelle fermentée et de mon laser à bouchon pour voler chevaleresquement à votre secours en poussant un cri des plus terrifiques : destroy !

Situons le problème

Avec ce petit programme appelé drand.c, voyons ce qui ce passe :

C

Effectivement, ce programme renvoie un gourou. Mais ne nous affolons pas car si ce bogue la fiche mal, c'est vrai, l'environnement du Lattice permet une correction rapide.

Il s'agit d'un gourou n°4, qui correspond, pour le 68000, à une instruction illégale. Pratiquement, ce type de gourou se rencontre principalement lors d'un mauvais traitement de la pile qui fait que le programme "saute" n'importe où. Le problème de l'instruction illégale apparaissant généralement lors d'un assemblage, mais pas lors d'un essai.

Identification du bogue

Compilons et relions notre petit programme comme ceci :

lc -d3 -Lma drand.c

...afin de pouvoir le passer au débogueur, qui soit dit en passant, fonctionne très bien, lui :

cpr drand

Une fois là, appuyons sur la touche "Entrée" jusqu'à arriver à la ligne "x=drand480;". Il faut maintenant continuer en pas à pas avec les touches Amiga-T mais après être passé en mode assembleur. Le débogueur du Lattice a l'excellente idée d'afficher dans la fenêtre de dialogue le nom de chaque routine dans laquelle il entre. Il nous suffit de continuer ainsi jusqu'au plantage en ayant seulement soin de repérer le nom de la routine qui plante.

Comme vous le verrez, ce nom est le très poétique et évocateur "_CXV25". Ne vous y trompez pas, le plantage est à "_CXV35" mais par l'entrée "_CXV25".

Localisation du bogue

C'est donc la routine "_CXV25" qui est boguée. Où est-elle ? Puisque le plantage se produit lors du calcul d'un nombre aléatoire, il s'agit d'un bogue de la bibliothèque mathématique lcm.lib. Qui dans cette routine utilise "_CXV25" ? Bonne question, je me remercie de l'avoir posée.

Pour le savoir, nous utiliserons un programme de l'environnement du Lattice, oml, comme ceci :

oml LIB:lcm.lib 1

Cette commande "liste" la bibliothèque, ce qui donne :

C

Le listing ci-dessus est bien entendu partiel. Si vous examinez ceci attentivement, vous verrez que "_CXV25" est appelée par le module cxv35. Et uniquement par lui, comme vous pourrez le vérifier en examinant le total si ça vous amuse.

Capture du bogue

Il faut tout d'abord faire impérativement une copie de votre Lattice original pour essayer la suite. Je décline toute responsabilité en cas de maladresse sur l'original. Non mais.

Pour gagner du temps lors des manipulations, faites d'abord :

copy LIB:lcm.lib ram:
cd ram:

Bien. Maintenant, nous allons extraire le module cxv35 par :

oml ram:lcm.lib x cxv35.o

Nous avons maintenant en ram: (c'est à ça que servait cd ram:), un fichier nommé "cxv35.o" qui est un fichier objet qu'il nous faut désassembler par :

omd >ram:cxv35.asm cxv35.o

Voici le contenu de cxv35.asm, résultat de cette opération (voir tableau).

Explication de la chose. Tout d'abord, ce module définit pour l'éditeur de liens les labels "_CXV25" et "_CXV35". C'est cela que signifie "external definitions". Où se situent ces labels ? Facile. La colonne de gauche nous donne un décalage depuis le début du module. On comprend alors que "_CXV25" est au décalage 0 et "_CXV35" est au décalage 8. De même, le BRA.W 0020 de la troisième ligne du programme (colonne de droite) ne saute pas à l'adresse 20 de l'ordinateur mais à ligne CMPI.L #00200000.D0 correspondant au décalage 20.

La colonne du milieu ne nous intéresse pas, c'est le code machine. Nous voyons également, troisième ligne en partant de la fin, que ce module utilise la fonction "_CXNRM5", ce qu'il ne faudra pas oublier plus tard.

C

Examinons d'un oeil de lynx ce listing. Lorsqu'on entre par "_CXV25" (décalage 0), les registres D4 et D1 sont initialisés puis on saute au décalage 20, suivent alors quelques instructions, l'appel de "_CXNRM5", ensuite on dépile et on sort.

J'ai dit on dépile ? Mais, tonnerre, on avait empilé quoi ? Eh bien on avait rien empilé du tout et voilà donc le bogue.

Extermination impitoyable du bogue

Il n'y a maintenant plus qu'à réécrire le module en tenant compte de tout ce que nous avons vu à propos des labels et des décalages, en ajoutant l'instruction d'empilage qui manque et en faisant très attention au fait que toutes les valeurs numériques du module désassemblé sont exprimées en hexadécimal et donc qu'il faudra, par exemple, remplacer un MOVE.W #8000,D4 par MOVE.W #$8000,D4 afin de ne pas générer nous-mêmes d'autres bogues (ça serait le comble, hein ?).

Voilà le listing, appelé cxv35.a écrit pour Asm du Lattice. J'ai choisi Asm pour des questions d'homogénéité avec le reste de l'article, mais n'importe quel macro-assembleur convient (Seka ne fait pas le poids).

C
C

Il reste à assembler ceci on ne peut plus simplement par :

asm cxv35

...et l'on obtient en ram: un nouvel objet "cvx35.o" qu'il faut maintenant insérer dans la bibliothèque, opération qui écrasera l'ancien module bogué. Ceci se fait par :

oml ram:lcm.lib r cxv35.o

Sauvegardons enfin notre travail :

copy ram:lcm.lib LIB:

Et nous aurons la joie de constater que le programme recompilé drand.c du début fonctionne cette fois parfaitement.

Du même coup, la fonction erand48 est elle aussi déboguée.

Petit complément à propos de erand48

Le programme drand.c a le défaut de sortir à chaque appel la même série de nombres aléatoires. Pour varier les résultats, il faut utiliser la fonction erand48. Cette fonction calcule les nombres à partir du contenu d'un tableau. Si vous modifiez le contenu du tableau, les résultats obtenus par erand48 seront également modifiés.

Mais attention, le tableau doit être ainsi défini comme "unsigned short seed[3]" et non pas "short seed[3]", comme dit dans la notice. En fait, cette coquille est corrigée dans l'errata de l'addendum. Mais je me suis permis de vous le signaler car cette information passe, semble-t-il, souvent inaperçue.

Voici un programme utilisant erand48 et initialisant le tableau sur le temps système.

C

Pour ceux qui désireraient exactement connaître comment sont tirés des nombres aléatoires, sachez que ceci est une autre histoire...


[Retour en haut] / [Retour aux articles]