[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