bashki, ez mi ez?

(gdb) bt
#0  0x000000010007e15c in expand_word_internal ()
#1  0x000000010007c8e0 in parameter_brace_expand ()
#2  0x00000001000791ac in parameter_brace_substring ()
#3  0x0000000100079304 in parameter_brace_substring ()
#4  0x0000000100079d3c in pos_params_pat_subst ()

Hozzászólások

Szerkesztve: 2022. 01. 27., cs – 13:47

Debuggal újrafordítva kicsit más:

(gdb) bt
#0  0x00000001000bf238 in rl_signal_handler (sig=-1) at signals.c:163
#1  0x00000000000049f4 in ?? ()

(gdb) l signals.c:163
158     }
159     
160     static RETSIGTYPE
161     rl_signal_handler (sig)
162          int sig;
163     {
164       if (_rl_interrupt_immediately)
165         {
166           _rl_interrupt_immediately = 0;
167           _rl_handle_signal (sig);

(gdb) disass $pc-16,$pc+16
Dump of assembler code from 0x1000bf228 to 0x1000bf248:
   0x00000001000bf228 <_rl_signal_handler+196>: mulli   r24,r0,0
   0x00000001000bf22c <rl_signal_handler+0>:    mflr    r0
   0x00000001000bf230 <rl_signal_handler+4>:    std     r0,16(r1)
   0x00000001000bf234 <rl_signal_handler+8>:    std     r31,-8(r1)
=> 0x00000001000bf238 <rl_signal_handler+12>:   stdu    r1,-128(r1)
   0x00000001000bf23c <rl_signal_handler+16>:   mr      r31,r1
   0x00000001000bf240 <rl_signal_handler+20>:   mr      r9,r3
   0x00000001000bf244 <rl_signal_handler+24>:   stw     r9,176(r31)
End of assembler dump.

A hiba reprodukálása:

# mc
Ctrl+O
# su - teve
$ pwd
Ctrl+O
F10

A truss szerint kap 48759 darab SIGHUP-ot a szegény, azután tényleg megáll, core-fájlt írva.

root@shodan:~# mc  #^o

root@shodan:~# su - nyos
nyos@shodan:~$ pwd
/home/nyos
nyos@shodan:~$  #^o, F10, enter
root@shodan:~#

64 bites Ubuntu, teve user mondjuk nincs rajta, lehet, hogy az a gond. :)

When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin

gdb-vel nézve némi ciklikusságot vélek felfedezni, talán olyasmi lehet, hogy a SIGHUP hatására nekikezd valami gyors műveletbe, ami sajnos lassúnak bizonyul.


#0  0x0900000000007250 in ioctl () from /usr/lib/libc.a(shr_64.o)
#1  0x09000000001840d8 in tcsetattr () from /usr/lib/libc.a(shr_64.o)
#2  0x00000001000cd6ac in _set_tty_settings (tty=0, tiop=0x110015858 <_rltty.bss_+40>) at rltty.c:476
#3  0x00000001000cd734 in set_tty_settings (tty=0, tiop=0x110015858 <_rltty.bss_+40>) at rltty.c:490
#4  0x00000001000cdd18 in rl_deprep_terminal () at rltty.c:688
#5  0x00000001000bfce4 in rl_cleanup_after_signal () at signals.c:536
#6  0x00000001000bf418 in _rl_handle_signal (sig=1) at signals.c:232
#7  0x00000001000bf1e8 in _rl_signal_handler (sig=1) at signals.c:155
#8  0x00000001000bff20 in _rl_release_sigint () at signals.c:610
#9  0x00000001000cdd28 in rl_deprep_terminal () at rltty.c:690
#10 0x00000001000bfce4 in rl_cleanup_after_signal () at signals.c:536
Szerkesztve: 2022. 01. 27., cs – 16:37

A SIGHUP előtt így állunk:

#0  0x090000000002e834 in read () from /usr/lib/libc.a(shr_64.o)
#1  0x00000001000c15c4 in rl_getc (stream=0x9001000a0002038 <_iob>) at input.c:488
#2  0x00000001000c14e8 in rl_read_key () at input.c:462
#3  0x00000001000d884c in readline_internal_char () at readline.c:564
#4  0x00000001000d8a78 in readline_internal_charloop () at readline.c:629
#5  0x00000001000d8b00 in readline_internal () at readline.c:643
#6  0x00000001000d80a0 in readline (prompt=0x110048850 "projects@p520ora:/home/projects$ ") at readline.c:369
#7  0x000000010005072c in yy_readline_get () at ./parse.y:1448
#8  0x000000010005089c in yy_readline_get () at ./parse.y:1479
#9  0x000000010005059c in yy_getc () at ./parse.y:1382
#10 0x000000010005207c in shell_getc (remove_quoted_newline=1) at ./parse.y:2283
#11 0x0000000100053eb4 in read_token (command=0) at ./parse.y:3050
#12 0x0000000100052f30 in yylex () at ./parse.y:2637
#13 0x000000010004c910 in yyparse () at y.tab.c:1830
#14 0x0000000100140be0 in parse_command () at eval.c:238
#15 0x0000000100140d74 in read_command () at eval.c:282
#16 0x000000010014082c in reader_loop () at eval.c:145
#17 0x0000000100001538 in main (argc=1, argv=0xffffffffffffcd8, env=0xffffffffffffce8) at shell.c:756

A SIGHUP hatására ő aktíválódik:


160     static RETSIGTYPE
161     rl_signal_handler (sig)
162          int sig;
163     {
164       if (_rl_interrupt_immediately)
165         {
166           _rl_interrupt_immediately = 0;
167           _rl_handle_signal (sig);
168         }
169       else
170         _rl_caught_signal = sig;
171     
172       SIGHANDLER_RETURN;
173     }

Utána pedig ez:


460             {
461               if (rl_get_char (&c) == 0)
462                 c = (*rl_getc_function) (rl_instream);
463     /* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */
464               RL_CHECK_SIGNALS ();
465             }
466         }

