Mve: Makescene trava ao importar arquivos PNG

Criado em 5 set. 2017  ·  30Comentários  ·  Fonte: simonfuhrmann/mve

Eu tenho um problema com o comando makescene que não consigo resolver sozinho.

Eu clonei e construi o repositório de acordo com as instruções no Readme.md no Ubuntu 16.04 64 bits. A compilação compila sem erros e todos os aplicativos estão lá.

No entanto, se eu executar o comando makescene com os parâmetros -i, ele apenas criará a pasta de cena e depois travará com a mensagem "Ungültiger Maschinenbefehl (Speicherabzug geschrieben)" (eu corro a versão alemã do Ubuntu)

Adicionei mensagens de saída ao código para ver até que ponto o comando é executado e, aparentemente, o travamento ocorre no arquivo image_io.cc, na função load_png_file, nas linhas 311-314, onde os ponteiros estão configurados.

Eu não sei como consertar isso, no entanto. Os valores para headers.height e headers.channels parecem fazer sentido.

Todos 30 comentários

Um crash em image_io é relativamente improvável. Você pode tentar escrever um programa de teste e carregar a imagem manualmente?

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

Há algo mais especial sobre a imagem? É um PNG de 8 ou 16 bits?

Ok, eu compilei o programa de teste e tento carregar um PNG que esteja na mesma pasta do aplicativo de teste. Eu recebo o mesmo resultado, o programa trava com "Ungültiger Maschinenbefehl (Speicherabzug geschrieben)".

No entanto, se eu alterar a chamada de função para "load_tiff_file" e carregar um arquivo TIFF, parece funcionar bem. Talvez a função load_png_file esteja quebrada especificamente?

Não tenho certeza se isso é de alguma ajuda, mas alterei o código de volta para load_png_file e usei strace para obter os logs do sistema relacionados a este aplicativo. Estas são as últimas linhas desse log antes de travar:

14:00:46.197536 open("./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 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
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 +++ morto por SIGILL (núcleo despejado) +++

Você se importa de me enviar um link para essa imagem?

Meu palpite é que a imagem tem apenas uma extensão png, mas na verdade não é um png... Já vi problemas semelhantes em que um arquivo “.png” era realmente codificado em jpeg.

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

Usei o ffmpeg para exportar os quadros de um vídeo para arquivos de imagem.

Eu pensei que poderia ser o formato de arquivo errado também, mas usei o comando convert para convertê-lo de png para tiff e vice-versa, sem efeito.

O arquivo carrega bem aqui.

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
...

De acordo com seu strace , seu programa é morto por SIGILL (não KILL). Acredito que isso signifique que seu processador ou sistema operacional está tentando executar uma instrução inválida. Não sei o que fazer com isso, mas acredito que seja seu sistema ou sua biblioteca libpng que está de alguma forma confusa. Você pode tentar reinstalar/atualizar libpng?

Então, eu desinstalei a versão libpng que instalei via apt-get install e, em vez disso, baixei o repositório libpng diretamente, compilei e instalei isso.

Infelizmente, tem o mesmo efeito. Talvez seja realmente o meu processador? Eu atualmente uso um processador AMD Phenom II X4 965, que não é o modelo mais novo, eu acho. Ainda assim, acho que nunca tive problemas semelhantes antes.

De qualquer forma, já que vocês não podem reproduzir o problema, acho que vou fechar o assunto.

Lamento saber que ainda não funciona. Eu realmente não acho que seja o seu hardware... mas estou sem ideias. Talvez existam sinalizadores de tempo de compilação para desabilitar certos recursos de aceleração para libpng? Neste ponto, estou apenas supondo sem realmente saber o que está causando o problema.

Eu sei por que o makescene trava ao importar arquivos de imagem após muitos experimentos. Não é o motivo do libjpeg ou libpng, o motivo real é o openMP. Você pode corrigir esse bug com estes códigos em makescene.cc:
Linha 845
mve::ImageBase::Ptr imagem;

pragma omp paralelo para agendamento ordenado (dinâmico,1)

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

....
std::string exif;

pragma omp crítico

    image = load_any_image(afname, &exif);

...

Mas essa mudança não faz muito sentido. Você está armazenando a imagem na variável image que é compartilhada em todos os encadeamentos e, embora o carregamento da imagem seja serializado agora, você substituirá a imagem devido a condições de corrida e usará os dados errados após carregar a imagem. ..

Você já tentou apenas colocar o #pragma omp critical antes do carregamento da imagem?

@timlgy , você pode nos contar um pouco mais sobre seu sistema? Qual CPU, sistema operacional e compilador você está usando?

Funciona para mim no Ubuntu 14.04.5 LTS, 16U32G e o compilador é gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1 ~ 14.04.3) PS 'dados errados' o que é isso? prebundle.sfm?

