76
Bruno Dufour Université de Montréal [email protected] Débogage IFT3912 – Développement et maintenance de logiciels Matériel adapté de : Andreas Zeller, “Why Programs Fail ”, 2nd ed, Morgan Kaufmann, 2009 Thursday, March 31, 2011

IFT3912 : Développement & maintenance de logiciels

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: IFT3912 : Développement & maintenance de logiciels

Bruno  DufourUniversité  de  Montré[email protected]

Débogage

IFT3912  –  Développement  et  maintenance  de  logiciels

Matériel  adapté  de  :  Andreas  Zeller,  “Why  Programs  Fail  ”,    2nd  ed,  Morgan  Kaufmann,  2009

Thursday, March 31, 2011

Page 2: IFT3912 : Développement & maintenance de logiciels

Quelques  staEsEques…

■ Les  bogues  coûtent  ~  60  milliards  $  annuellement■ Des  amélioraJons  pourraient  réduire  ce  coût  de  30%■ La  validaJon  (incluant  le  débogage)  peuvent  facilement  prendre  jusqu’à  50-­‐75%  du  temps  de  développement

■ Certaines  personnes  sont  trois  fois  plus  efficace  que  d’autres  pour  le  débogage

2

Thursday, March 31, 2011

Page 3: IFT3912 : Développement & maintenance de logiciels

Le  premier  bogue

3

9  septembre  1947

Thursday, March 31, 2011

Page 4: IFT3912 : Développement & maintenance de logiciels

Plus  de  bogues...

4

Thursday, March 31, 2011

Page 5: IFT3912 : Développement & maintenance de logiciels

DéfiniEons  (rappel)

§ Erreur  (error):  commise  par  un  développeur• Erreur  de  programmaEon• Erreur  de  logique

§ Faute  ou  défault  (fault,  defect):  état  interne  invalide  d’un  logiciel  après  l’acEvaEon  d’une  erreur

§ Défaillance  (failure):  manifestaEon  externe  d’une  faute• Observable  (ex:  le  programme  dévie  de  sa  spécificaEon)

5

Thursday, March 31, 2011

Page 6: IFT3912 : Développement & maintenance de logiciels

Erreurs,  Fautes  &  Défaillances  (rappel)

6

Erreur Faute Défaillance

ImpliqueImplique

peut  causer peut  causer

Thursday, March 31, 2011

Page 7: IFT3912 : Développement & maintenance de logiciels

✘✘

De  l’erreur  à  la  défaillance

■ Le  programmeur  commet  une  erreur  dans  le  code

■ Lorsqu’exécutée,  l’erreur  provoque  une  faute  (un  état  erroné  du  programme)

■ Ce^e  faute  ce  propage■ La  faute  cause  une  défaillance

■ Il  faut  retracer  la  chaîne  et  la  briser

7

✘ ✘

t

variables

Thursday, March 31, 2011

Page 8: IFT3912 : Développement & maintenance de logiciels

8

■ Les  erreurs  ne  causent  pas  toutes  des  défaillances!

■ Tester  ne  peut  que  démontrer  la  présence  d’erreurs  –  et  non  pas  leur  absence.(Dijkstra  1972)

Erreurs  et  tests

✘✘

✘ ✘

t

variables

Thursday, March 31, 2011

Page 9: IFT3912 : Développement & maintenance de logiciels

9

■ On  peut  remonter  à  une  faute  depuis  chaque  défaillance,  et  chaque  faute  est  due  à  une  erreur.

■ Le  débogage  consiste  à  faire  le  lien  entre  une  défaillance  et  une  erreur,  et  à  supprimer  l’erreur.

Débogage

✘✘

✘ ✘

t

variables

Thursday, March 31, 2011

Page 10: IFT3912 : Développement & maintenance de logiciels

■ L’état  iniJal  est  correct.■ Eventuellement,  l’état  est  erroné.■ C’est  dans  ce^e  région  qu’on  doit  chercher.

10

Recherche  dans  l’espace  et  le  temps

✔✔✔✔✔✔✔✔✔✔

t?

Thursday, March 31, 2011

Page 11: IFT3912 : Développement & maintenance de logiciels

