Mve: 导入PNG文件时makescene崩溃

创建于 2017-09-05  ·  30评论  ·  资料来源: simonfuhrmann/mve

我无法自行解决 makescene 命令的问题。

我已经根据 Ubuntu 16.04 64 位下的 Readme.md 中的说明克隆并构建了存储库。 构建编译没有错误,所有应用程序都在那里。

但是,如果我使用参数 -i 运行 makescene 命令,它只会创建场景文件夹,然后崩溃并显示消息“Ungültiger Maschinenbefehl (Speicherabzug geschrieben)”(我运行德语版的 Ubuntu)

我在代码中添加了输出消息,以查看命令执行的程度,显然,崩溃发生在 image_io.cc 文件中的 load_png_file 函数中,在第 311-314 行附近,其中设置了指针。

不过,我不知道如何解决它。 headers.height 和 headers.channels 的值似乎有意义。

所有30条评论

image_io的崩溃相对不太可能。 你可以尝试编写一个测试程序并手动加载图像吗?

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

图片还有什么特别之处吗? 它是 8 位还是 16 位 PNG?

好的,我已经编译了测试程序并尝试加载与测试应用程序位于同一文件夹中的 PNG。 我得到相同的结果,程序因“Ungültiger Maschinenbefehl (Speicherabzug geschrieben)”而崩溃。

但是,如果我将函数调用更改为“load_tiff_file”并加载 TIFF 文件,它似乎运行良好。 也许 load_png_file 函数被专门破坏了?

不确定这是否有任何帮助,但我已将代码改回 load_png_file 并使用 strace 获取与此应用程序相关的系统日志。 这些是该日志在崩溃之前的最后几行:

14:00:46.197536 打开(“./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 读取(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 +++ 被 SIGILL 杀死(核心转储) +++

你介意给我发那个图片的链接吗?

我的猜测是图像只有一个 png 扩展名,但实际上不是 png ......我见过类似的问题,其中“.png”文件实际上是 jpeg 编码的。

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

我使用 ffmpeg 将视频的帧导出为图像文件。

我认为它也可能是错误的文件格式,但我使用 convert 命令将其从 png 转换为 tiff 并返回,但没有任何效果。

该文件在这里加载良好。

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

根据您的strace ,您的程序被 SIGILL 杀死(而不是 KILL)。 我相信这意味着您的处理器或操作系统正在尝试执行无效指令。 我不知道该怎么做,但我相信是你的系统,或者你的 libpng 库搞砸了。 您可以尝试重新安装/升级 libpng 吗?

所以,我已经卸载了我通过 apt-get install 安装的 libpng 版本,而是直接下载了 libpng 存储库,编译它并安装它。

不幸的是,它具有相同的效果。 也许它真的是我的处理器? 我目前使用的是 AMD Phenom II X4 965 处理器,我猜这不是最新型号。 不过,我认为我以前从未遇到过类似的问题。

不管怎样,既然你们不能重现这个问题,我想我会关闭这个问题。

我很遗憾听到它仍然不起作用。 我真的不认为这是你的硬件......但我没有想法。 也许有编译时标志来禁用 libpng 的某些加速功能? 在这一点上,我只是在猜测,并不知道是什么导致了问题。

经过多次实验,我知道为什么在导入图像文件时makescene会崩溃。 这不是libjpeg或libpng的原因,实际原因是openMP。 您可以使用 makecene.cc 中的这些代码修复此错误:
845线
mve::ImageBase::Ptr 图像;

用于有序计划的 pragma omp 并行(动态,1)

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

……
标准::字符串 exif;

pragma omp 关键

    image = load_any_image(afname, &exif);

...

但这种改变没有多大意义。 您将图像存储在所有线程共享的image变量中,尽管现在加载图像是序列化的,但由于竞争条件,您将覆盖图像并在加载图像后使用错误的数据。 ..

您是否尝试过在图像加载之前将#pragma omp 置于关键位置?

@timlgy ,你能告诉我们更多关于你的系统的信息吗? 您使用的是哪个 CPU、操作系统和编译器?

它适用于 Ubuntu 14.04.5 LTS、16U32G 和编译器是 gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) PS“错误数据”那是什么? prebundle.sfm?

根据这篇文章#pragma omp critical
omp critical 指令标识必须由单个线程一次执行的一段代码。
所以我认为将这段代码放入mve::ImageBase::Ptr imagel=oad_any_image(afname, &exif);时,'load_any_image' 可能很危险

load_any_image只是在后台使用libpng ,如果正确使用它是线程安全的,我希望我们这样做。 通过“错误数据”,我的意思是,在上面的代码中,图像可能会在使用之前被另一个图像覆盖,因此您最终会在视图中得到错误的图像数据。

现在只是为了感受一下这个问题,谁实际上受到了这些崩溃的影响?

当我只加载一个图像(任何类型的 jpg tif 或 png)时,它是可以的,但是当我加载两个图像(任何类型)时,它很有可能崩溃。

我不知道是什么导致了这个问题。 应该可以并行加载图像,我从未见过问题。 如果您加载非常大的图像,此崩溃是否可能与您的可用内存有关? 我可以想象在 2GB RAM 机器上并行加载 32 个图像(如果你有那么多内核)会导致问题。

同时,只需在load_any_image #pragma omp critical即可解决问题。

@timlgy ,你能发布崩溃的回溯吗?
另外,“16U32G”是什么意思?

@andre-schulz 16U32G 表示 CPU 16 多线程和 32GB 内存

我在 Windows 7 64x 上使用最新的 mve build by 指令观察到同样的崩溃:

crash

试图“在 load_any_image 之前添加一行 #pragma omp critical”,但这没有帮助,在这种情况下我无法构建。我们如何解决这个问题?在这里使用 OpenMP 的目的是什么?

image

尝试只导入一张图片:我也遇到了同样的崩溃。

嗨@stiv-yakovenko,
感谢您的信息。 您是否可以发布导致问题的 png 文件?
另外,你用的是哪个CPU?

cpuz

问题似乎是makescene是在 Debug 模式下编译的,但在 Release 模式下链接到 libpng; 链接不同的运行时库(/MD 与 /MDd)可能存在问题。 这是当前构建系统工作方式的问题。 我必须对此进行进一步调查。
你能确认makescene在 RelWithDebInfo 模式下工作吗?

如果您需要在 Debug 模式下运行makescene ,您可以在 3rdparty CMakeLists.txt $ 中将Debug添加到CMAKE_CONFIGURATION_TYPES以在 Debug 模式下编译 3rdparty 库。 然后,重新编译并手动将库的调试版本复制到makescene的调试版本的位置。 我将尝试找出是否可以以某种方式修复/自动化此问题。

我确认 ReleaseWithDeb 版本有效。

@andre-schulz 嗨,感谢您对调试模式的分析。 我已经在调试模式下重新编译了 3rdparty 库,并将 tiffd.dll、zlibd.dll 添加到 makecene 的调试版本中。 程序仍然崩溃

png_read_image(png, &row_pointers[0]);

image

@andre-schulz 现在好了! 修改了3rdparty库的CMakeLists.txt中的CMAKE_CONFIGURATION_TYPES,修改了MVE.sln的input lib配置后,经过完整的debug编译,解决了jpg加载问题。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

HelliceSaouli picture HelliceSaouli  ·  12评论

Jus80687 picture Jus80687  ·  11评论

daleydeng picture daleydeng  ·  8评论

GustavoCamargoRL picture GustavoCamargoRL  ·  13评论

HelliceSaouli picture HelliceSaouli  ·  14评论