0

我从 libpng 文档中直接获取了以下代码:此外,如果它有任何用途,则此代码位于从基于 gtkmm 的应用程序调用的类中。

FILE *fp = fopen(path.c_str(), "rb");
if (!fp)
  return false; 

unsigned char sig[8];
fread(sig, 1, 8, fp);
if (!png_sig_cmp(sig, 0, 8))
  return false;

我安装了 debuginfo,并从命令行运行 gdb。我继续单步执行代码以查看为什么该png_sig_cmp()函数说我使用 GIMP 创建的 png 的前 8 位以及我从 Internet 下载的一些其他 .png 文件无法被 png 识别。我希望 gdb 的输出比对我来说更能提供信息:

...
_IO_fread (buf=<optimized out>, size=1, count=8, fp=0x848440) at iofread.c:43
43    _IO_acquire_lock (fp);
(gdb) 
_IO_acquire_lock_fct (p=<optimized out>) at libioP.h:968
968   if ((fp->_flags & _IO_USER_LOCK) == 0)
(gdb) 
969     _IO_funlockfile (fp);
(gdb) 
_IO_fread (buf=<optimized out>, size=1, count=8, fp=0x848440) at iofread.c:46
46    return bytes_requested == bytes_read ? count : bytes_read / size;
(gdb) 
47  }
(gdb) 
PNGFileReader::read_png (this=0x7ca620, path=<optimized out>) at pngfilereader.cpp:46
46    if (!png_sig_cmp(sig, 0, 8))
(gdb) step
png_sig_cmp (sig=0x7fffffffd830 "\211PNG\r\n\032\n\236\330\377\377\377\177", start=0, num_to_check=8) at png.c:122
122 {
(gdb) 
124    if (num_to_check > 8)
(gdb) 
123    png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
(gdb) 
124    if (num_to_check > 8)
(gdb) 
126    else if (num_to_check < 1)
(gdb) 
127       return (-1);
(gdb) 
126    else if (num_to_check < 1)
(gdb) 
129    if (start > 7)
(gdb) 
130       return (-1);
(gdb) 
129    if (start > 7)
(gdb) 
132    if (start + num_to_check > 8)
(gdb) 
135    return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
(gdb) 
__memcmp_sse4_1 () at ../sysdeps/x86_64/multiarch/memcmp-sse4.S:52
52      pxor    %xmm0, %xmm0
(gdb) 
53      cmp $79, %rdx
(gdb) 
54      ja  L(79bytesormore)
(gdb) 
56      cmp $1, %rdx
(gdb) 
57      je  L(firstbyte)
(gdb) 
59      add %rdx, %rsi
(gdb) 
60      add %rdx, %rdi
(gdb) 
61      BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 4)
(gdb) 
803     mov -8(%rdi), %rax
(gdb) 
804     mov -8(%rsi), %rcx
(gdb) 
805     cmp %rax, %rcx
(gdb) 
806     jne L(diffin8bytes)
(gdb) 
807     xor %eax, %eax
(gdb) 
__memcmp_sse4_1 () at ../sysdeps/x86_64/multiarch/memcmp-sse4.S:808
808     ret
(gdb) 
png_sig_cmp (sig=<optimized out>, start=<optimized out>, num_to_check=<optimized out>) at png.c:136
136 }
(gdb) 
PNGFileReader::read_png (this=0x7ca620, path=<optimized out>) at pngfilereader.cpp:47
47      return false;
(gdb) 
46    if (!png_sig_cmp(sig, 0, 8))

png_sig_cmp从函数返回的堆栈跟踪一是

#0  PNGFileReader::read_png (this=0x7ca620, path=<optimized out>) at pngfilereader.cpp:46
#1  0x0000000000409017 in DrawingArea::zoom (this=0x7c8360, zoom_factor=<optimized out>) at drawingarea.cpp:97
#2  0x00000000004090cd in DrawingArea::on_scroll_event (this=<optimized out>, event=<optimized out>) at drawingarea.cpp:70
#3  0x000000351fd5cb03 in Gtk::Widget_Class::scroll_event_callback (self=0x6df8e0 [gtkmm__GtkDrawingArea], p0=0x7bf4b0) at widget.cc:4474
#4  0x000000351cf52848 in _gtk_marshal_BOOLEAN__BOXED (closure=0x62d640, return_value=0x7fffffffda80, n_param_values=<optimized out>, param_values=0x82da90, 
    invocation_hint=<optimized out>, marshal_data=<optimized out>) at gtkmarshalers.c:85
#5  0x0000003515a0ea24 in g_closure_invoke (closure=0x62d640, return_value=0x7fffffffda80, n_param_values=2, param_values=0x82da90, invocation_hint=<optimized out>)
    at gclosure.c:774
#6  0x0000003515a20b5c in signal_emit_unlocked_R (node=<optimized out>, detail=0, instance=0x6df8e0, emission_return=0x7fffffffdbe0, instance_and_params=0x82da90)
    at gsignal.c:3310
#7  0x0000003515a29f13 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=<optimized out>) at gsignal.c:3013
#8  0x0000003515a2a2e2 in g_signal_emit (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3060
#9  0x000000351d07eff9 in gtk_widget_event_internal (widget=0x6df8e0 [gtkmm__GtkDrawingArea], event=0x7bf4b0) at gtkwidget.c:6132
#10 0x000000351cf51fba in gtk_propagate_event (widget=0x6df8e0 [gtkmm__GtkDrawingArea], event=0x7bf4b0) at gtkmain.c:2614
#11 0x000000351cf523bb in gtk_main_do_event (event=0x7bf4b0) at gtkmain.c:1889
#12 0x000000351de47572 in gdk_event_source_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at gdkeventsource.c:360
#13 0x0000003514a44acd in g_main_dispatch (context=0x663aa0) at gmain.c:2441
#14 g_main_context_dispatch (context=0x663aa0) at gmain.c:3011
#15 0x0000003514a452c8 in g_main_context_iterate (context=0x663aa0, block=<optimized out>, dispatch=1, self=<optimized out>) at gmain.c:3089
#16 0x0000003514a45815 in g_main_loop_run (loop=0x8564c0) at gmain.c:3297
#17 0x000000351cf517fd in gtk_main () at gtkmain.c:1362
#18 0x000000351fcfd026 in Gtk::Main::run (window=...) at main.cc:384
#19 0x00000000004075f0 in main (argc=1, argv=0x7fffffffe168) at main.cpp:10
4

1 回答 1

1

The problem seems to be the check of the return value from png_sig_cmp. Looking at the documentation, it seems this follows a memcmp return style, in other words, 0 is returned for a good header, nonzero for a non-match.

于 2012-03-22T19:31:11.120 回答