Bővebben:


#define RL_CHECK_SIGNALS() \
        do { \
          if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \
        } while (0)

Értelemszerűen a _rl_signal_handler meghívja a _rl_handle_signal-t.

bash-4.4.18-ra frissítve a hiba megmaradt, illetve esetlegessé vált: vagy lesz core fájl, vagy nem

Szerkesztve: 2022. 01. 27., cs – 20:02

Van itt egy gyanusított (a debukiirasokat én tettem bele):


static int _set_tty_settings (int tty, TIOTYPE *tiop)
{
   fprintf(stderr,"rltty.c:_set_tty_settings begin\n");
   while (SETATTR (tty, tiop) < 0) {
      int e= errno;
      fprintf(stderr,"rltty.c:SETATTR failed errno=%d: %s\n",
          e, strerror(e));
      if (e != EINTR)
          return -1;
      errno = 0;
    }
    fprintf(stderr,"rltty.c:_set_tty_settings end\n");
    return 0;
}

Mindig azon merengek, hogy ki és milyen indíttatásból finanszírozza ezt a debug maratont?

Régebben azt gondoltam, hogy valami nagy mamut banknál vagy, ahol kritikus még lélegeztetőgépen tartani az AIX vasat...de  képátméretezés és tsai tutira nem banki közeg.

Ha pedig pet project, akkor vmit nagyon jól csinálsz/én valamit nagyon rosszul :D

Minden tiszteletem a tiéd, mindig van egy ilyen "IT l’art pour l’art" gondolatom amikor nézem a blogodat...nehéz elválasztani, hogy borzongást vagy ámulatot érzek :)

"The only valid measurement of code quality: WTFs/min"

Szerkesztve: 2022. 01. 28., p – 09:20

Pillanatnyilag az a gondolatom, hogy tényleg végtelen ciklus van a 'readline'-ban, ami akkor jelentkezik, ha megsorozzák végtelen+1 SIGHUP-pal. Talán ez a komment is kapcsolatban van ezzel:


    101 /* Private variables. */
    102 int _rl_interrupt_immediately = 0;
    103 int volatile _rl_caught_signal = 0;
    104 /* should be sig_atomic_t, but that requires including <signal.h> everywhere */

