packages icon indicating copy to clipboard operation
packages copied to clipboard

perl: SIGSEGV on start if LC_ALL is unset

Open egorenar opened this issue 1 year ago • 16 comments

Maintainer: Esaaprilia Salsabila Environment: ARMv7 Processor rev 4 (v7l), custom OpenWRT fw

Description:

  • perl always crashes on startup after upgrade

GDB output:

Reading symbols from ./build_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/perl/perl-5.40.0/perl...
0xb6fe69c8 in _dlstart () from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/lib/ld-musl-armhf.so.1
=> 0xb6fe69c8 <_dlstart+0>:     e3a0b000        mov     r11, #0
(gdb) r
Starting program: /home/egorenar/Repositories/openwrt-rel/build_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/perl/perl-5.40.0/perl

Program received signal SIGSEGV, Segmentation fault.
0xb6fd8d18 in strlen (s=<optimized out>) at src/string/strlen.c:17
17              for (w = (const void *)s; !HASZERO(*w); w++);
   0xb6fd8d0c <strlen+52>:      e308e080        movw    lr, #32896      @ 0x8080
   0xb6fd8d10 <strlen+56>:      e34f4efe        movt    r4, #65278      @ 0xfefe
   0xb6fd8d14 <strlen+60>:      e348e080        movt    lr, #32896      @ 0x8080
=> 0xb6fd8d18 <strlen+64>:      e593c000        ldr     r12, [r3]
   0xb6fd8d1c <strlen+68>:      e1a02003        mov     r2, r3
   0xb6fd8d20 <strlen+72>:      e2833004        add     r3, r3, #4
   0xb6fd8d24 <strlen+76>:      e08c1004        add     r1, r12, r4
   0xb6fd8d28 <strlen+80>:      e1c1100c        bic     r1, r1, r12
   0xb6fd8d2c <strlen+84>:      e111000e        tst     r1, lr
   0xb6fd8d30 <strlen+88>:      0afffff8        beq     0xb6fd8d18 <strlen+64>
   0xb6fd8d34 <strlen+92>:      e1a03002        mov     r3, r2
(gdb) bt
#0  0xb6fd8d18 in strlen (s=<optimized out>) at src/string/strlen.c:17
#1  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#2  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#3  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#4  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#5  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#6  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#7  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#8  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#9  0xb6e3265c in Perl_sv_vcatpvfn_flags ()
   from /home/egorenar/Repositories/openwrt-rel/scripts/../staging_dir/target-arm_cortex-a15+neon-vfpv4_musl_eabi/root-alpine/usr/lib/perl5/5.40/CORE/libperl.so
#10 0xb6e3265c in Perl_sv_vcatpvfn_flags ()

egorenar avatar Jul 04 '24 14:07 egorenar

gdb> info reg # r3 is from....
gdb> info proc mappings # same offsets look like excess recursion -> stack depletion -> ??? overflow to trap page ???

also set breakpoint at Perl_sv_vcatfpn_flags () and run it again. might need -g -O0 build if too much sense is optimized away.

brada4 avatar Jul 04 '24 15:07 brada4

info proc mappings

thanks for the hints!

Program received signal SIGSEGV, Segmentation fault.
0xb6fd8d18 in strlen (s=<optimized out>) at src/string/strlen.c:17
17              for (w = (const void *)s; !HASZERO(*w); w++);
   0xb6fd8d0c <strlen+52>:      e308e080        movw    lr, #32896      @ 0x8080
   0xb6fd8d10 <strlen+56>:      e34f4efe        movt    r4, #65278      @ 0xfefe
   0xb6fd8d14 <strlen+60>:      e348e080        movt    lr, #32896      @ 0x8080
=> 0xb6fd8d18 <strlen+64>:      e593c000        ldr     r12, [r3]
   0xb6fd8d1c <strlen+68>:      e1a02003        mov     r2, r3
   0xb6fd8d20 <strlen+72>:      e2833004        add     r3, r3, #4
   0xb6fd8d24 <strlen+76>:      e08c1004        add     r1, r12, r4
   0xb6fd8d28 <strlen+80>:      e1c1100c        bic     r1, r1, r12
   0xb6fd8d2c <strlen+84>:      e111000e        tst     r1, lr
   0xb6fd8d30 <strlen+88>:      0afffff8        beq     0xb6fd8d18 <strlen+64>
   0xb6fd8d34 <strlen+92>:      e1a03002        mov     r3, r2