■ La  faute  est  la  transiJon  de  correct  à  incorrect■ Comment  isoler  la  faute  ?

•Milliers  de  variables•Millions  d’instrucEons

11

Isoler  la  faute  

t

Thursday, March 31, 2011

Page 12: IFT3912 : Développement & maintenance de logiciels

L’état  d’un  programme

12

44  000  variables  et  42  000  liens  entre  elles  !

Thursday, March 31, 2011

Page 13: IFT3912 : Développement & maintenance de logiciels

Étapes  du  débogage

■ Enregistrer  le  bogue■ Reproduire  la  défaillance■ Automa:ser  et  simplifier  le  cas  de  test■ Trouver  les  origines  possibles  de  la  faute■ Isoler  l’origine  de  la  faute  (l’erreur)■ Corriger  l’erreur  et  tester  le  programme  à  nouveau

13

Thursday, March 31, 2011

Page 14: IFT3912 : Développement & maintenance de logiciels

1.  Enregistrer  le  bogue

■ Le  débogage  débute  lorsqu’un  problème  est  constaté■ Souvent,  un  uJlisateur  observe  et  rapporte  le  problème■ Quoi  inclure  ?

•Version  du  logiciel• Environnement•Démarche  à  suivre  pour  reproduire  le  bogue• Comportement  a`endu  et  observé•Un  court  résumé

■ Les  rapports  de  bogues  sont  souvent  enregistrés  et  gérés  par  un  logiciel  spécialisé

14

Thursday, March 31, 2011

Page 15: IFT3912 : Développement & maintenance de logiciels

2.  Reproduire  la  défaillance

■ La  première  tâche  du  débogage  (et  souvent  la  plus  difficile)

■ Pourquoi  reproduire  le  problème  ?• Pour  pouvoir  faire  de  nouvelles  observaEons  et  trouver  de  nouveaux  faits  à  propos  du  problème

• Pour  perme`re  de  déterminer  si  le  problème  est  réglé■ Il  faut  :

• recréer  la  démarche  qui  mène  au  problème• recréer  l’environnement  qui  dans  lequel  le  problème  est  survenu

15

Thursday, March 31, 2011

Page 16: IFT3912 : Développement & maintenance de logiciels

Reproduire  l’environnement

■ Débuter  avec  votre  environnement■ Tant  que  le  problème  n’est  pas  reproduit,  adapter  d’autres  circonstances  de  l’environnement  de  l’usager

■ L’itéraJon  se  termine• lorsque  le  problème  est  reproduit• lorsque  les  deux  environnements  sont  idenEques

■ Permet  par  la  même  occasion  d’apprendre  des  faits  au  sujet  des  circonstances  qui  causent  le  problème• Circonstance  =  un  aspect  de  l’environnement  ou  une  étape  de  la  démarche  qui  influence  le  problème

16

Thursday, March 31, 2011

Page 17: IFT3912 : Développement & maintenance de logiciels

Reproduire  l’exécuEon

■ En  plus  de  reproduire  l’environnement,  il  faut  reproduire  la  démarche  (l’exécuJon)  qui  cause  le  problème

■ L’exécuJon  est  déterminée  par  les  entrées  (généralement)

■ Reproduire  l’entrée  permet  donc  de  reproduire  l’exécuJon

17

Thursday, March 31, 2011

Page 18: IFT3912 : Développement & maintenance de logiciels

18

Les  entrées  d’un  programme

Program

Données

UJlisateur

CommunicaJon

Hasard Système  d’exploitaJon

Ordonnancement

Physique

OuJls  de  débogage

Thursday, March 31, 2011

Page 19: IFT3912 : Développement & maintenance de logiciels

19

“Heisenbug”

■ Le  code  suivant  ne  cause  pas  de  problème  en  mode  débogage

int  f()  {        int  i;        return  i;}

ExécuJon  normale:retourne  une  valeur  non-­‐définie

Dans  le  débogueurretourne  0

Thursday, March 31, 2011

Page 20: IFT3912 : Développement & maintenance de logiciels

3.  AutomaEser  et  simplifier

■ AutomaJser  :  écrire  un  test  automaJsé  (ex:  JUnit)  qui  reproduit  et  détecte  l’échec  à  l’exécuJon

