bug-gettext
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Segmentation fault in dcigettext.c:925 using Apache + PHP


From: Bruno Haible
Subject: Re: Segmentation fault in dcigettext.c:925 using Apache + PHP
Date: Thu, 28 May 2020 20:58:10 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-177-generic; KDE/5.18.0; x86_64; ; )

Hi,

Wiebe Cazemier wrote:
> We're running an Ubuntu 18.04 server with GNU Gettext 0.19.8.1-6ubuntu0.3, 
> Apache 2.4.29-1ubuntu4.13, mod-php 7.2.24-0ubuntu0.18.04.6. We're getting 
> occasional segmentation faults in the Apache worker, from dcigettext.c:925:
> 
> > Program terminated with signal SIGSEGV, Segmentation fault.
> > [...snip...]
> > 925     dcigettext.c: No such file or directory.
> > (gdb) bt
> > #0  _nl_find_msg (domain_file=domain_file@entry=0x55c520144980, 
> > domainbinding=domainbinding@entry=0x55c520141aa0, 
> > msgid=msgid@entry=0x7fd27b426610 "Home", convert=convert@entry=1, 
> > lengthp=lengthp@entry=0x7ffde958b268) at dcigettext.c:925
> > #1  0x00007fd29bc6f5eb in __dcigettext (domainname=<optimized out>, 
> > msgid1=0x7fd27b426610 "Home", msgid2=0x0, plural=0, n=0, category=5) at 
> > dcigettext.c:710
> > #2  0x00007fd288adf649 in ?? () from /usr/lib/php/20170718/gettext.so
> 
> Full backtrace is attached.

Thanks for the report.

> dcigettext.c is actually installed by the gettext package (and it's the same 
> one as 'apt-get source gettext' pulls in), but I think that version is not 
> the one used to compile. Line 710 is not _nl_find_msg(). In fact, it's a 
> comment.

You're looking at the wrong source. I'm looking at glibc-2.27/intl/dcigettext.c
from glibc_2.27.orig.tar.xz from https://packages.ubuntu.com/bionic/libc-bin ,
and the line numbers match perfectly:

          retval = _nl_find_msg (domain, binding, msgid1, 1, &retlen); // <- 
Line 710

and

          nls_uint32 nstr =
            W (domain->must_swap_hash_tab, domain->hash_tab[idx]);

          if (nstr == 0)
            /* Hash table entry is empty.  */
            return NULL;

          nstr--;

          /* Compare msgid with the original string at index nstr.
             We compare the lengths with >=, not ==, because plural entries
             are represented by strings with an embedded NUL.  */
          if (nstr < nstrings
              ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len
                && (strcmp (msgid,
                            domain->data + W (domain->must_swap,
                                              domain->orig_tab[nstr].offset))
                    == 0)
              : domain->orig_sysdep_tab[nstr - nstrings].length > len
                && (strcmp (msgid,                                            
// <- Line 925
                            domain->orig_sysdep_tab[nstr - nstrings].pointer)

> The the domain struct:
> 
> 
> (gdb) print *domain
> $2 = {data = 0x7fd27a56f000 <error: Cannot access memory at address 
> 0x7fd27a56f000>, use_mmap = 1, mmap_size = 74773, must_swap = 0, malloced = 
> 0x0, nstrings = 665, orig_tab = 0x7fd27a56f01c, trans_tab = 0x7fd27a5704e4, 
> n_sysdep_strings = 0, orig_sysdep_tab = 0x0, 
>   trans_sysdep_tab = 0x0, hash_size = 887, hash_tab = 0x7fd27a5719ac, 
> must_swap_hash_tab = 0, conversions = 0x55c51fd8e300, nconversions = 1, 
> conversions_lock = {__data = {__readers = 0, __writers = 0, __wrphase_futex = 
> 0, __writers_futex = 0, __pad3 = 0, __pad4 = 0, 
>       __cur_writer = 0, __shared = 0, __rwelision = 0 '\000', __pad1 = 
> "\000\000\000\000\000\000", __pad2 = 0, __flags = 0}, __size = '\000' 
> <repeats 55 times>, __align = 0}, plural = 0x55c520143a00, nplurals = 1}
> 
> 
> Then a frame up the trace (frame 1):
> 
> 
> (gdb) info locals
> domain = 0x55c520144980
> binding = <optimized out>
> categoryname = <optimized out>
> categoryvalue = 0x7fd29186f20e ""
> dirname = 0x55c520141ad0 "/var/www/website/includes/locale"
> xdirname = 0x0
> xdomainname = 0x7ffde958b1c0 "LC_MESSAGES/messages.mo"
> single_locale = <optimized out>
> retval = <optimized out>
> retlen = 140728518357728
> saved_errno = 2
> search = {domainname = 0x7fd29bdf4830 <_nl_default_default_domain> 
> "messages", category = 5, localename = 0x55c52034ab90 "zh_CN", counter = 
> -1734892282, domain = 0x0, translation = 0x7fd2918826f8 "Turkish", 
> translation_length = 0, msgid = {
>     appended = 0x7ffde958b2a8 "\020fB{\322\177", ptr = 0x7fd27b426610 "Home"}}
> foundp = 0x55c520144ce0
> localename = 0x55c52034ab90 "zh_CN"
> domainname_len = 8
> 
> 
> Then the args:
> 
> 
> (gdb) info args
> domainname = <optimized out>
> msgid1 = 0x7fd27b426610 "Home"
> msgid2 = 0x0
> plural = 0
> n = 0
> category = 5

This is valuable info. Can you please also attach all the files that
match the wildcard
  /var/www/website/includes/locale/zh*/LC_MESSAGES/messages.mo ?

Most probably, the .mo file has invalid offsets.

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]