(gdb) info reg
r0             0x5c8               0x5c8
r1             0xbefffbe0          0xbefffbe0
r2             0x5c8               0x5c8
r3             0x5c8               0x5c8
r4             0xfefefeff          0xfefefeff
r5             0x0                 0x0
r6             0xb6e87e56          0xb6e87e56
r7             0xb6e87e5d          0xb6e87e5d
r8             0xffffffff          0xffffffff
r9             0x73                0x73
r10            0x0                 0x0
r11            0x6666666           0x6666666
r12            0xb6f71c98          0xb6f71c98
sp             0xbefffa28          0xbefffa28
lr             0x80808080          0x80808080
pc             0xb6fd8d18          0xb6fd8d18 <strlen+64>
cpsr           0x60000010          0x60000010
fpscr          0x10                0x10
tpidruro       <unavailable>
(gdb) info proc mappings
process 17207
Mapped address spaces:

        Start Addr   End Addr       Size     Offset  Perms   objfile
           0x10000    0x11000     0x1000        0x0  r-xp   /usr/bin/perl5.40.0
           0x11000    0x12000     0x1000        0x0  r--p   /usr/bin/perl5.40.0
           0x12000    0x13000     0x1000        0x0  rw-p   [heap]
           0x13000    0x14000     0x1000        0x0  ---p   [heap]
           0x14000    0x15000     0x1000        0x0  rw-p   [heap]
        0xb6c87000 0xb6ca3000    0x1c000        0x0  rw-p
        0xb6ca3000 0xb6cae000     0xb000        0x0  r-xp   /lib/libgcc_s.so.1
        0xb6cae000 0xb6caf000     0x1000     0xa000  r--p   /lib/libgcc_s.so.1
        0xb6caf000 0xb6cb0000     0x1000     0xb000  rw-p   /lib/libgcc_s.so.1
        0xb6cb0000 0xb6f69000   0x2b9000        0x0  r-xp   /usr/lib/perl5/5.40/CORE/libperl.so
        0xb6f69000 0xb6f72000     0x9000   0x2b9000  r--p   /usr/lib/perl5/5.40/CORE/libperl.so
        0xb6f72000 0xb6f73000     0x1000   0x2c2000  rw-p   /usr/lib/perl5/5.40/CORE/libperl.so
        0xb6f73000 0xb6f7a000     0x7000        0x0  rw-p
        0xb6f7a000 0xb6f7b000     0x1000        0x0  r-xp   [sigpage]
        0xb6f7b000 0xb6f7c000     0x1000        0x0  r--p   [vvar]
        0xb6f7c000 0xb6f7d000     0x1000        0x0  r-xp   [vdso]
        0xb6f7d000 0xb6ffc000    0x7f000        0x0  r-xp   /lib/libc.so
        0xb6ffc000 0xb6ffe000     0x2000    0x7f000  rw-p   /lib/libc.so
        0xb6ffe000 0xb7000000     0x2000        0x0  rw-p
        0xbefdf000 0xbf000000    0x21000        0x0  rw-p   [stack]
        0xffff0000 0xffff1000     0x1000        0x0  r-xp   [vectors]
(gdb)

I will try to obtain more information like suggested.

egorenar avatar Jul 04 '24 15:07 egorenar

The r3 does not look like a pointer totally.... 0xb6ffc000 0xb6ffe000 0x2000 0x7f000 rw-p /lib/libc.so Is in libc.

More excersises: Confirm that perl function in backtrace is in libperl mapping Set breakpoint gdb> b Perl_sv_vcatpvfn_flags then once it is hit continue and check registers -> what is in R3, but should be only SP changing until runs out of stack.

brada4 avatar Jul 04 '24 16:07 brada4

More useful backtrace with -g -O0:

Program received signal SIGSEGV, Segmentation fault.
0xb6fd8d18 in strlen (s=<optimized out>, s@entry=0x5c8 <error: Cannot access memory at address 0x5c8>) at src/string/strlen.c:17
17              for (w = (const void *)s; !HASZERO(*w); w++);
   0xb6fd8d0c <strlen+52>:      e308e080        movw    lr, #32896      @ 0x8080
   0xb6fd8d10 <strlen+56>:      e34f4efe        movt    r4, #65278      @ 0xfefe
   0xb6fd8d14 <strlen+60>:      e348e080        movt    lr, #32896      @ 0x8080
=> 0xb6fd8d18 <strlen+64>:      e593c000        ldr     r12, [r3]
   0xb6fd8d1c <strlen+68>:      e1a02003        mov     r2, r3
   0xb6fd8d20 <strlen+72>:      e2833004        add     r3, r3, #4
   0xb6fd8d24 <strlen+76>:      e08c1004        add     r1, r12, r4
   0xb6fd8d28 <strlen+80>:      e1c1100c        bic     r1, r1, r12
   0xb6fd8d2c <strlen+84>:      e111000e        tst     r1, lr
   0xb6fd8d30 <strlen+88>:      0afffff8        beq     0xb6fd8d18 <strlen+64>
   0xb6fd8d34 <strlen+92>:      e1a03002        mov     r3, r2
(gdb) bt
#0  0xb6fd8d18 in strlen (s=<optimized out>, s@entry=0x5c8 <error: Cannot access memory at address 0x5c8>) at src/string/strlen.c:17
#1  0xb6e3265c in Perl_sv_vcatpvfn_flags (my_perl=my_perl@entry=0xb6ca1020, sv=sv@entry=0xb6c9ea40, pat=pat@entry=0xb6e87e48 "%s: %: panic: %s%s%s\n", patlen=patlen@entry=0x15, args=<optimized out>,
    args@entry=0xbefffbe0, svargs=<optimized out>, svargs@entry=0xb6e76764 <Perl_vmess+84>, sv_count=<optimized out>, sv_count@entry=0xbefffbe0, maybe_tainted=<optimized out>,
    maybe_tainted@entry=0x0, flags=<optimized out>, flags@entry=0x0) at sv.c:12669
#2  0xb6e4984c in Perl_sv_vsetpvfn (my_perl=my_perl@entry=0xb6ca1020, sv=sv@entry=0xb6c9ea40, pat=pat@entry=0xb6e87e48 "%s: %: panic: %s%s%s\n", patlen=0x15, args=args@entry=0xbefffbe0,
    svargs=svargs@entry=0x0, sv_count=sv_count@entry=0x0, maybe_tainted=maybe_tainted@entry=0x0) at sv.c:11295
#3  0xb6e76764 in Perl_vmess (my_perl=my_perl@entry=0xb6ca1020, pat=0xb6e87e48 "%s: %: panic: %s%s%s\n", pat@entry=0xb6ca1020 "`\300\377\266", args=0xbefffbe0, args@entry=0xbefffbc0) at util.c:1684
#4  0xb6e75ee0 in Perl_vcroak (my_perl=my_perl@entry=0xb6ca1020, pat=pat@entry=0xb6ca1020 "`\300\377\266", args=args@entry=0xbefffbc0) at util.c:1899
#5  0xb6e76af8 in Perl_croak (my_perl=my_perl@entry=0xb6ca1020, pat=0xb6e87e48 "%s: %: panic: %s%s%s\n") at util.c:1952
#6  0xb6d3e38c in Perl_locale_panic (msg=0xb6ffffb0 "'C.UTF-8;C;C;C;C;C' needs an '=' to split name=value\n", immediate_caller_line=immediate_caller_line@entry=0x5c8,
    higher_caller_file=<optimized out>, higher_caller_line=0x1001, higher_caller_line@entry=0xb6d40b98) at locale.c:1113
#7  0xb6d40a34 in S_parse_LC_ALL_string (my_perl=0xb6e880c8, my_perl@entry=0xb6ca1020, string=string@entry=0xb6fffcf0 "C.UTF-8;C;C;C;C;C", output=0xb6ffff98, output@entry=0xbefffc84,
    always_use_full_array=0x20, always_use_full_array@entry=0x1, panic_on_error=0x1, caller_line=0x1001, override=override_if_ignored) at locale.c:1480