■ Simplifier  :  pour  chaque  circonstance  du  problème,  vérifier  à  l’aide  d’expériences  si  elle  est  vraiment  nécessaire• Le  problème  dépend-­‐t’il  vraiment  des  milliers  de  lignes  d’entrées  ?

• La  défaillance  requiert-­‐elle  vraiment  cet  ordonnancement  précis  ?

•A-­‐t’on  besoin  de  ce`e  séquence  d’appels  ?■ Les  circonstances  non-­‐essenJelles  sont  éliminées

20

Thursday, March 31, 2011

Page 21: IFT3912 : Développement & maintenance de logiciels

Pourquoi  simplifier  ?

■ Pour  faciliter  la  communicaJon•Un  cas  simple  est  plus  facile  à  communiquer,  à  expliquer  et  à  comprendre

■ Pour  faciliter  le  débogage•Un  cas  simple  réduit  la  taille  de  l’état  à  considérer  et  produit  des  exécuEons  plus  courtes

■ Pour  idenJfier  les  doubles•Un  cas  simple  peut  remplacer  plusieurs  cas  plus  complexes  qui  illustrent  le  même  problème

21

Thursday, March 31, 2011

Page 22: IFT3912 : Développement & maintenance de logiciels

4.  Trouver  les  origines

■ Consiste  à  suivre  les  dépendances  dans  le  programme  pour  idenJfier  les  causes  possibles  d’une  faute

■ 2  types  de  dépendances• dépendances  de  données

• dépendances  de  contrôle

22

x  =  y  *  y  +  z  *  z;  //  x  dépend  de  y  et  z

if  (y  ==  z)  {        x  =  0;}  else  {        x  =  1;}

//  x  dépend  de  y  et  z

Thursday, March 31, 2011

Page 23: IFT3912 : Développement & maintenance de logiciels

23

Un  exemple

sort 9 8 7$

Sortie: 7 8 9

sort 11 14$

Sortie: 0 11

Thursday, March 31, 2011

Page 24: IFT3912 : Développement & maintenance de logiciels

24

main()int main(int argc, char *argv[]) { int *a; int i;

a = (int *)malloc((argc - 1) * sizeof(int)); for (i = 0; i < argc - 1; i++) a[i] = atoi(argv[i + 1]);

shell_sort(a, argc);

printf("Output: "); for (i = 0; i < argc - 1; i++) printf("%d ", a[i]); printf("\n");

free(a);

return 0;}

Thursday, March 31, 2011

Page 25: IFT3912 : Développement & maintenance de logiciels

variables

time!

!

!

!

!

25

Trouver  les  origines

■ La  valeur  0  affichée  est  la  valeur  de  a[0].  D’où  provient-­‐elle  ?

■ But  :  Suivre  ou  déduire  l’origine  des  valeurs

■ Sépare  les  valeurs  perJnentes  de  celles  qui  sont  inuJles

■ On  peut  suivre  a[0]  jusqu’à  shell_sort

Thursday, March 31, 2011

Page 26: IFT3912 : Développement & maintenance de logiciels

26

shell_sort()

static void shell_sort(int a[], int size) { int i, j; int h = 1; do { h = h * 3 + 1; } while (h <= size); do { h /= 3; for (i = h; i < size; i++) { int v = a[i]; for (j = i; j >= h && a[j - h] > v; j -= h) a[j] = a[j - h]; if (i != j) a[j] = v; } } while (h != 1);}

Thursday, March 31, 2011

Page 27: IFT3912 : Développement & maintenance de logiciels

27

Recherche  dans  le  temps

■ Dans  shell_sort,  l’état  doit  être  devenu  corrompu.

■ But  :  Observer  une  transiJon  de  correct  à  incorrect

✔✔✔✔✔✔✔✔✔✔

✘✘✘✘✘✘✘✘✘✘

t

Thursday, March 31, 2011

Page 28: IFT3912 : Développement & maintenance de logiciels

28

ObservaEon  spécifique

static void shell_sort(int a[], int size) {

int i, j; int h = 1; ...}

fprintf(stderr, “At shell_sort”); for (i = 0; i < size; i++) fprintf(stderr, “a[%d] = %d\n”, i, a[i]); fprintf(stderr, “size = %d\n”, size);

L’état  est  erroné  au  moment  de  l’appel  à  shell_sort!

sort 11 14$a[0] = 11a[1] = 14a[2] = 0size = 3Sortie: 0 11

Thursday, March 31, 2011

Page 29: IFT3912 : Développement & maintenance de logiciels

29

main()

int main(int argc, char *argv[]) { int *a; // Input array a = (int *)malloc((argc - 1) * sizeof(int)); for (int i = 0; i < argc - 1; i++) a[i] = atoi(argv[i + 1]);

// Sort array shell_sort(a, argc);

// Output array printf("Output: "); for (int i = 0; i < argc - 1; i++) printf("%d ", a[i]); printf("\n");

free(a); return 0;}

Devrait  être  argc  -­‐  1

Thursday, March 31, 2011

Page 30: IFT3912 : Développement & maintenance de logiciels

shell_sort(a, argc - 1);

int main(int argc, char *argv[]){ int *a; int i;

a = (int *)malloc((argc - 1) * sizeof(int)); for (i = 0; i < argc - 1; i++) a[i] = atoi(argv[i + 1]);

...}

30

Corriger  le  programme

shell_sort(a, argc); shell_sort(a, argc);sort 11 14$

Sortie: 11 14

Thursday, March 31, 2011

Page 31: IFT3912 : Développement & maintenance de logiciels

31

Débogage  scienJfique

Thursday, March 31, 2011

Page 32: IFT3912 : Développement & maintenance de logiciels

Erreur

■ Une  erreur  est  une  déviaJon  de  ce  qui  est  correct,  juste  ou  vrai.

■ Pour  prouver  que  quelque  chose  est  une  erreur,  il  faut  démontrer  la  déviaJon• Peut  être  difficile  pour  certains  programmes

32

Thursday, March 31, 2011

Page 33: IFT3912 : Développement & maintenance de logiciels

Causes  et  effets

■ Quelle  est  la  cause  de  la  défaillance  observée  ?• La  cause  d’un  événement  est  un  événement  précédent  sans  lequel  l’effet  ne  serait  pas  produit

■ Pour  prouver  la  causalité,  il  faut  montrer  que• l’effet  se  produit  lorsque  la  cause  se  produit• l’effet  ne  se  produit  pas  lorsque  la  cause  ne  se  produit  pas

■ En  général,  la  causalité  est  difficile  à  établir• Il  faut  pouvoir  répéter  les  événements  passés• En  informaEque,  les  programmes  peuvent  être  contrôlés  et  exécutés  à  volonté

33

Thursday, March 31, 2011

Page 34: IFT3912 : Développement & maintenance de logiciels

Vérifier  les  causes

34

a  =  compute_value();printf("a  =  %d\n",  a);

a  =  0

(a  ne  devrait  jamais  être  égal  à  zéro...)

Thursday, March 31, 2011

Page 35: IFT3912 : Développement & maintenance de logiciels

Vérifier  les  causes

35

a  =  compute_value();a  =  1;printf("a  =  %d\n",  a);

a  =  0

?

Thursday, March 31, 2011

Page 36: IFT3912 : Développement & maintenance de logiciels

Vérifier  les  causes

36

double  a;a  =  compute_value();a  =  1;printf("a  =  %d\n",  a);

a  =  0

Thursday, March 31, 2011

Page 37: IFT3912 : Développement & maintenance de logiciels

Vérifier  les  causes

37

double  a;a  =  compute_value();a  =  1;printf("a  =  %f\n",  a);

a  =  3.1415...

Nous  avons  isolé  le  format  (“%d”)  comme  cause  de  la  défaillance.

Thursday, March 31, 2011

Page 38: IFT3912 : Développement & maintenance de logiciels

“Voilà  le  bogue”

■ Certaines  personnes  sont  vraiment  douées  à  deviner  les  causes

■Malheureusement,  l’intuiJon  est  difficile  à  saisir  :• Requiert  des  connaissances  préalables•Ne  foncEonne  pas  d’une  manière  systémaEque  et  reproducEble

•Ne  peut  pas  être  enseignée

38

Thursday, March 31, 2011

Page 39: IFT3912 : Développement & maintenance de logiciels

La  méthode  scienEfique

■ La  méthode  scienJfique  décrit  comment  trouver  une  théorie  qui  explique  (et  prédit)  certains  aspects  de  notre  univers

■ Ce^e  méthode  est  appliquée  dans  toutes  les  branches  de  science  expérimentale.  

39

Thursday, March 31, 2011

Page 40: IFT3912 : Développement & maintenance de logiciels

Étapes  de  la  méthode  scienEfique

1.Observer  un  aspect  de  l’univers2.Formuler  une  hypothèse  qui  est  compaJble  avec  les  observaJons

3.UJliser  l’hypothèse  pour  faire  une  prédicJon4.Tester  la  prédicJon  par  des  expériences  ou  observaJons.5.Si  nécessaire,  modifier  l’hypothèse  si  nécessaire  et  retourner  à  l’étape  3.

40

Thursday, March 31, 2011

Page 41: IFT3912 : Développement & maintenance de logiciels

Une  théorie

■ Lorsque  l’hypothèse  explique  toutes  les  expériences  et  observaJons,  elle  devient  une  théorie

■ Une  théorie  est  une  hypothèse  qui• Explique  toutes  les  observaEons  antérieures• Prédit  les  observaEons  ultérieures

■ Dans  le  contexte  du  débogage,  une  théorie  est  un  diagnos(c

41

Thursday, March 31, 2011

Page 42: IFT3912 : Développement & maintenance de logiciels

MasterMind

■MasterMind  est  un  exemple  typique  d’applicaJon  de  la  méthode  scienJfique

■ Des  hypothèses  sont  formulées  jusqu’à  ce  que  le  secret  soit  révélé.

42

Thursday, March 31, 2011

Page 43: IFT3912 : Développement & maintenance de logiciels

43

Débogage  scienEfique

Hypothèse PrédicEon Expérience ObservaEons

DiagnosEc

Hypothèse  supportée  :  raffiner  l’hypothèse

Hypothèse  rejetée  :  formuler  une                        nouvelle  hypothèse

Thursday, March 31, 2011

Page 44: IFT3912 : Développement & maintenance de logiciels

44

Un  exemple

sort 9 8 7$

Sortie: 7 8 9

sort 11 14$

Sortie: 0 11

Déboguer  à  nouveau  en  uElisant  le  débogage  scienEfique

Thursday, March 31, 2011

Page 45: IFT3912 : Développement & maintenance de logiciels

45

Hypothèse  iniEale

Hypothèse

Prédic:on

Expérience

Observa:on

Conclusion

“sort 11 14” fonctionne

Sortie est “11 14”

Exécuter “sort” avec l’entrée spécifiée

Sortie est “0 11”

L’hypothèse est rejetée.

Thursday, March 31, 2011

Page 46: IFT3912 : Développement & maintenance de logiciels

46

int main(int argc, char *argv[]){ int *a; int i;

a = (int *)malloc((argc - 1) * sizeof(int)); for (i = 0; i < argc - 1; i++) a[i] = atoi(argv[i + 1]);

shell_sort(a, argc);

printf("Output: "); for (i = 0; i < argc - 1; i++) printf("%d ", a[i]); printf("\n");

free(a);

return 0;}

Est-­‐ce  que  a[0]  =  0  est  vrai?

Thursday, March 31, 2011

Page 47: IFT3912 : Développement & maintenance de logiciels

47

Hypothèse  1:  a[]

Hypothèse

Prédic:on

Expérience

Observa:on

Conclusion

L’exécution cause a[0] = 0.

À la ligne 37, a[0] = 0 est vrai.

Observer a[0] à la ligne 37.

a[0] = 0 est vrai, tel que prédit.

L’hypothesis est confirmée.

Thursday, March 31, 2011

Page 48: IFT3912 : Développement & maintenance de logiciels

48

static void shell_sort(int a[], int size){ int i, j; int h = 1; do { h = h * 3 + 1; } while (h <= size); do { h /= 3; for (i = h; i < size; i++) { int v = a[i]; for (j = i; j >= h && a[j - h] > v; j -= h) a[j] = a[j - h]; if (i != j) a[j] = v; } } while (h != 1);}

L’état  est-­‐il  correct  ici?

Thursday, March 31, 2011

Page 49: IFT3912 : Développement & maintenance de logiciels

49

Hypothèse  2:  shell_sort()

Hypothèse

Prédic:on

Expérience

Observa:on

Conclusion

La faute ne se produit pas avant shell_sort.

À la ligne 6, a[] = [11, 14]; size = 2

Observer a[] et sa taille à la ligne 6.

a[] = [11, 14, 0]; taille = 3.

L’hypothèse est rejetée.

Thursday, March 31, 2011

Page 50: IFT3912 : Développement & maintenance de logiciels

50

Hypothèse  3:  size

Hypothèse

Prédic:on

Expérience

Observa:on

Conclusion

size = 3 cause la défaillance

Changer la valeur de ‘size’ à 2 rend la sortie correcte.Changer la valeur de size dans un débogueur.

Tel que prédit.

L’hypothèse est confirmée.

Thursday, March 31, 2011

Page 51: IFT3912 : Développement & maintenance de logiciels

shell_sort(a, argc - 1);

int main(int argc, char *argv[]){ int *a; int i;

a = (int *)malloc((argc - 1) * sizeof(int)); for (i = 0; i < argc - 1; i++) a[i] = atoi(argv[i + 1]);

...}

51

Corriger  le  programme

shell_sort(a, argc); shell_sort(a, argc);sort 11 14$

Sortie: 11 14

Thursday, March 31, 2011

Page 52: IFT3912 : Développement & maintenance de logiciels

52

Hypothèse  4:  argc

Hypothèse

Prédic:on

Expérience

Observa:on

Conclusion

L’invocation de shell_sort avec size = argc cause la défaillance.Changer argc pour argc - 1 devrait faire réussir l’exécution.Changer argc pour argc - 1 et recompiler.

Tel que prédit.

L’hypothèse est confirmée.

Thursday, March 31, 2011

Page 53: IFT3912 : Développement & maintenance de logiciels

53

Le  diagnosEc

■ La  cause  est  “Invoquer  shell_sort()  avec  argc”■ Prouvé  par  deux  expériences  :

• Invoqué  avec  argc,  la  défaillance  se  produit• Invoqué  avec  argc  -­‐  1,  la  défaillance  ne  se  produit  pas

■ Effet  de  bord:  nous  avons  obtenu  une  soluJon■ NB:  nous  n’avons  pas  encore  obtenu  la  validité

•D’autres  erreurs  peuvent  être  présentes• La  soluEon  peut  engendrer  d’autres  problèmes

Thursday, March 31, 2011

Page 54: IFT3912 : Développement & maintenance de logiciels

54

Garder  la  trace...

■ Dans  le  jeu  Mastermind,  toutes  les  hypothèses  et  observaJons  sont  explicites.

■ Rend  le  jeu  beaucoup  plus  facile

Thursday, March 31, 2011

Page 55: IFT3912 : Développement & maintenance de logiciels

Débogage  implicite  vs  explicite

■ Débogage  implicite  :•Garde  tout  en  mémoire• Très  difficile,  comme  jouer  à  Mastermind  sans  le  plateau!

■ Débogage  explicite  :  uJlise  un  carnet  pour  toujours  connaître  :•Où  on  est  présentement• Par  où  on  est  passé•Où  l’on  va•Où  on  veut  aller

55

Thursday, March 31, 2011

Page 56: IFT3912 : Développement & maintenance de logiciels

Carnet  de  débogage

■ Quoi  noter  ?

56

Hypothèse

Prédic:on

Expérience

Observa:on

Conclusion

Thursday, March 31, 2011

Page 57: IFT3912 : Développement & maintenance de logiciels

Débogage  rapide

■ Pas  toutes  les  situaJons  demandes  des  carnets  et  des  procédures  complexes

■ SuggesJon  :•Déboguer  de  façon  rapide  et  ad  hoc  pendant  une  courte  période  (10  minutes)

•UEliser  le  débogage  scienEfique  si  le  problème  n’est  pas  encore  idenEfié

57

Thursday, March 31, 2011

Page 58: IFT3912 : Développement & maintenance de logiciels

Sources  d’hypothèses

58

0  exécuEon

1  exécuEon

n  exécuEons

n  exécuEons  contrôléesExpérimentaEon

InducEon

ObservaEon

DéducEon

UJlise

UJlise

UJlise

Thursday, March 31, 2011

Page 59: IFT3912 : Développement & maintenance de logiciels

OBSERVATIONSObservaJons

59

Thursday, March 31, 2011

Page 60: IFT3912 : Développement & maintenance de logiciels

Principes  d’observaEon

■ Ne  pas  interférer• Éviter  que  les  faits  observés  découlent  de  l’observaEon  elle-­‐même

■ Savoir  quoi  et  quand  observer• L’état  d’un  programme  est  trop  grand  pour  être  observé  à  chaque  instrucEon

• Trop  d’observaEons  peuvent  ralenEr  le  programme■ Procéder  de  façon  systémaJque

• Les  hypothèses  doivent  guider  les  observaEons  plutôt  que  de  procéder  à  tâtons

60

Thursday, March 31, 2011

Page 61: IFT3912 : Développement & maintenance de logiciels

JournalisaEon  (logging)

■ Idée  principale  :  insérer  des  instrucJons  de  sorJe  à  des  endroits  stratégiques  dans  le  code•Débogage  par  printf / println

■ Problèmes• Code  encombré• SorEe  encombrée• RalenEssement• Perte  de  données  possible  (buffering)

61

Thursday, March 31, 2011

Page 62: IFT3912 : Développement & maintenance de logiciels

Au-­‐delà  de  print

■ UJliser  un  format  standard• Permet  la  recherche  et  les  filtres

■ Rendre  l’enregistrement  opJonnel• Pour  améliorer  la  performance  lorsque  déployé

■ Perme^re  une  granularité  variable• Pour  la  performance• Pour  une  meilleure  compréhension

■ Favoriser  la  persistence• Pour  recommencer  si  un  problème  semblable  fait  surface

62

Thursday, March 31, 2011

Page 63: IFT3912 : Développement & maintenance de logiciels

Au-­‐delà  de  print

■ FoncJons  de  journalisaJon• FoncEons  spécifiques  qui  impriment  les  messages  sur  une  sorEe  spécifique

•UEliser  des  macros  pour  perme`re  d’acEver  ou  de  désacEver  les  messages  rapidement