de acordo com este artigo #pragma omp critical
A diretiva omp critical identifica uma seção de código que deve ser executada por uma única thread por vez.
Então eu pensei que talvez 'load_any_image' fosse perigoso ao colocar esse código dentro de mve::ImageBase::Ptr imagel=oad_any_image(afname, &exif);

load_any_image apenas usa libpng em segundo plano, que é thread-safe quando usado corretamente, o que espero que façamos. Por "dados errados", quero dizer que, no código acima, a imagem pode ser substituída por outra imagem antes de ser usada e, assim, você acaba com os dados de imagem errados em sua visualização.

Agora, apenas para ter uma ideia desse problema, quem é realmente afetado por essas falhas?

Quando carrego apenas uma imagem (qualquer tipo jpg tif ou png), tudo bem, mas quando carrego duas imagens (qualquer tipo), ela trava com alta probabilidade.

Não sei o que causa o problema. O carregamento de imagens deve ser possível em paralelo, e nunca vi problemas. Esta falha pode estar relacionada à sua memória disponível, se você carregar imagens muito grandes? Posso imaginar que carregar 32 imagens (caso você tenha tantos núcleos) em paralelo em uma máquina de 2 GB de RAM causará problemas.

Enquanto isso, basta colocar uma linha #pragma omp critical antes load_any_image , o que deve resolver o problema.

@timlgy , você pode postar um backtrace da falha?
Além disso, o que você quer dizer com "16U32G"?

@andre-schulz 16U32G significa CPU 16 threads múltiplos e 32GB Mem

Eu observo a mesma falha no Windows 7 64x com a última compilação do mve por instrução:

crash

Tentei "colocar uma linha #pragma omp critical antes de load_any_image", mas isso não ajuda, neste caso não consigo construir. Como podemos resolver isso? Qual é o propósito de usar o OpenMP aqui?

image

Tentei importar apenas uma imagem: também recebo a mesma falha.

Olá @stiv-yakovenko,
Obrigado pela informação. É possível postar o arquivo png que está causando o problema?
Além disso, qual processador você está usando?

cpuz

O problema parece ser que makescene foi compilado no modo Debug, mas vinculado a libpng no modo Release; provavelmente um problema com a vinculação a diferentes bibliotecas de tempo de execução (/MD vs. /MDd). Este é um problema com a forma como o sistema de compilação atual funciona. Tenho que investigar isso mais a fundo.
Você pode confirmar que makescene funciona no modo RelWithDebInfo?

Se você precisar executar makescene no modo de depuração, poderá compilar as bibliotecas de terceiros no modo de depuração adicionando Debug a CMAKE_CONFIGURATION_TYPES no CMakeLists.txt de terceiros. Em seguida, recompile e copie manualmente as versões de depuração das bibliotecas para o local da versão de depuração de makescene . Vou tentar descobrir se posso de alguma forma corrigir/automatizar isso.

Confirmo que a versão ReleaseWithDeb funciona.

@andre-schulz Olá, obrigado por sua análise sobre o modo de depuração. Eu recompilei as bibliotecas de terceiros no modo de depuração e adicionei tiffd.dll, zlibd.dll à versão de depuração do makescene. O programa ainda travou em

png_read_image(png, &row_pointers[0]);

image

@andre-schulz Está tudo bem agora! Após uma compilação completa de depuração após modificar CMAKE_CONFIGURATION_TYPES em CMakeLists.txt das bibliotecas de terceiros e modificar a configuração de lib de entrada de MVE.sln, o problema de carregamento de jpg foi resolvido.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

HelliceSaouli picture HelliceSaouli  ·  14Comentários

Jus80687 picture Jus80687  ·  11Comentários

HelliceSaouli picture HelliceSaouli  ·  12Comentários

GustavoCamargoRL picture GustavoCamargoRL  ·  13Comentários

daleydeng picture daleydeng  ·  8Comentários