[Pkg-gmagick-im-team] Bug#777158: Text functions segfault on i386

Herwin Weststrate herwin at quarantainenet.nl
Mon May 4 14:14:31 UTC 2015


Some more observations:

The error begins in PerlMagick/Magick.xs method QueryFontMetrics around
line 12321:

  draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
  CloneString(&draw_info->text,"");

Tracing CloneDrawInfo in GDB, we have the following piece of code:

  clone_info=(DrawInfo *) AcquireMagickMemory(sizeof(*clone_info));
  ...
  GetDrawInfo(image_info,clone_info);
  if (draw_info == (DrawInfo *) NULL)
    return(clone_info);

AcquireMagickMemory is basicly a malloc, and GetDrawInfo initialized the
structure created with AcquireMagickMemory with some defaults. The
relevant changes it does here (we'll get to why these attributes are
relevant in a minute):

  clone_info.text = NULL;
  clone_info.decorate = NoDecoration;
  clone_info.compose = OverCompositeOp;

After the call to GetDrawInfo in CloneDrawInfo, my attempt here results
in the following addresses (reproduction may vary):

  (gdb) p &clone_info->text
  $1 = (char **) 0x90b93bc
  (gdb) p &clone_info->compose
  $2 = (CompositeOperator *) 0x90b93b8
  (gdb) p &clone_info->decorate
  $3 = (DecorationType *) 0x90b93b4

Calling "next" in GDB after this point jumps to line 351, which is the
end of the function CloneDrawInfo. Suddenly we can't read the symbolic
value anymore:

  (gdb) p clone_info->text
  value has been optimized out
  (gdb) p &clone_info->text
  value has been optimized out
  (gdb) p clone_info
  $4 = <optimized out>

When returning to QueryFontMetrics on line 12322, the symbol draw_info
(which was the result of CloneDrawInfo) behaves the same, everything has
been optimized out. Once we continue, we get the segfault:

  #3  0xf76cdc8e in CloneString (destination=0x90b93b4,
            source=0xf7855f1f "") at ../../magick/string.c:287

Destination should have been the value of `&draw_info->text`, but thas
was 0x90b93bc. Instead, an address of 8 bytes lower has been passed. If
we look at the definition of DrawInfo:

  ..
  DecorationType decorate;
  CompositeOperator compose;
  char *text;
  ...

This shows that decorate has been passed. This has been initialized with
the value NoDecoration, which results in 1. This explains the 0x1
showing up in the backtraces in GDB. Just to be complete, the memory
looks like this:

  (gdb) x/3x 0x90b93b4
  0x90b93b4:    0x00000001    0x00000028    0x00000000

The second value (0x28) is the value of OverCompositeOp, assigned to
draw_info->compose. The third value is a NULL-pointer for the text.

I don't really understand what could make this shift of two bytes.

-- 
Herwin Weststrate



More information about the Pkg-gmagick-im-team mailing list