Azzal a különbséggel, hogy a _rl_interrupt_immediatly -t használja a signal-handler az is lehetne sig_atomic_t. Bár igaz, hogy sosem írja senki, mindig nulla.

Mondjuk jó kérdés, hogy konkrétan ki DOS-ol meg minket ennyi SIGHUP-pal? Ilyen lenne a hívási lánc: bash->mc->bash->bash(user)

%PID:      16973974   PPID:  14942356   NOW: 2022-01-28.09:27:28
%USERID:   root       GROUP: system     ELAPSED:           15:25
%STATION:  pts/1      PRI:   60 20      CPU-USED:       00:00:00
%SIZE(KB): 1328       %MEM:  0.0        %CPU:  0.0
%STATE:    A Active                     WCHAN: -
%CMD:      bash

%PID:      5701860    PPID:  16973974   NOW: 2022-01-28.09:25:41
%USERID:   root       GROUP: system     ELAPSED:           02:25
%STATION:  pts/1      PRI:   60 20      CPU-USED:       00:00:00
%SIZE(KB): 3052       %MEM:  0.0        %CPU:  0.0
%STATE:    A Active                     WCHAN: -
%CMD:      mc

%PID:      16646342   PPID:  5701860    NOW: 2022-01-28.09:25:41
%USERID:   root       GROUP: system     ELAPSED:           02:25
%STATION:  pts/5      PRI:   60 20      CPU-USED:       00:00:00
%SIZE(KB): 1312       %MEM:  0.0        %CPU:  0.0
%STATE:    A Active                     WCHAN: -
%CMD:      bash -rcfile .bashrc

%PID:      11075678   PPID:  16646342   NOW: 2022-01-28.09:25:41
%USERID:   teve       GROUP: teve       ELAPSED:           02:19
%STATION:  pts/5      PRI:   60 20      CPU-USED:       00:00:00
%SIZE(KB): 1544       %MEM:  0.0        %CPU:  0.0
%STATE:    A Active                     WCHAN: -
%CWD:      /home/teve/
%CMD:      -bash

Esetleg bepróbálkozom egy ilyennel:

sed_repl 's/_rl_caught_signal = sig;/_rl_caught_signal = sig; if (sig==SIGHUP) signal(sig, SIG_IGN);/' lib/readline/signals.c

Azt most komolyan állítod, hogy ez a kék rózsa olyan ősrégi, hogy signal(2) van, de sigaction(2) és társai pediglen nincsenek, Mert ez a signal-handlerben újra elkapjuk a signal-t játék olyan erőst 80-as évek eleje fíling. Már ha jól tippelem SVR3-ban és BSD 4.3-Tahoe-ban is volt ennél modernebb megszakításkezelés.

Én biztos inkább ott keresném a megoldást, hogy valahonnan nem a múlt évezredből emlékül itt ragadt módon próbálnám meg a megszakításkezelést intézni - nem csak a tegnapi Linuxon, hanem a tegnapelőtti AIX-en is.

Hogyne lenne sigaction(2)! Speciel egy sima letiltáshoz elég a signal(2). Különösen, hogy egysoros javítást (sed) próbáltam találni. [Mármint nem az a cél, hogy egyszer javítsam+fordítsam+telepítsem, hanem hogy készítsek egy scriptet, ami configure-tól `make install`-ig mindent tartalmaz, beleértve az esetleges foldozásokat.]

Ha találgatnom kellene, azt mondanám, hogy a szignál-handler "belsejét" kiszervezték egy külön rutinba, a handler csak annyit tesz, hogy beteszi egy globális változóba a signal számát. Ugye normálisan nem záporoznak úgy a szignálok, hogy ebből gond legyen.

Az is valószínű, hogy azóta a readline is ment előre, csak különféle technikai korlátok miatt a bash-4.3/4.4 beépített readline-ját használom.