• Exemple  :

63

#define LOG(msg) fprintf(stderr, “[DEBUG] %s at %s:%d\n”, \ msg, __FILE__, __LINE__)

Thursday, March 31, 2011

Page 64: IFT3912 : Développement & maintenance de logiciels

Au-­‐delà  de  print

■ Bibliothèques  spécialisées  :• LOG4J  populaire  pour  Java• Est  conçu  pour  la  persistence  et  la  flexibilité• Exemple  :

64

public class TestLogging { // Initialize a logger. final ULogger logger = LoggerFactory.getLogger(TestLogging.class);

public static void main(String args[]) { logger.debug("Start of main()"); logger.info ("A log message with level set to INFO"); logger.warn ("A log message with level set to WARN"); logger.error("A log message with level set to ERROR"); logger.fatal("A log message with level set to FATAL"); }}

Thursday, March 31, 2011

Page 65: IFT3912 : Développement & maintenance de logiciels

Débogueurs

■ Débogueur  :  un  ouJl  conçu  pour  s’a^acher  au  programme  durant  l’exécuJon  et  perme^re  d’effectuer  des  observaJons

■ Avantages  :• Permet  de  débuter  rapidement,  sans  modificaEon  du  code• Permet  l’observaEon  flexible  d’événements  arbitraires• Sessions  éphémères  (aucun  code  à  écrire)

