调试libpng-1.2.46-2 Fedora Core 16 - .PNG前8位没有超过libpng

时间:2012-03-22 04:45:41

标签: c++ fedora gtkmm libpng

我从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位和我从互联网上下载的一些其他.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

1 个答案:

答案 0 :(得分:1)

问题似乎是检查png_sig_cmp的返回值。看一下文档,它似乎遵循memcmp返回样式,换句话说,对于一个好的头,返回0,对于不匹配,返回非零。