lseek/écriture soudain retourne -1 avec errno = 9 (Mauvais descripteur de fichier)
Mon application utilise lseek()
à chercher la position souhaitée à l'écriture de données.
Le fichier est ouvert avec succès à l'aide de open()
et ma demande a été en mesure d'utiliser lseek()
et write()
beaucoup de temps.
À un moment donné, pour certains utilisateurs et pas facilement reproduit, lseek()
retourne -1 avec errno
de 9. Le fichier n'est pas fermé avant cette et le descripteur de fichier (int) n'est pas réinitialisé.
Après cela, un nouveau fichier est créé; open()
est bien à nouveau et lseek()
et write()
fonctionne à nouveau.
À le rendre encore pire, c'utilisateur a essayé de la séquence complète de nouveau, et tout allait bien.
Donc ma question est, peut-OS fermer le descripteur de fichier pour moi pour une raison quelconque?
Quelle pourrait en être la cause? Un fichier d'indexation ou de l'analyseur de fichiers de la sorte?
Quelle est la meilleure façon de résoudre ce problème; est-ce le pseudo-code de la meilleure solution?
(ne jamais oublier le code de mise en page, vont créer des fonctions pour elle)
int fd=open(...);
if (fd>-1) {
long result = lseek(fd,....);
if (result == -1 && errno==9) {
close(fd..); //make sure we try to close nicely
fd=open(...);
result = lseek(fd,....);
}
}
Quelqu'un d'expérience avec quelque chose de similaire?
Résumé: fichier de rechercher et d'écrire les œuvres d'accord pour un fd et donne soudainement de retour errno=9 sans raison.
Vous connaissez le pseudo-code de droit?
Si lseek() échoue avec EBADF, vous pouvez être sûr qu'close() sur le même descripteur de fichier ne pourra pas non plus avec EBADF. Et puisque vous ne vérifiez pas vos ré-ouvrir ou de re-chercher les appels, quelque chose pourrait se produire.
Ger Teunis: Si ce que vous postez est pseudo-code, de le marquer comme tel, de sorte que les gens ne se plaignent (Tim) ou tout simplement vous dire "fonctionne pour moi". Éviter l'affichage de pseudo-si possible - le processus de trouver le plus petit morceau de code pour reproduire le problème, c'est une partie importante de l'art de débogage. Très souvent, le problème n'est pas là où vous pensez qu'il est, et le pseudo-code que vous publiez ne contient même pas le cœur du problème (dans ce cas, le fichier se trouvant sur un réseau de montage).
J'ai raté le pseudo-code de la partie. Je m'en excuse, ma faute, et encore de ma faute pour l'utilisation d'un langage sans une double vérification.
OriginalL'auteur Ger Teunis | 2010-03-30
Vous devez vous connecter pour publier un commentaire.
Je ne sais pas quel type de configuration que vous avez, mais le scénario suivant, pourrais-je penser à produire un tel effet (ou un similaire). Je n'ai pas testé pour vérifier, merci donc de prendre avec un grain de sel.
Si le fichier/dispositif d'ouverture mis en œuvre comme un serveur d'application (par exemple, NFS), pensez à ce qui pourrait se produire si le serveur d'application descend /redémarrage /redémarre. Le descripteur de fichier si à l'origine valable au client final pourrait ne plus carte valide d'un descripteur de fichier à la fin du serveur. Cela peut mener à une séquence d'événements dans laquelle le client devra obtenir EBADF.
Espère que cette aide.
OriginalL'auteur Sparky
Non, cela n'arrivera pas.
Non, le meilleur moyen est de trouver le bug et le corriger.
J'ai vu des fds se foiré plusieurs fois, résultant en EBADF dans certains des cas,
et en soufflant de façon spectaculaire dans d'autres, c'est l'été:
if(fd = foo[i].fd)
quand ils voulaientif(fd == foo[i].fd)
Si vous pouvez trouver un moyen de reproduire ce problème, exécutez le programme sous "strace", de sorte que vous pouvez voir ce qui se passe.
Après vérification, le fd ne change pas du tout et d'un seul thread est en train de faire de l'e / s de disque (tous les fichiers de manutention). J'ai peut croire que si je ne ferme pas la fd, fd reste le même je ne devrais pas le errno et -1 résultat? Il fait vraiment.
Alors que certaines particulier les OS, à l'aide de certains particulier de système de fichiers/e / s réseau qui pourrait avoir un certain angle cas de bug qui provoque cela se produise est entièrement possible, il ne ferait que des conjectures. un strace de tous les threads quand cela ne se produise serait très utile si
Après beaucoup plus de journalisation de débogage et ce n'était pas une erreur dans mon code. La fh de ne jamais changer et il ne faut pas les fermer. Les descripteurs de fichiers sont contrôlés à l'extérieur de mon domaine d'application du programme (ouvrir et écrire) il n'est donc pas un problème de mémoire.Vous êtes ici. Tous les descripteurs de fichiers où correct. Pas de fermeture de descripteurs de fichier. Il n'y avait pas un problème dans mon code juste osx marquage de la fh invalide. Reoping le fichier a également renvoyé le Même fd id. De drôles de trucs.
OriginalL'auteur nos
Le système d'exploitation ne doivent pas fermer les descripteurs de fichiers de manière aléatoire (je suis en supposant un système de type Unix). Si votre descripteur de fichier est fermé, alors il ya quelque chose de mal avec votre code, le plus probablement ailleurs (merci pour le langage C et Unix API, cela peut être vraiment n'importe où dans le code, et peut-être en raison, par exemple, un léger dépassement de tampon dans un morceau de code qui ressemble vraiment à être indépendants).
Votre pseudo-code est la pire des solutions, car il vous donnera l'impression d'avoir résolu le problème, alors que le bug subsistait.
Je vous suggère d'ajouter debug imprime (c'est à dire
printf()
appels), où vous pouvez ouvrir et fermer un fichier ou d'une douille. Aussi, essayez de Valgrind.(J'ai juste eu hier un sinistre hors-en-1 dépassement de la mémoire tampon, qui a endommagé l'octet le moins significatif d'un logement temporaire généré par le compilateur pour enregistrer un PROCESSEUR inscrire; l'effet indirect a été qu'une structure dans une autre fonction qui semblait être décalé de quelques octets. Il m'a fallu un certain temps pour comprendre ce qui se passait, y compris certains approfondie de lecture de code assembleur Mips).
Je ne pouvais pas être plus d'accord. Les Bugs doivent être fixes, ni masqués. @Ger, comment pouvez-vous être sûr que vous n'avez pas de pile ou de la corruption de segment de mémoire? Cela sonne comme une sinistre bug qui a besoin de fixation
Sûr que je suis d'accord, mieux trouver la cause. Mais à première vue, il semble que la cause en était hors de ma portée. Il semble toujours de cette façon parce qu'il n'y a aucun moyen de l'actuel fd est écrasé avec une autre valeur.
Certains ont fait une suggestion de ce qui pourrait arriver si l' (réseau) lecteur devient soudainement déconnecté. Devra se pencher sur cette.
OriginalL'auteur Thomas Pornin
Non, l'OS ne devrait pas fermer les descripteurs de fichiers comme ça, et d'autres applications (fichier scanners etc.) ne doit pas être mesure de le faire.
Ne pas contourner le problème, trouver la source. Si vous ne savez pas ce que la raison de votre problème, vous ne saurez jamais si votre solution de contournement en fait ne travail.
errno
mis à 0 avant l'appel? Est-fd vraiment valable au point de l'appel est fait? (Je sais que vous avez dit c'est bien, mais avez-vous vérifier?)puts( strerror( 9 ) );
sur votre plate-forme?Eh bien, allez vérifier vos hypothèses. Vous connaissez votre code mieux que moi. L'impression de la valeur de fd avant chaque appel serait mon prochain déménagement.
Bonne idée et une suggestion de ce qui se passe quand un (réseau) disque est déconnecté pour une raison quelconque.
OriginalL'auteur DevSolar