Hi, I notice that a fc_value_string macro is used to retrieve a string from an FcValue object. #define FcValueString(v) FcPointerMember(v, u.s, FcChar8) Which seems to expand to: (((intptr_t) (v->u.s) & 1) != 0) ? (FcChar8 *) ((intptr_t) v + ((intptr_t) (v->u.s) & ~1)) : v->u.s As I understand it, if the string is at an odd address, then return the base FcValue object address + the 31 most significant bits of the address of the string, otherwise return the address of the string. This happens when using the patelt expression in the xml config files and other locations like loading the font map: #0 0xb744ac49 in FcStrCaseWalkerNext (w=0xbfa94c24) at fcstr.c:160 #1 0xb744ae48 in IA__FcStrCmpIgnoreCase (s1=0xd2c21fe6 <Address 0xd2c21fe6 out of bounds>, s2=0x200e4d0e <Address 0x200e4d0e out of bounds>) at fcstr.c:224 #2 0xb743642e in FcConfigCompareValue (left_o=0x69611ff0, op=FcOpEqual, right_o=0xbfa94d18) at fccfg.c:683 #3 0xb743762d in FcConfigMatchValueList (p=0x695a9ff0, t=0x690d6fe8, values=0x69611fec) at fccfg.c:1088 #4 0xb7437d16 in IA__FcConfigSubstituteWithPat (config=0x69617fbc, p=0x695a9ff0, p_pat=0x0, kind=FcMatchPattern) at fccfg.c:1358 #5 0xb74381f9 in IA__FcConfigSubstitute (config=0x0, p=0x695a9ff0, kind=FcMatchPattern) at fccfg.c:1512 #6 0xb7465ebd in pango_cairo_fc_font_map_context_substitute (fcfontmap=0x17c1ec60, context=0x29ea9f50, pattern=0x695a9ff0) at pangocairo-fcfontmap.c:95 #7 0xb6d39e95 in pango_fc_default_substitute (fontmap=0x17c1ec60, context=0x29ea9f50, pattern=0x695a9ff0) at pangofc-fontmap.c:988 #8 0xb6d3a1f8 in pango_fc_font_map_get_patterns (fontmap=0x17c1ec60, context=0x29ea9f50, desc=0x110f1f80, language=0x69cf9ffa) at pangofc-fontmap.c:1081 #9 0xb6d3a5e3 in pango_fc_font_map_load_fontset (fontmap=0x17c1ec60, context=0x29ea9f50, desc=0x110f1f80, language=0x69cf9ffa) at pangofc-fontmap.c:1238 #10 0xb73cb232 in pango_font_map_load_fontset (fontmap=0x17c1ec60, context=0x29ea9f50, desc=0x110f1f80, language=0x69cf9ffa) at pango-fontmap.c:107 In FcConfigCompareValue, left_o and right_o are: (gdb) print *left_o $14 = {type = FcTypeString, u = {s = 0x6960fff7 "Sans", i = 1767964663, b = 1767964663, d = -1.9593223504712061e-42, m = 0x6960fff7, c = 0x6960fff7, f = 0x6960fff7, p = 0x6960fff7, l = 0x6960fff7}} (gdb) print *right_o $15 = {type = FcTypeString, u = {s = 0x6064fff7 "mono", i = 1617231863, b = 1617231863, d = 4.7669276023636118e-270, m = 0x6064fff7, c = 0x6064fff7, f = 0x6064fff7, p = 0x6064fff7, l = 0x6064fff7}} And after ''Canonicalize''-ing you get: (gdb) print left $16 = {type = FcTypeString, u = {s = 0xd2c21fe6 <Address 0xd2c21fe6 out of bounds>, i = -759029786, b = -759029786, d = 3.8689810404977115e-314, m = 0xd2c21fe6, c = 0xd2c21fe6, f = 0xd2c21fe6, p = 0xd2c21fe6, l = 0xd2c21fe6}} (gdb) print right $17 = {type = FcTypeString, u = {s = 0x200e4d0e <Address 0x200e4d0e out of bounds>, i = 537808142, b = 537808142, d = 2.3877083179811831e-314, m = 0x200e4d0e, c = 0x200e4d0e, f = 0x200e4d0e, p = 0x200e4d0e, l = 0x200e4d0e}}
Keith Packard
2008-Jan-02 17:53 UTC
[Fontconfig] Understanding the FcValue type == FcTypeString
On Wed, 2008-01-02 at 16:58 +0000, David wrote:> Hi, > > I notice that a fc_value_string macro is used to retrieve a string from > an FcValue object. > > #define FcValueString(v) FcPointerMember(v, u.s, FcChar8) > > Which seems to expand to: > > (((intptr_t) (v->u.s) & 1) != 0) ? > (FcChar8 *) ((intptr_t) v + ((intptr_t) (v->u.s) & ~1)) > : v->u.sThe commends around the definition of FcValueString, FcValueCharSet and FcValueLangSet are relevant here -- fontconfig uses offsets instead of pointers almost everywhere as this allows objects to live in mmap''d files without requiring them to be mapped at a specific address. However, the FcValue type is exposed, and so sometimes these three types may end up as regular pointers instead of offsets. I stole the low bit of the pointer to disambiguate pointers from offsets, which is an ugly hack, but I needed to preserve ABI compatiblity and so couldn''t change the FcValue datatype.> As I understand it, if the string is at an odd address, then return the > base FcValue object address + the 31 most significant bits of the > address of the string, otherwise return the address of the string.Odd pointer values are not addresses, they''re offsets. The rest of the internal data structures use offsets exclusively. Hmm. I might be able to use a bit of the FcType field instead of the pointer itself. That might be safer in the presence of systems that can pass strings with odd addresses to the library. -- keith.packard at intel.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://lists.freedesktop.org/archives/fontconfig/attachments/20080102/4003e894/attachment.pgp
Ah, I forgot to mention I am using a memory checker called DUMA. This doesn''t happen without DUMA, so it is probably doing something funny with the alignment. Keith Packard wrote:> On Wed, 2008-01-02 at 16:58 +0000, David wrote: > >> Hi, >> >> I notice that a fc_value_string macro is used to retrieve a string from >> an FcValue object. >> >> #define FcValueString(v) FcPointerMember(v, u.s, FcChar8) >> >> Which seems to expand to: >> >> (((intptr_t) (v->u.s) & 1) != 0) ? >> (FcChar8 *) ((intptr_t) v + ((intptr_t) (v->u.s) & ~1)) >> : v->u.s >> > > The commends around the definition of FcValueString, FcValueCharSet and > FcValueLangSet are relevant here -- fontconfig uses offsets instead of > pointers almost everywhere as this allows objects to live in mmap''d > files without requiring them to be mapped at a specific address. > However, the FcValue type is exposed, and so sometimes these three types > may end up as regular pointers instead of offsets. I stole the low bit > of the pointer to disambiguate pointers from offsets, which is an ugly > hack, but I needed to preserve ABI compatiblity and so couldn''t change > the FcValue datatype. > > >> As I understand it, if the string is at an odd address, then return the >> base FcValue object address + the 31 most significant bits of the >> address of the string, otherwise return the address of the string. >> > > Odd pointer values are not addresses, they''re offsets. The rest of the > internal data structures use offsets exclusively. > > Hmm. I might be able to use a bit of the FcType field instead of the > pointer itself. That might be safer in the presence of systems that can > pass strings with odd addresses to the library. > >