#8  0xb6d40b98 in S_new_LC_ALL (my_perl=my_perl@entry=0xb6ca1020, lc_all=lc_all@entry=0xb6fffcf0 "C.UTF-8;C;C;C;C;C", force=force@entry=0x1) at locale.c:4090
#9  0xb6d439b8 in S_give_perl_locale_control (caller_line=0x23fd, lc_all_string=0xb6fffcf0 "C.UTF-8;C;C;C;C;C", my_perl=0xb6ca1020) at locale.c:8575
#10 Perl_init_i18nl10n (my_perl=0xb6ca1020, printwarn=printwarn@entry=0x1) at locale.c:9213
#11 0xb6cfc95c in perl_construct (my_perl=<optimized out>) at perl.c:464
#12 0x0001091c in main (argc=<optimized out>, argv=<optimized out>, env=<optimized out>) at perlmain.c:102
(gdb)

egorenar avatar Jul 04 '24 16:07 egorenar

Try to set LC_ALL=C and see if backtrace is same or it goes through. I am no expert in perl internals, that comes just from superfluus look at the text messages.

brada4 avatar Jul 04 '24 16:07 brada4

LC_ALL

Yes, i noticed that too, Perl seems to crash while parsing LC_ALL :rofl:

The problem disappears with export LC_ALL=C or export LC_ALL=en_US.UTF-8.

egorenar avatar Jul 04 '24 16:07 egorenar

I think something goes wrong in locale.c (generated file ???) of Perl

    /* diag_listed_as: panic: %s */
    Perl_croak(aTHX_ "%s: %" LINE_Tf ": panic: %s%s%s\n",
                     __FILE__, immediate_caller_line,
                     msg, errno_text, called_by);

and from handy.h

#define LINE_Tf  U32uf

It's a typical format string error. immediate_caller_line (0x5c8 in backtrace) is interpreted as %s.

I've never seen a C format string %U32uf :scream:

egorenar avatar Jul 04 '24 16:07 egorenar

Look what i found while re-compiling Perl:

locale.c: In function 'Perl_locale_panic':
locale.c:1089:37: warning: unknown conversion type character '\x0a' in format [-Wformat=]
 1089 |         called_by = Perl_form(aTHX_ "\nCalled by %s: %" LINE_Tf "\n",
      |                                     ^~~~~~~~~~~~~~~~~~~
locale.c:1089:66: note: format string is defined here
 1089 |         called_by = Perl_form(aTHX_ "\nCalled by %s: %" LINE_Tf "\n",
      |                                                                  ^~
locale.c:1089:37: warning: too many arguments for format [-Wformat-extra-args]
 1089 |         called_by = Perl_form(aTHX_ "\nCalled by %s: %" LINE_Tf "\n",
      |                                     ^~~~~~~~~~~~~~~~~~~
locale.c:1113:22: warning: unknown conversion type character ':' in format [-Wformat=]
 1113 |     Perl_croak(aTHX_ "%s: %" LINE_Tf ": panic: %s%s%s\n",
      |                      ^~~~~~~
locale.c:1113:39: note: format string is defined here
 1113 |     Perl_croak(aTHX_ "%s: %" LINE_Tf ": panic: %s%s%s\n",
      |                                       ^
locale.c:1113:22: warning: format '%s' expects argument of type 'char *', but argument 4 has type 'line_t' {aka 'long unsigned int'} [-Wformat=]
 1113 |     Perl_croak(aTHX_ "%s: %" LINE_Tf ": panic: %s%s%s\n",
      |                      ^~~~~~~
 1114 |                      __FILE__, immediate_caller_line,
      |                                ~~~~~~~~~~~~~~~~~~~~~
      |                                |
      |                                line_t {aka long unsigned int}
locale.c:1113:49: note: format string is defined here
 1113 |     Perl_croak(aTHX_ "%s: %" LINE_Tf ": panic: %s%s%s\n",
      |                                                ~^
      |                                                 |
      |                                                 char *
      |                                                %ld
locale.c:1113:22: warning: too many arguments for format [-Wformat-extra-args]
 1113 |     Perl_croak(aTHX_ "%s: %" LINE_Tf ": panic: %s%s%s\n",
      |                      ^~~~~~~
In file included from locale.c:383:
locale.c: In function 'S_bool_setlocale_2008_i':
locale.c:2571:39: warning: unknown conversion type character ')' in format [-Wformat=]
 2571 |         locale_panic_(Perl_form(aTHX_ "(called from %" LINE_Tf "):"
      |                                       ^~~~~~~~~~~~~~~~
perl.h:7525:56: note: in definition of macro 'locale_panic_via_'
 7525 | #define locale_panic_via_(m, f, l)  Perl_locale_panic((m), __LINE__, f, l)
      |                                                        ^
locale.c:2571:9: note: in expansion of macro 'locale_panic_'
 2571 |         locale_panic_(Perl_form(aTHX_ "(called from %" LINE_Tf "):"
      |         ^~~~~~~~~~~~~
locale.c:2571:54: note: format string is defined here
 2571 |         locale_panic_(Perl_form(aTHX_ "(called from %" LINE_Tf "):"
      |                                                      ^
locale.c:2571:39: warning: too many arguments for format [-Wformat-extra-args]
 2571 |         locale_panic_(Perl_form(aTHX_ "(called from %" LINE_Tf "):"
      |                                       ^~~~~~~~~~~~~~~~
perl.h:7525:56: note: in definition of macro 'locale_panic_via_'
 7525 | #define locale_panic_via_(m, f, l)  Perl_locale_panic((m), __LINE__, f, l)
      |                                                        ^
locale.c:2571:9: note: in expansion of macro 'locale_panic_'
 2571 |         locale_panic_(Perl_form(aTHX_ "(called from %" LINE_Tf "):"
      |         ^~~~~~~~~~~~~
locale.c: In function 'S_setlocale_failure_panic_via_i':
locale.c:3379:56: warning: spurious trailing '%' in format [-Wformat=]
 3379 |         proxy_text = Perl_form(aTHX_ "\nCalled via %s: %" LINE_Tf,
      |                                                        ^
locale.c:3379:38: warning: too many arguments for format [-Wformat-extra-args]
 3379 |         proxy_text = Perl_form(aTHX_ "\nCalled via %s: %" LINE_Tf,
      |                                      ^~~~~~~~~~~~~~~~~~~~
locale.c:3386:58: warning: spurious trailing '%' in format [-Wformat=]
 3386 |         proxy_text = Perl_form(aTHX_ "%s\nCalled via %s: %" LINE_Tf,
      |                                                          ^
locale.c:3386:38: warning: too many arguments for format [-Wformat-extra-args]
 3386 |         proxy_text = Perl_form(aTHX_ "%s\nCalled via %s: %" LINE_Tf,
      |                                      ^~~~~~~~~~~~~~~~~~~~~~

This is also interesting: https://github.com/Perl/perl5/pull/21956

egorenar avatar Jul 04 '24 16:07 egorenar

Okay, U32uf seems to be a Perl-specific format string specifier: https://perldoc.perl.org/5.37.3/perl5372delta#Internal-Changes. The above warnings can be ignored then.

egorenar avatar Jul 04 '24 16:07 egorenar

To me it seems that Perl_sv_vcatpvfn_flags doesn't support the format string specifier U32uf, and therefore, just skips it and goes straight for the next specifier which is %s, and attempts to interpret a line number as a string pointer :stuck_out_tongue_winking_eye:

egorenar avatar Jul 04 '24 17:07 egorenar

According to Perl's devs, OpenWrt's Perl package configuration is broken :disappointed: config.sh generation is outdated in OpenWrt and needs to be fixed for 5.40.

egorenar avatar Jul 04 '24 19:07 egorenar

The missing format string symbols have been a problem since perl 5.38, but apparently nobody noticed then.

mauke avatar Jul 04 '24 19:07 mauke

Helps to tag maintainer @pprindeville and recent commiter @esaaprillia

brada4 avatar Jul 04 '24 21:07 brada4

@esaaprillia

the perl package should be updated. I see many are outdated. but at that time I was too lazy to update everything. let the perl package maintainer update it

predators46 avatar Jul 06 '24 01:07 predators46

It might be useful to check how buildroot builds Perl: https://github.com/buildroot/buildroot/blob/3ebc7c69d56430c34eba4c869d1d4fe4d1e8de55/package/perl/perl.mk buildroot doesn't use custom config files. i wonder why OpenWrt needs all these custom configs. This will be a constant pain to keep in sync with upstream.

egorenar avatar Jul 06 '24 12:07 egorenar

Okay, i dropped outdated symbols from base.config and added new formats to architecture.config and got this error:

$ perl
locale.c: 1480: panic: 'C.UTF-8;C;C;C;C;C' needs an '=' to split name=value
; errno=0
Called by locale.c: 4097

The panic is thrown by perl's S_parse_LC_ALL_string().

        {   /* Get the category part when each component is the
             * 'category=locale' form */

            category_end = strchr(s, '=');

            /* The '=' terminates the category name.  If no '=', is improper
             * form */
            if (! category_end) {
                error = no_equals;
                goto failure;
            }

...

    switch (error) {
        case incomplete:
            msg = "doesn't list every locale category";
            display_start = string;
            break;
        case no_equals:
            msg = "needs an '=' to split name=value";
            break;

Any idea where C.UTF-8;C;C;C;C;C comes from ?

egorenar avatar Jul 06 '24 13:07 egorenar

Okay, found out that d_perl_lc_all_uses_name_value_pairs='define' is responsible for the above panic which was added in commit https://github.com/openwrt/packages/commit/c5b97d4d967fde1e090b90b547500abaa40cc925.

egorenar avatar Jul 06 '24 15:07 egorenar

Okay, found out that d_perl_lc_all_uses_name_value_pairs='define' is responsible for the above panic which was added in commit c5b97d4.

do you succeed in building perl if you change define to undef?

esaaprillia avatar Jul 06 '24 17:07 esaaprillia

Okay, found out that d_perl_lc_all_uses_name_value_pairs='define' is responsible for the above panic which was added in commit c5b97d4.

do you succeed in building perl if you change define to undef?

Sadly, not yet :( Tried different combinations. Need to look deeper into it.

egorenar avatar Jul 06 '24 17:07 egorenar

This might give the hint why:

d_perl_lc_all_category_positions_init (disparate_lc_all.U):
	This symbol, if defined, indicates that $lc_all_category_positions_init
	is valid

d_perl_lc_all_separator (disparate_lc_all.U):
	This symbol, if defined, indicates that $perl_lc_all_separator is valid

d_perl_lc_all_uses_name_value_pairs (disparate_lc_all.U):
	This symbol, if defined, indicates that the string returned by
	setlocale(LC_ALL, NULL) uses 'name=value;' pairs to indicate what each
	category's locale is when they aren't all set to the same locale.
	When not defined, the platform uses positional notation.

egorenar avatar Jul 06 '24 17:07 egorenar

Okay, this seems to help:

modified   lang/perl/files/base.config
@@ -365,9 +365,9 @@ d_open3='define'
 d_openat='define'
 d_pathconf='define'
 d_pause='define'
-d_perl_lc_all_category_positions_init='undef'
-d_perl_lc_all_separator='undef'
-d_perl_lc_all_uses_name_value_pairs='define'
+d_perl_lc_all_category_positions_init='define'
+d_perl_lc_all_separator='define'
+d_perl_lc_all_uses_name_value_pairs='undef'
 d_perl_otherlibdirs='undef'
 d_phostname='undef'
 d_pipe='define'
@@ -842,6 +842,8 @@ passcat='cat /etc/passwd'
 path_sep=':'
 perl=''
 perl5=''
+perl_lc_all_category_positions_init='{ 0, 1, 5, 2, 3, 4 }'
+perl_lc_all_separator='";"'
 perl_patchlevel=''
 perl_static_inline='static __inline__'
 perlpath='/usr/bin/perl'

egorenar avatar Jul 06 '24 17:07 egorenar

I made a branch for my Perl fixes: https://github.com/egorenar/openwrt-packages/tree/perl

egorenar avatar Jul 06 '24 18:07 egorenar

@egorenar

if the problem is solved please update perl. thanks

esaaprillia avatar Jul 06 '24 20:07 esaaprillia

@egorenar Does your branch is already compile-able?, getting the following when compiling with gcc 14 targeting x86_64 glibc :

In file included from /home/user/works/openwrt/staging_dir/toolchain-x86_64_gcc-14.1.0_glibc/include/features.h:503,
                 from /home/user/works/openwrt/staging_dir/toolchain-x86_64_gcc-14.1.0_glibc/include/sys/types.h:25,
                 from perl.h:1117,
                 from locale.c:383:
locale.c: In function 'Perl_init_i18nl10n':
perl.h:4280:36: error: negative width in bit-field '__error_if_negative'
 4280 | #  define STATIC_ASSERT_DECL(COND) static_assert(COND, #COND)
      |                                    ^~~~~~~~~~~~~
perl.h:4296:52: note: in expansion of macro 'STATIC_ASSERT_DECL'
 4296 | #define STATIC_ASSERT_STMT(COND)      STMT_START { STATIC_ASSERT_DECL(COND); } STMT_END
      |                                                    ^~~~~~~~~~~~~~~~~~
locale.c:8813:9: note: in expansion of macro 'STATIC_ASSERT_STMT'
 8813 |         STATIC_ASSERT_STMT(   C_ARRAY_LENGTH(lc_all_category_positions)
      |         ^~~~~~~~~~~~~~~~~~
make[3]: *** [Makefile:266: locale.o] Error 1

vortexilation avatar Jul 07 '24 08:07 vortexilation

@egorenar Does your branch is already compile-able?, getting the following when compiling with gcc 14 targeting x86_64 glibc :

In file included from /home/user/works/openwrt/staging_dir/toolchain-x86_64_gcc-14.1.0_glibc/include/features.h:503,
                 from /home/user/works/openwrt/staging_dir/toolchain-x86_64_gcc-14.1.0_glibc/include/sys/types.h:25,
                 from perl.h:1117,
                 from locale.c:383:
locale.c: In function 'Perl_init_i18nl10n':
perl.h:4280:36: error: negative width in bit-field '__error_if_negative'
 4280 | #  define STATIC_ASSERT_DECL(COND) static_assert(COND, #COND)
      |                                    ^~~~~~~~~~~~~
perl.h:4296:52: note: in expansion of macro 'STATIC_ASSERT_DECL'
 4296 | #define STATIC_ASSERT_STMT(COND)      STMT_START { STATIC_ASSERT_DECL(COND); } STMT_END
      |                                                    ^~~~~~~~~~~~~~~~~~
locale.c:8813:9: note: in expansion of macro 'STATIC_ASSERT_STMT'
 8813 |         STATIC_ASSERT_STMT(   C_ARRAY_LENGTH(lc_all_category_positions)
      |         ^~~~~~~~~~~~~~~~~~
make[3]: *** [Makefile:266: locale.o] Error 1

Yes, but i tested only with musl. I think perl_lc_all_category_positions_init='{ 0, 1, 5, 2, 3, 4 }' should be different for glibc.

egorenar avatar Jul 07 '24 09:07 egorenar

@vortexilation Try this for perl_lc_all_category_positions_init https://github.com/Perl/perl5/blob/b786e5e6e5e961082d2f48dac2a1f3ab69339b14/perl.h#L1239

egorenar avatar Jul 07 '24 09:07 egorenar

@egorenar Thanks, it compile-able now, but haven't tested functionalities wise.

Then you will also use perl_lc_all_category_positions_init for glibc as for musl?, if not how you overcome glibc and musl differences for base.config ?.

vortexilation avatar Jul 07 '24 09:07 vortexilation

Then you will also use perl_lc_all_category_positions_init for glibc as for musl?, if not how you overcome glibc and musl differences for base.config ?.

We have to put them into libc.config i think. There are conditionals for musl and glibc.

egorenar avatar Jul 07 '24 09:07 egorenar

musl


LC_ALL categories:

#define LC_CTYPE    0
#define LC_NUMERIC  1
#define LC_TIME     2
#define LC_COLLATE  3
#define LC_MONETARY 4
#define LC_MESSAGES 5

Perl's LC_ positions (locale_table.h):

#define LC_CTYPE    0
#define LC_NUMERIC  1
#define LC_COLLATE  2
#define LC_TIME     3
#define LC_MESSAGES   4
#define LC_MONETARY  5

perl_lc_all_category_positions_init maps musl category positions to Perl's category positions.

perl_lc_all_category_positions_init='{ 0, 1, 3, 2, 5, 4 }'

glibc


LC_ALL categories:

#define LC_CTYPE		 0
#define LC_NUMERIC		 1
#define LC_TIME		 2
#define LC_COLLATE		 3
#define LC_MONETARY		 4
#define LC_MESSAGES		 5
#define LC_PAPER		 7
#define LC_NAME		 8
#define LC_ADDRESS		 9
#define LC_TELEPHONE		10
#define LC_MEASUREMENT	11
#define LC_IDENTIFICATION	12

Perl's LC_ positions (locale_table.h):

#define LC_CTYPE    0
#define LC_NUMERIC  1
#define LC_COLLATE  2
#define LC_TIME     3
#define LC_MESSAGES   4
#define LC_MONETARY  5
#define LC_ADDRESS  6
#define LC_IDENTIFICATION  7
#define LC_MEASUREMENT  8
#define LC_PAPER  9
#define LC_TELEPHONE 10
#define LC_NAME  11

perl_lc_all_category_positions_init maps glibc category positions to Perl's category positions.

perl_lc_all_category_positions_init='{ 0, 1, 3, 2, 5, 4, -1, 9, 11, 6, 10, 8, 7 }' Still unsure about mapping, need to double check everything and then test it.

egorenar avatar Jul 07 '24 11:07 egorenar

A simple program to obtain all LC_* values:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main()
{
#ifdef LC_CTYPE
        fprintf(stdout, "LC_CTYPE: %d\n", LC_CTYPE);
#endif
#ifdef LC_NUMERIC
        fprintf(stdout, "LC_NUMERIC: %d\n", LC_NUMERIC);
#endif
#ifdef LC_TIME
        fprintf(stdout, "LC_TIME: %d\n", LC_TIME);
#endif
#ifdef LC_COLLATE
        fprintf(stdout, "LC_COLLATE: %d\n", LC_COLLATE);
#endif
#ifdef LC_MONETARY
        fprintf(stdout, "LC_MONETARY: %d\n", LC_MONETARY);
#endif
#ifdef LC_MESSAGES
        fprintf(stdout, "LC_MESSAGES: %d\n", LC_MESSAGES);
#endif
#ifdef LC_PAPER
        fprintf(stdout, "LC_PAPER: %d\n", LC_PAPER);
#endif
#ifdef LC_NAME
        fprintf(stdout, "LC_NAME: %d\n", LC_NAME);
#endif
#ifdef LC_ADDRESS
        fprintf(stdout, "LC_ADDRESS: %d\n", LC_ADDRESS);
#endif
#ifdef LC_TELEPHONE
        fprintf(stdout, "LC_TELEPHONE: %d\n", LC_TELEPHONE);
#endif
#ifdef LC_MEASUREMENT
        fprintf(stdout, "LC_MEASUREMENT: %d\n", LC_MEASUREMENT);
#endif
#ifdef LC_IDENTIFICATION
        fprintf(stdout, "LC_IDENTIFICATION: %d\n", LC_IDENTIFICATION);
#endif
#ifdef LC_SYNTAX
        fprintf(stdout, "LC_SYNTAX: %d\n", LC_SYNTAX);
#endif
#ifdef LC_TOD
        fprintf(stdout, "LC_TOD: %d\n", LC_TOD);
#endif

        return 0;
}

I verified the above LC_* values on musl and glibc.

egorenar avatar Jul 07 '24 13:07 egorenar