65

Thursday, March 31, 2011

Page 66: IFT3912 : Développement & maintenance de logiciels

Débogueurs

■ FoncJonnalités  des  débogueurs  modernes  :• Exécuter  un  programme  et  l’arrêter  lorsqu’une  condiEon  est  remplie  (breakpoint  -­‐  emplacement,  watchpoint  -­‐  condiEon)

•Observe  l’état  du  programme  arrêté  (valeurs  des  variables,  pile  d’exécuEon,  etc.)

•Modifier  l’état  du  programme  arrêté•Débogage  post-­‐mortem  (core  dump)• Logging  (print,  display,  etc.)• “Fix  and  conEnue”  (permet  de  modifier  le  code  durant  l’exécuEon)

66

Thursday, March 31, 2011

Page 67: IFT3912 : Développement & maintenance de logiciels

Techniques  d’observaEons  avancées

■ IntégraJon  avec  l’interpréteur• Plus  interpréteurs  de  code  (ex:  python,  java)  perme`ent  à  des  ouEls  arbitraires  de  s’intégrer  dynamiquement  pour  observer  l’exécuEon

■ModificaJon  du  code• Il  est  possible  d’effectuer  des  observaEons  en  modifiant  directement  le  code  binaire  (code  machine  ou  interprété)

■ Débogage  à  rebours• Session  de  débogage  typique  :  suivant,  suivant,  suivant,  ...,  trop  loin!

• Certains  ouEls  perme`ent  de  remonter  dans  le  temps  (ex:  Whyline)  

