Mve: makescene se bloque lors de l'importation de fichiers PNG

Créé le 5 sept. 2017  ·  30Commentaires  ·  Source: simonfuhrmann/mve

J'ai un problème avec la commande makescene que je n'arrive pas à résoudre moi-même.

J'ai cloné et construit le référentiel selon les instructions du fichier Readme.md sous Ubuntu 16.04 64 bits. La compilation se compile sans erreur et toutes les applications sont là.

Cependant, si je lance la commande makescene avec les paramètres -i, il ne créera que le dossier de la scène, puis plantera avec le message "Ungültiger Maschinenbefehl (Speicherabzug geschrieben)" (je lance la version allemande d'Ubuntu)

J'ai ajouté des messages de sortie au code pour voir jusqu'où la commande est exécutée et apparemment, le crash se produit dans le fichier image_io.cc, dans la fonction load_png_file, autour des lignes 311-314, où les pointeurs sont configurés.

Je ne sais pas comment le réparer, cependant. Les valeurs de headers.height et headers.channels semblent logiques.

Tous les 30 commentaires

Un crash en image_io est relativement peu probable. Pouvez-vous essayer d'écrire un programme de test et de charger l'image manuellement ?

#include "mve/image_io.h"
int main() {
  mve::image::load_png_file("your path");
  return 0;
}

Y a-t-il autre chose de spécial dans l'image ? Est-ce un PNG 8 ou 16 bits ?

D'accord, j'ai compilé le programme de test et j'essaie de charger un PNG qui se trouve dans le même dossier que l'application de test. J'obtiens le même résultat, le programme plante avec "Ungültiger Maschinenbefehl (Speicherabzug geschrieben)".

Cependant, si je change l'appel de fonction en "load_tiff_file" et que je charge un fichier TIFF à la place, il semble bien fonctionner. Peut-être que la fonction load_png_file est spécifiquement cassée ?

Je ne sais pas si cela est utile, mais j'ai changé le code en load_png_file et utilisé strace pour obtenir les journaux système liés à cette application. Voici les dernières lignes de ce journal avant qu'il ne plante :

14:00:46.197536 ouvert("./frame_0001.png", O_RDONLY) = 3
14:00:46.197561 fstat(3, {st_mode=S_IFREG|0664, st_size=407653, ...}) = 0
14:00:46.197582 lire(3, "\211PNG\r\n\32\n\0\0\0\rIHDR\0\0\5\0\0\0\2\320\10\2\0 \0\0@\37J"..., 4096) = 4096
14:00:46.197651 mmap(NULL, 2768896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcadc163000
14:00:46.198666 --- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x40b69d} ---
14:00:46.337334 +++ tué par SIGILL (core dumped) +++

Accepteriez-vous de m'envoyer un lien vers cette image ?

Je suppose que l'image a juste une extension png mais n'est pas réellement un png ... J'ai vu des problèmes similaires où un fichier ".png" était en fait encodé en jpeg.

http://maxdid.it/gamejam/img/frame_0001.png

J'ai utilisé ffmpeg pour exporter les images d'une vidéo dans des fichiers image.

Je pensais que c'était peut-être aussi le mauvais format de fichier, mais j'ai utilisé la commande convert pour le convertir de png en tiff et inversement, sans effet.

Le fichier se charge bien ici.

open("frame_0001.png", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0640, st_size=691915, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5395d8a000
read(3, "\211PNG\r\n\32\n\0\0\0\rIHDR\0\0\5\0\0\0\2\320\10\2\0\0\0@\37J"..., 4096) = 4096
mmap(NULL, 2768896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5393b87000
read(3, "\7\0?)\363\207i\27\30x'\356\330\214Xg\7\260\334W\23G\371\323\31 \323\2S\273\353\\"..., 4096) = 4096
...

Selon votre strace , votre programme est tué par SIGILL (pas KILL). Je pense que cela signifie que votre processeur ou votre système d'exploitation tente d'exécuter une instruction non valide. Je ne sais pas quoi penser de cela, mais je pense que c'est votre système ou votre bibliothèque libpng qui est en quelque sorte foiré. Pouvez-vous essayer de réinstaller/mettre à jour libpng ?

J'ai donc désinstallé la version de libpng que j'ai installée via apt-get install et téléchargé directement le référentiel libpng, l'ai compilé et l'a installé.

Malheureusement, cela a le même effet. C'est peut-être vraiment mon processeur ? J'utilise actuellement un processeur AMD Phenom II X4 965, qui n'est pas le modèle le plus récent, je suppose. Pourtant, je ne pense pas avoir déjà eu de problèmes similaires auparavant.

Quoi qu'il en soit, puisque vous ne pouvez pas reproduire le problème, je suppose que je vais fermer le problème.

Je suis désolé d'apprendre que cela ne fonctionne toujours pas. Je ne pense pas vraiment que ce soit votre matériel... mais je suis à court d'idées. Peut-être existe-t-il des indicateurs de compilation pour désactiver certaines fonctionnalités d'accélération pour libpng ? À ce stade, je ne fais que deviner sans vraiment savoir ce qui cause le problème.

Je sais pourquoi makescene se bloque lors de l'importation de fichiers image après de nombreuses expériences. Ce n'est pas la raison de libjpeg ou libpng, la vraie raison est openMP. Vous pouvez corriger ce bogue avec ces codes dans makescene.cc :
Ligne 845
mve::ImageBase::Ptr image ;

pragma omp parallèle pour le calendrier ordonné (dynamique, 1)

for (std::size_t i = 0; i < dir.size(); ++i)

....
std ::string exif;

pragma omp critique

    image = load_any_image(afname, &exif);

...

Mais ce changement n'a pas beaucoup de sens. Vous stockez l'image dans la variable image qui est partagée par tous les threads, et bien que le chargement de l'image soit maintenant sérialisé, vous allez écraser l'image en raison des conditions de concurrence et utiliser les mauvaises données après le chargement de l'image. ..

Avez-vous essayé de mettre le #pragma omp critique avant le chargement de l'image ?

@timlgy , pouvez-vous nous en dire un peu plus sur votre système ? Quel CPU, système d'exploitation et compilateur utilisez-vous ?

Cela fonctionne pour moi sur Ubuntu 14.04.5 LTS, 16U32G et le compilateur est gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1 ~ 14.04.3) PS "données erronées", qu'est-ce que c'est? prebundle.sfm ?

selon cet article #pragma omp critique
La directive critique omp identifie une section de code qui doit être exécutée par un seul thread à la fois.
J'ai donc pensé que 'load_any_image' était peut-être dangereux en mettant ce code à l'intérieur mve::ImageBase::Ptr imagel=oad_any_image(afname, &exif);

load_any_image utilise simplement libpng en arrière-plan qui est thread-safe lorsqu'il est correctement utilisé, ce que j'espère que nous ferons. Par "données erronées", je veux dire que, dans le code ci-dessus, l'image peut être écrasée par une autre image avant d'être utilisée et que vous vous retrouvez donc avec les mauvaises données d'image dans votre vue.

Maintenant, juste pour avoir une idée de ce problème, qui est réellement affecté par ces plantages ?

Lorsque je charge une seule image (n'importe quel type jpg tif ou png), tout va bien, mais lorsque je charge deux images (n'importe quel type), il se bloque avec une forte probabilité.

Je ne sais pas ce qui cause le problème. Le chargement d'images devrait être possible en parallèle, et je n'ai jamais vu de problèmes. Ce plantage est-il peut-être lié à votre mémoire disponible, si vous chargez des images vraiment volumineuses ? Je peux imaginer que le chargement de 32 images (au cas où vous auriez autant de cœurs) en parallèle sur une machine de 2 Go de RAM causera des problèmes.

En attendant, mettez simplement une ligne #pragma omp critical avant load_any_image , ce qui devrait résoudre le problème.

@timlgy , pouvez-vous poster une trace du crash ?
Aussi, que voulez-vous dire par "16U32G" ?

@andre-schulz 16U32G signifie CPU 16 threads multiples et 32 ​​Go de mémoire

J'observe le même plantage sur Windows 7 64x avec la dernière version mve par instruction :

crash

J'ai essayé de "mettre une ligne #pragma omp critique avant load_any_image", mais cela n'aide pas, dans ce cas, je ne peux pas construire. Comment pouvons-nous résoudre ce problème ? Quel est le but d'utiliser OpenMP ici ?

image

J'ai essayé d'importer une seule image : j'obtiens également le même plantage.

Salut @stiv-yakovenko,
Merci pour l'information. Vous est-il possible de poster le fichier png qui pose problème ?
Aussi, quel CPU utilises-tu ?

cpuz

Le problème semble être que makescene a été compilé en mode Debug mais lié à libpng en mode Release ; probablement un problème de liaison avec différentes bibliothèques d'exécution (/MD vs. /MDd). C'est un problème avec la façon dont le système de construction actuel fonctionne. Je dois enquêter plus avant.
Pouvez-vous confirmer que makescene fonctionne en mode RelWithDebInfo ?

Si vous devez exécuter makescene en mode débogage, vous pouvez compiler les bibliothèques tierces en mode débogage en ajoutant Debug à CMAKE_CONFIGURATION_TYPES dans le CMakeLists.txt tiers. Ensuite, recompilez et copiez manuellement les versions de débogage des bibliothèques à l'emplacement de la version de débogage de makescene . Je vais essayer de savoir si je peux résoudre/automatiser cela d'une manière ou d'une autre.

Je confirme que la version ReleaseWithDeb fonctionne.

@andre-schulz Bonjour, merci pour votre analyse sur le mode débogage. J'ai recompilé les bibliothèques tierces en mode débogage et ajouté tiffd.dll, zlibd.dll à la version débogage de makescene. Le programme s'est encore planté dans

png_read_image(png, &row_pointers[0]);

image

@andre-schulz C'est bon maintenant ! Après une compilation complète du débogage après la modification de CMAKE_CONFIGURATION_TYPES dans CMakeLists.txt des bibliothèques tierces et la modification de la configuration de la bibliothèque d'entrée de MVE.sln, le problème de chargement de jpg est résolu.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

HelliceSaouli picture HelliceSaouli  ·  12Commentaires

GustavoCamargoRL picture GustavoCamargoRL  ·  13Commentaires

HelliceSaouli picture HelliceSaouli  ·  14Commentaires

daleydeng picture daleydeng  ·  8Commentaires

Jus80687 picture Jus80687  ·  11Commentaires