Et donc il estime qu'il est plus probable que le programmeur ait pris la peine de tester qu'un pointeur n'est pas NULL par erreur, plutôt que l'inverse, à savoir que le pointeur ait été déréférencé par erreur avant d'être testé non NULL ?
Je suis curieux de voir un exemple de telle utilisation volontaire...
Je dirais que dans 99% des cas, un tel code est très très douteux, le choix fait par gcc me paraît foireux...
En fait, le problème de base c'est que le code est buggé. Ce n'est pas vraiment un problème d'optimisation.
Déréférencer un pointeur NULL est une "undefined behavior", autrement dit l'implémentation est libre de faire _ce qu'elle veut_. Crasher, générer du code foireux, imprimer "42", etc.
Définition de "undefined behavior" :
behavior, upon use of a nonportable or erroneous program construct, of erroneous data, or of indeterminately valued objects, for which this International Standard imposes no requirements
NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
En l'occurrence, gcc supprime le test puisqu'il "suppose" que le programme aura crashé.
C'est un choix comme un autre, par contre je ne comprends pas pourquoi il ne lève pas un warning à la compilation, s'il _pense_ que le code va crasher...
Je suis pas en forme moi...
Dans mon exemple, sk est un pointeur, situé à l'adresse offsetof(tun, sk).
Donc, si sk->sk_destruct(sk) est appelé, le code appelé est situé à l'adresse pointée par sk, plus offsetof(sk, sk_destruct).
Mais ce n'est qu'un exemple...
Ce qui est marrant c'est que c'est optimisation de gcc qui permet au code d'être exécuté, au lieu de faire un oops.
En regardant l'extrait de code, j'ai l'impression que ce n'est pas l'affectation qui provoque l'exploit.
C'est l'optimisation de gcc qui supprime la vérification if (!tun) return POLLERR;
Du coup, derrière, au lieu de sortir de la fonction, on se retrouve avec sk qui pointe vers l'adresse 0 + offsetof(tun, sk).
Et là, c'est le drame. Par exemple, si le socket et supprimé, c'est sk->sk_destruct(sk) qui est appelé, et donc si tu as mis la fonction qui va bien à l'adresse 0 + offsetof(tun, sk) + offsetof(sk, sk_destruct), tu deviens calife à la place du calife...
Ce mot n'apparaît pas dans le dictionnaire de l'Académie française.
De même pour "les fondamentaux de l'enseignement" : fondamental est un adjectif, pas un nom.
Ce n'est pas parce que 1000 personnes pensent la même connerie que ce n'est pas une connerie...
À part le démarrage, KDE est tout à fait utilisable sur de petites configurations (d'ailleurs j'ai fait mes screenshots avec un mini-ordinateur à base d'Atom, avec 1Gio de RAM et une carte Intel intégrée, et ça roule :) ).
Je me fais très vieux...
- "Mais madame, 4Go de RAM pour un grille-pain, c'est le minimum, il calcule le temps de cuisson et la puissance tout seul !"
Pour les outils différents je peu pas faire autrement.
Rien de t'empêche de faire un programme en C de 10 lignes pour copier un fichier, et de le compiler sous Linux et sous Windows. Au moins, tu sauras ce que fait ton programme.
Pour les testes concurrent j'ai mit 4 programme essayant de faire un lecture parallèle du disk brute. dd if=/dev/sda of=/dev/null pour linux
Ca alors, d'un essai à l'autre, la vitesse a été multipliée par 10...
Bien sûr, on voit tout de suite que le buffer cache a été utilisé pour le deuxième essai, d'où la différence énorme. Tout cela pour dire que j'ai de gros doutes quant à la pertinence de tes tests...
Les performances dépendent de plein de facteurs, l'ordonnanceur d'E/S, le readahead, le FS, l'utlisation du cache...
Il faut savoir que 90% des benchmarks que tu peux trouver sur Internet sont totalement inutiles : il ne faut pas se leurrer, c'est plus complexe qu'il n'y paraît, certaines grandes boîtes emploient des gars dont c'est la spécialité.
Je n'ai rien contre ta curiosité, au contraire, mais il faut bien se renseigner avant de crier au loup, et de vouloir contacter les développeurs du noyau ;-)
J'ai vu que tu développais un équivalent de super-copier sous Linux, ce ne serait pas à cause d'un écart de performances sous Windows et sous Linux que tu te poserais des questions ;-) ?
Si tel est le cas, je te conseille de regarder ton code avant d'aller poster sur lkml, notamment quand je vois ceci :-)
Hypotése: L'ordonnanceur sous linux ne preampt pas correctement la tache en la mettant sur pause le temps d'avoir les données hdd, mais fait tourner le cpu en boucle.
Il n'y a pas qu'en anglais que tu as du mal...
En ce qui concerne ton problème, tu es en train de dire que tu procèdes à des benchmarks en utilisant des outils différents (et que visiblement tu ne maîtrises pas), sur des configurations différentes, et que tu obtiens des résultats différents ?
Très intéressant, je suis certain que ton analyse va passionner les développeurs du noyau...
Sinon, est-ce que tu écris les paquets sur le disque dès qu'il arrivent ? Essaie de grouper les écritures en utilisant un buffer ou en procédant de façon périodique ou mieux, utilise fwrite au lieu de write.
Si j'écris sur le disque, à priori j'ai envie que ça soit écrit physiquement sur le disque.
En fait non.
Quand tu écris sur le disque, la seule chose qui t'importe, c'est de pouvoir lire ce que tu as écrit par la suite. Alors au lieu de forcer l'écriture sur disque, puis la lecture depuis le disque, autant garder le fichier en cache (en mémoire), comme ça tu te passes complètement d'accès disques.
En venir à renoncer à toute liberté d'expression, de pensée, de croyance en l'échange d'une illusion de sécurité : visiblement, le gouvernement fait bien son travail en France aussi...
Le problème ce n'est pas ton application qui ne reçoit pas les paquets lorsqu'elle écrit sur le disque : le problème c'est que lorsque tu écris, tu traites les données moins vite, le buffer de ton socket en réception se remplit, et lorsqu'il est plein, les nouveaux paquets reçus sont droppés (en quel langage est implémentée ton appli, tu as des mécanismes de synchronisation?).
Tu peux vérifier en faisant un netstat pendant que tu reçois des paquets, tu dois voir la recv-q de ton socket augmenter.
Tu peux essayer d'augmenter la taille maximum du buffer en faisant : sysctl -w net.core.rmem_max=8388608 par exemple.
De plus, des IRQ ok, mais lorsqu'il accède directement à la mémoire, il ne devrait pas avoir d'interruption particulière, si ? (d'où le test avec -cache 9000 ;))
Bah, il y a quand même les interruptions de la carte, non :-)
Il faudrait regarder l'évolution des stats de /proc/interrupts lorsque tu tourne sur un core qui pose problème et sur un qui fonctionne.
Aussi, tu pourrais essayer de désactiver MSI...
[^] # Re: Je ne comprends pas
Posté par neologix . En réponse à la dépêche Exploit local dans le noyau Linux 2.6.30. Évalué à 1.
Je suis curieux de voir un exemple de telle utilisation volontaire...
Je dirais que dans 99% des cas, un tel code est très très douteux, le choix fait par gcc me paraît foireux...
[^] # Re: Je ne comprends pas
Posté par neologix . En réponse à la dépêche Exploit local dans le noyau Linux 2.6.30. Évalué à 2.
Déréférencer un pointeur NULL est une "undefined behavior", autrement dit l'implémentation est libre de faire _ce qu'elle veut_. Crasher, générer du code foireux, imprimer "42", etc.
Définition de "undefined behavior" :
behavior, upon use of a nonportable or erroneous program construct, of erroneous data, or of indeterminately valued objects, for which this International Standard imposes no requirements
NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
En l'occurrence, gcc supprime le test puisqu'il "suppose" que le programme aura crashé.
C'est un choix comme un autre, par contre je ne comprends pas pourquoi il ne lève pas un warning à la compilation, s'il _pense_ que le code va crasher...
[^] # Re: Il me manque une piece du puzzle
Posté par neologix . En réponse à la dépêche Exploit local dans le noyau Linux 2.6.30. Évalué à 6.
Dans mon exemple, sk est un pointeur, situé à l'adresse
offsetof(tun, sk)
.Donc, si
sk->sk_destruct(sk)
est appelé, le code appelé est situé à l'adresse pointée par sk, plus offsetof(sk, sk_destruct).Mais ce n'est qu'un exemple...
Ce qui est marrant c'est que c'est optimisation de gcc qui permet au code d'être exécuté, au lieu de faire un oops.
[^] # Re: Il me manque une piece du puzzle
Posté par neologix . En réponse à la dépêche Exploit local dans le noyau Linux 2.6.30. Évalué à 7.
C'est l'optimisation de gcc qui supprime la vérification
if (!tun) return POLLERR;
Du coup, derrière, au lieu de sortir de la fonction, on se retrouve avec sk qui pointe vers l'adresse
0 + offsetof(tun, sk)
.Et là, c'est le drame. Par exemple, si le socket et supprimé, c'est
sk->sk_destruct(sk)
qui est appelé, et donc si tu as mis la fonction qui va bien à l'adresse0 + offsetof(tun, sk) + offsetof(sk, sk_destruct)
, tu deviens calife à la place du calife...[^] # Re: Sus à l'anglois !
Posté par neologix . En réponse à la dépêche Exploit local dans le noyau Linux 2.6.30. Évalué à 4.
De même pour "les fondamentaux de l'enseignement" : fondamental est un adjectif, pas un nom.
Ce n'est pas parce que 1000 personnes pensent la même connerie que ce n'est pas une connerie...
[^] # Re: Simplification de format {}
Posté par neologix . En réponse à la dépêche Python arrive en version 3.1. Évalué à 5.
>>> int(1).__add__(int(2))
3
C'est pas beau ça ?
[^] # Re: Simplification de format {}
Posté par neologix . En réponse à la dépêche Python arrive en version 3.1. Évalué à 4.
>>> prenom='toto'
>>> nom='tata'
>>> print("prenom: %(prenom)s nom: %(nom)s" % locals())
prenom: toto nom: tata
[^] # Re: Merci!
Posté par neologix . En réponse au message Constat improbable!. Évalué à 4.
net.ipv4.tcp_window_scaling=0
# audit
Posté par neologix . En réponse au message Accès SSH, récupérer ip, nom de la personne. Évalué à 4.
http://librenix.com/?inode=10248
http://www.cyberciti.biz/tips/linux-audit-files-to-see-who-m(...)
# En français...
Posté par neologix . En réponse au journal En vrac : Python 3.1, Netbeans 6.7. Évalué à 5.
brièveté, concision
De rien.
# un routeur moisi...
Posté par neologix . En réponse au message Constat improbable!. Évalué à 9.
Essaie avec
sysctl -w net.ipv4.tcp_window_scaling=0
Sinon, comme suggéré ci-dessus, un tcpdump te donnera vite une piste...
[^] # Re: Un lien pas mal
Posté par neologix . En réponse au message Recherche documentation FS. Évalué à 3.
http://lwn.net/Articles/322823/
http://lwn.net/Articles/291826/
Voir http://lwn.net/Kernel/Index/
# Un lien pas mal
Posté par neologix . En réponse au message Recherche documentation FS. Évalué à 3.
Sinon, tu as le classique "Understanding the Linux Kernel".
# SNMP
Posté par neologix . En réponse au message Surveiller interfaces depuis la console. Évalué à 2.
[^] # Re: Carte Graphique
Posté par neologix . En réponse au journal KDE 4.3, ça promet pour juillet !. Évalué à 10.
Je me fais très vieux...
- "Mais madame, 4Go de RAM pour un grille-pain, c'est le minimum, il calcule le temps de cuisson et la puissance tout seul !"
[^] # Re: ...
Posté par neologix . En réponse au message Bug dans les accès concurrent du disk. Évalué à 6.
Rien de t'empêche de faire un programme en C de 10 lignes pour copier un fichier, et de le compiler sous Linux et sous Windows. Au moins, tu sauras ce que fait ton programme.
Pour les testes concurrent j'ai mit 4 programme essayant de faire un lecture parallèle du disk brute. dd if=/dev/sda of=/dev/null pour linux
root@neobox:/home/cf# free -m
total used free shared buffers cached
Mem: 502 383 119 0 122 71
-/+ buffers/cache: 188 313
Swap: 486 0 486
root@neobox:/home/cf# time dd if=/dev/hda2 of=/dev/null count=100K
102400+0 enregistrements lus
102400+0 enregistrements écrits
52428800 bytes (52 MB) copied, 2,61817 s, 20,0 MB/s
real 0m2.622s
user 0m0.069s
sys 0m0.256s
root@neobox:/home/cf# free -m
total used free shared buffers cached
Mem: 502 433 69 0 173 71
-/+ buffers/cache: 189 313
Swap: 486 0 486
root@neobox:/home/cf# time dd if=/dev/hda2 of=/dev/null count=100K
102400+0 enregistrements lus
102400+0 enregistrements écrits
52428800 bytes (52 MB) copied, 0,262924 s, 199 MB/s
real 0m0.267s
user 0m0.057s
sys 0m0.206s
Ca alors, d'un essai à l'autre, la vitesse a été multipliée par 10...
Bien sûr, on voit tout de suite que le buffer cache a été utilisé pour le deuxième essai, d'où la différence énorme. Tout cela pour dire que j'ai de gros doutes quant à la pertinence de tes tests...
Les performances dépendent de plein de facteurs, l'ordonnanceur d'E/S, le readahead, le FS, l'utlisation du cache...
Il faut savoir que 90% des benchmarks que tu peux trouver sur Internet sont totalement inutiles : il ne faut pas se leurrer, c'est plus complexe qu'il n'y paraît, certaines grandes boîtes emploient des gars dont c'est la spécialité.
Je n'ai rien contre ta curiosité, au contraire, mais il faut bien se renseigner avant de crier au loup, et de vouloir contacter les développeurs du noyau ;-)
J'ai vu que tu développais un équivalent de super-copier sous Linux, ce ne serait pas à cause d'un écart de performances sous Windows et sous Linux que tu te poserais des questions ;-) ?
Si tel est le cas, je te conseille de regarder ton code avant d'aller poster sur lkml, notamment quand je vois ceci :-)
Hypotése: L'ordonnanceur sous linux ne preampt pas correctement la tache en la mettant sur pause le temps d'avoir les données hdd, mais fait tourner le cpu en boucle.
# ...
Posté par neologix . En réponse au message Bug dans les accès concurrent du disk. Évalué à 8.
En ce qui concerne ton problème, tu es en train de dire que tu procèdes à des benchmarks en utilisant des outils différents (et que visiblement tu ne maîtrises pas), sur des configurations différentes, et que tu obtiens des résultats différents ?
Très intéressant, je suis certain que ton analyse va passionner les développeurs du noyau...
[^] # Re: pistes
Posté par neologix . En réponse au message comment investiguer des "packet receive errors" en UDP ?. Évalué à 1.
Sinon, est-ce que tu écris les paquets sur le disque dès qu'il arrivent ? Essaie de grouper les écritures en utilisant un buffer ou en procédant de façon périodique ou mieux, utilise fwrite au lieu de write.
[^] # Re: pistes
Posté par neologix . En réponse au message comment investiguer des "packet receive errors" en UDP ?. Évalué à 1.
/sbin/ifconfig et cat /proc/net/snmp, pour avoir une idée de la cause des pertes de paquets.
[^] # Re: Forme canonique d'écriture de fichier
Posté par neologix . En réponse à la dépêche Le noyau Linux 2.6.30 est disponible. Évalué à 1.
En fait non.
Quand tu écris sur le disque, la seule chose qui t'importe, c'est de pouvoir lire ce que tu as écrit par la suite. Alors au lieu de forcer l'écriture sur disque, puis la lecture depuis le disque, autant garder le fichier en cache (en mémoire), comme ça tu te passes complètement d'accès disques.
[^] # Re: Logiciel antiporno
Posté par neologix . En réponse au journal Hadopi en Chine. Évalué à 2.
[^] # Re: Logiciel antiporno
Posté par neologix . En réponse au journal Hadopi en Chine. Évalué à 7.
[^] # Re: pistes
Posté par neologix . En réponse au message comment investiguer des "packet receive errors" en UDP ?. Évalué à 4.
Tu peux vérifier en faisant un netstat pendant que tu reçois des paquets, tu dois voir la recv-q de ton socket augmenter.
Tu peux essayer d'augmenter la taille maximum du buffer en faisant :
sysctl -w net.core.rmem_max=8388608
par exemple.# pistes
Posté par neologix . En réponse au message comment investiguer des "packet receive errors" en UDP ?. Évalué à 2.
/sbin/ifconfig
cat /proc/net/snmp
Causes possibles, :
- buffer du socket plein (plus probable, modifiable avec sysctl)
- rx_ring de la carte pleine
[^] # Re: IRQ
Posté par neologix . En réponse au message 2.6.29-2 + CPU0 + mplayer = pas bonne idée ?. Évalué à 3.
Bah, il y a quand même les interruptions de la carte, non :-)
Il faudrait regarder l'évolution des stats de /proc/interrupts lorsque tu tourne sur un core qui pose problème et sur un qui fonctionne.
Aussi, tu pourrais essayer de désactiver MSI...