• # criticité

    Posté par . En réponse au journal Genèse d'un journal. Évalué à 10. Dernière modification le 09 septembre 2012 à 12:55.

    Non, on ne peut pas compter sur le magicien "OOM Killer" de Linux. Le noyau a pu être compiler sans ça.

    Le OOM killer se tune par sysctl (overcommit_memory knobs) et /proc (oom_adj), pas à la compilation.
    Et ce n'est pas un tour de magie, mais plutôt un hack ignoble (et compter dessus est stupide et non portable).

    C'est exactement le cas. Votre programme de traitement de texte n'a pas assez d'espace pour le prochain caractère donc il plante sans possibilité de sauvegarder ?

    Tu sous-estime la complexité.
    OK, tu testes ton pointeur, tu vois qu'il est NULL.
    Mais pour faire les choses proprement, par exemple prévenir l'utilisateur, ou sauvegarder le fichier, et bien il faut de la mémoire.
    Bah oui, créer un popup, ça demande de la mémoire. fprintf() utilise malloc(), tout comme fwrite() (oui je connais setvbuf()), etc. Quand tu y penses, sans malloc(), il ne te reste plus grand chose de disponible.

    En fait c'est encore bien pire que ça, parce que sur OOM (je ne parle pas du cas où tu es limité par RLIMIT_DATA/RLIMIT_AS…), quasiment n'importe quel appel système peut foirer: fork() (vérifié sur OpenIndiana), write(), close()…

    Donc la morale, c'est que tu ne pourras probablement pas sauvegarder ton fichier, et que tu risques de le corrompre si tu essaies.

    C'est pour cela que dans les applications critiques, il faut utiliser des opérations atomiques, ou des transactions. Par exemple, ton traitement de texte bosse sur une copie du fichier, et ensuite fait un truc du style :

    fsync(fd);
    close(fd):
    rename("monfichier.tmp", "monfichier");
    fsync(<répertoire parent du fichier>);
    
    

    Au moins là tu es tranquille.
    Par ce que tu vois le cas d'OOM, mais ton process peut se faire tuer par un SIGKILL ou n'importe quel autre signal, et dans ce cas là tu ne pourras pas catcher.

    Mais ce genre de chose est complexe, et ce n'est probablement pas la peine de le faire sur un programme qui se content de te donner ta consommation en CPU/RAM/bande passante. Il n'a pas d'état, pas d'effets de bords, il peut crasher n'importe quand.
    Par contre, mettre un assert() est pas mal pour éviter une éventuelle faille de sécurité due au déréférencement d'un pointeur NULL.