67

Thursday, March 31, 2011

Page 68: IFT3912 : Développement & maintenance de logiciels

Techniques  d’observaEons  avancées

■ VisualisaJon• Plusieurs  ouEls  perme`ent  de  visualiser  une  ou  plusieurs  exécuEons• Données• Code  exécuté

68

Thursday, March 31, 2011

Page 69: IFT3912 : Développement & maintenance de logiciels

AutomaEser  les  observaEons

■ Il  est  difficile  pour  un  humain  de  vérifier  tout  l’état  d’un  programme

■ Pourquoi  ne  pas  demander  à  la  machine  de  vérifier  son  propre  état  ?

69

Thursday, March 31, 2011

Page 70: IFT3912 : Développement & maintenance de logiciels

AsserEons  de  base

70

if  (divisor  ==  0)  {        printf("Division  by  zero!");        abort();}

Thursday, March 31, 2011

Page 71: IFT3912 : Développement & maintenance de logiciels

AsserEons  spécialisées

71

assert  (divisor  !=  0);

Thursday, March 31, 2011

Page 72: IFT3912 : Développement & maintenance de logiciels

ImplémentaEon

72

void  assert  (int  x)  {      if  (!x)  {          printf("Assertion  failed!\n");        abort();    }}

$  my-­‐programAssertion  failed!Abort  (core  dumped)$  

Thursday, March 31, 2011

Page 73: IFT3912 : Développement & maintenance de logiciels

ImplémentaEon  avec  macro

73

#ifndef  NDEBUG#define  assert(ex)  \((ex)  ?  1  :  (cerr  <<  __FILE__  <<  ":"  <<  __LINE__  \                        <<  ":  assertion  ‘"  #ex  "’  failed\n",  \                                    abort(),  0))#else#define  assert(x)  ((void)  0)#endif

Thursday, March 31, 2011

Page 74: IFT3912 : Développement & maintenance de logiciels

Meilleurs  diagnosEcs

74

$  my-­‐programdivide.c:37:      assertion  ‘divisor  !=  0’  failedAbort  (core  dumped)$  

Thursday, March 31, 2011

Page 75: IFT3912 : Développement & maintenance de logiciels

AsserEons  et  Java

75

private  void  divide(int  divisor)  {        assert  divisor  !=  0;        assert  divisor  >  numerator  :  divisor;}

$  java  -­‐ea  Divide  0[...AssertionError...]$  

Passé  au  constructeur  pour  AsserEonError

Thursday, March 31, 2011

Page 76: IFT3912 : Développement & maintenance de logiciels

Quoi  observer  ?

76

■ PrécondiJons•ViolaEon  =  faute  avant  la  méthode

■ PostcondiJons•ViolaEon  =  faute  à  l’intérieur  de  la  méthode

■ Invariants•Devrait  toujours  être  vrai  (pré-­‐  et  post-­‐condiEon  à  la  fois)

Thursday, March 31, 2011