Irssi: Segfault при отправке большого сообщения

Созданный на 30 нояб. 2017  ·  47Комментарии  ·  Источник: irssi/irssi

Когда я пытаюсь распечатать всю христианскую библию на канале (с отключенной защитой от флуда на сервере и клиенте), irssi частично завершает работу.

Если я использую /exec -out cat bible.txt для печати Библии, irssi segfaults. Если я использую другую команду, которая разбивает файл на ~ 10 кусков и засыпает на две секунды между печатаемыми кусками, все будет успешно отправлено.

Действия по воспроизведению:

  • запустите указанную выше команду с файлом примерно того же размера, что и вся Библия.

Ожидаемое поведение:

  • Вся Библия отправлена ​​на канал
  • irssi не имеет ошибок

Фактическое поведение:

  • Часть Библии отправлена ​​на канал
  • irssi segfaults

Я использую irssi 1.0.5-1 (20171020 1715) из тестовых репозиториев debian, но эта проблема сохраняется в нескольких версиях.

Пожалуйста, дайте мне знать, если есть дополнительная информация, которую мне было бы полезно предоставить.

WIP bug memory

Самый полезный комментарий

Ах да, христианский официант.

Удалось воспроизвести аварию. Спасибо!

Краткая версия (точки останова на server_connect_init , server->connection_lost = TRUE , glog_func , server_disconnect ) уже почти полностью рассказывает всю историю. Журнал большего размера с трассировкой: log.txt

0x00007f095e233f30 in _start () from /lib64/ld-linux-x86-64.so.2
(rr) c
Continuing.

Breakpoint 9, server_connect_init (server=0x558ecd4099a0) at servers.c:357
357             g_return_if_fail(server != NULL);
(rr)
Continuing.
[New Thread 29950.29980]

Thread 1 hit Breakpoint 12, glog_func (log_domain=0x0, log_level=G_LOG_LEVEL_WARNING, message=0x558ecd88a9d0
    "Dropping some data on an outgoing connection") at fe-common-core.c:253
253             switch (log_level) {
(rr)
Continuing.

Thread 1 hit Breakpoint 11, irc_server_send_data (server=0x558ecd4099a0, data=<optimized out>, len=94) at irc-servers.c:529
529                     server->connection_lost = TRUE;
(rr)
Continuing.

Thread 1 hit Breakpoint 4, server_disconnect (server=0x558ecd4099a0) at servers.c:462
462     {
(rr)
Continuing.

Thread 1 hit Breakpoint 12, glog_func (log_domain=0x7f095d55efc5 "GLib", log_level=G_LOG_LEVEL_CRITICAL, message=0x558ecd5876b0
    "g_hash_table_lookup: assertion 'hash_table != NULL' failed") at fe-common-core.c:253
253             switch (log_level) {
(rr)
Continuing.

Thread 1 hit Breakpoint 12, glog_func (log_domain=0x7f095d55efc5 "GLib", log_level=G_LOG_LEVEL_CRITICAL, message=0x558ecd9f0200
    "g_hash_table_lookup: assertion 'hash_table != NULL' failed") at fe-common-core.c:253
253             switch (log_level) {
(rr)
Continuing.

[...]

Thread 1 received signal SIGSEGV, Segmentation fault.
flood_newmsg (server=0x558ecd4099a0, level=4, nick=0x558ecd40acd1 "|\237U",
    host=0x558ecd40acd9 "ble_lookup: assertion 'hash_table != NULL' failed",
    target=0x558ecd594720 "#christianity") at flood.c:196
196             flood = g_hash_table_lookup(mserver->floodlist, nick);
(rr)

server->connection_lost = TRUE происходит на несколько кадров стека выше того же пути, что и Dropping some data on an outgoing connection

Входящее сообщение, отправленное со второго irssi, обрабатывается sig_public nickcolor.pl, который выполняет $server->command(...) , который вызывает parse_command который замечает server->connection_lost и отключается.

server_disconnect еще не убивает его, но излучает сигнал "сервер отключен", который очищает такие вещи, как server->isupport что приводит к этим сообщениям хэш-таблицы NULL и вызывает flood_deinit_server который удаляет данные модуля этого флуда.

Поэтому, когда он доходит до flood_newmsg он делает mserver = MODULE_DATA(server); , не может его найти и поэтому возвращает NULL, и mserver->floodlist вылетает.

Я думаю, что здесь нет никакого смысла после бесплатного использования, что довольно круто. К моменту сбоя refcount сервера равен 1, там все хорошо. После того, как irc-часть сервера заполнена NULL, вызывается лишь несколько вещей.

Все 47 Комментарий

У меня работает с использованием ftp://ftp.cs.princeton.edu/pub/cs226/textfiles/bible.txt (3,9 МБ)

Получить обратную трассировку https://wiki.debian.org/HowToGetABacktrace

@dequis

#0  flood_newmsg (server=0x555555b96a10, level=4, nick=0x5555559b6c41 "iled", host=0x5555559b6c4a "", target=0x555556f25600 "#test") at flood.c:196
#1  0x00005555555e053f in flood_privmsg (server=0x555555b96a10, data=<optimized out>, nick=0x5555559b6c41 "iled", addr=0x5555559b6c4a "") at flood.c:255
#2  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x555555870350, params=params@entry=4, va=va@entry=0x7fffffffe1d0, first_hook=<optimized out>) at signals.c:242
#3  0x00005555555fa60d in signal_emit (signal=<optimized out>, params=params@entry=4) at signals.c:286
#4  0x00005555555c0858 in irc_server_event (server=0x555555b96a10, line=0x5555559b6c6c "", nick=0x5555559b6c41 "iled", address=0x5555559b6c4a "") at irc.c:308
#5  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x5555558743d0, params=params@entry=4, va=va@entry=0x7fffffffe390, first_hook=<optimized out>) at signals.c:242
#6  0x00005555555fa6e5 in signal_emit_id (signal_id=<optimized out>, params=4) at signals.c:304
#7  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x55555586ed00, params=params@entry=2, va=va@entry=0x7fffffffe500, first_hook=<optimized out>) at signals.c:242
#8  0x00005555555fa6e5 in signal_emit_id (signal_id=<optimized out>, params=params@entry=2) at signals.c:304
#9  0x00005555555c09b5 in irc_parse_incoming (server=0x555555b96a10) at irc.c:383
#10 0x00005555555eb84d in irssi_io_invoke (source=<optimized out>, condition=<optimized out>, data=<optimized out>) at misc.c:55
#11 0x00007ffff6ba8dd5 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#12 0x00007ffff6ba91a0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#13 0x00007ffff6ba922c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#14 0x000055555557701f in main (argc=<optimized out>, argv=<optimized out>) at irssi.c:335

Получил 3 Царств 11:43 до крушения

Какое сообщение о выходе видят на канале другие люди?

Это тоже происходит с чистым профилем? irssi --home=~/.irssi-test/

Какое сообщение о выходе видят на канале другие люди?

Через несколько секунд после остановки сообщений на канал отправляется irssi segfaults и -!- test [[email protected]] has quit [Connection closed]

Это тоже происходит с чистым профилем?

Благодаря полностью чистому профилю защита от флуда не позволяет мне попробовать это. После отключения защиты от флуда я отправляю все это целиком, но только определенная его часть действительно отображается для других в канале (так же, как это происходило раньше), но через несколько секунд вместо segfaulting соединение просто закрывается. Irssi сообщает «Соединение потеряно», и на канале отображается то же сообщение о выходе, что и при сбое перехода (был завершен [Соединение закрыто]).

Я удивлен, что поведение изменилось, поскольку единственными реальными изменениями в моей конфигурации, помимо отключения защиты от флуда, являются цветовые схемы и псевдонимы.

Хорошо, это интересно. Для справки, я тестирую это с «тестовым» клиентом, из которого я фактически отправляю текст Библии, а другой клиент («просматривающий» клиент) присоединяется к тому же каналу, на котором я наблюдаю извне.

Когда я отправляю текст Библии в тестовом клиенте, я вижу, что все это отправляется на канал в течение секунды или двух.
В просматривающем клиенте я вижу, как текст течет быстро в течение нескольких секунд, а затем резко останавливается в какой-то момент задолго до конца текста.

На этом этапе я обычно жду несколько секунд, а затем клиент выходит из строя или отключается (в зависимости от конфигурации), но я просто понял, что это всегда совпадает с тем, что кто-то другой в канале говорит или делает что-то, что отправляется на тестовый клиент . В случае исходной конфигурации, в которой происходит segfaulting, любой, кто говорит что-либо в канале или выходит из канала после остановки текста, вызывает segfault. Со свежим конфигом вызывает отключение.

Вот еще один след

#0  flood_newmsg (server=0x555555b96c40, level=4, nick=0x5555559b6c41 "", host=0x5555559b6c4b "table_lookup: assertion 'hash_table != NULL' failed", 
    target=0x555555d6bf80 "#test") at flood.c:196
#1  0x00005555555e053f in flood_privmsg (server=0x555555b96c40, data=<optimized out>, nick=0x5555559b6c41 "", 
    addr=0x5555559b6c4b "table_lookup: assertion 'hash_table != NULL' failed") at flood.c:255
#2  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x555555870350, params=params@entry=4, va=va@entry=0x7fffffffe1d0, first_hook=<optimized out>) at signals.c:242
#3  0x00005555555fa60d in signal_emit (signal=<optimized out>, params=params@entry=4) at signals.c:286
#4  0x00005555555c0858 in irc_server_event (server=0x555555b96c40, line=0x5555559b6c6b "ble != NULL' failed", nick=0x5555559b6c41 "", 
    address=0x5555559b6c4b "table_lookup: assertion 'hash_table != NULL' failed") at irc.c:308
#5  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x5555558743d0, params=params@entry=4, va=va@entry=0x7fffffffe390, first_hook=<optimized out>) at signals.c:242
#6  0x00005555555fa6e5 in signal_emit_id (signal_id=<optimized out>, params=4) at signals.c:304
#7  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x55555586ed00, params=params@entry=2, va=va@entry=0x7fffffffe500, first_hook=<optimized out>) at signals.c:242
#8  0x00005555555fa6e5 in signal_emit_id (signal_id=<optimized out>, params=params@entry=2) at signals.c:304
#9  0x00005555555c09b5 in irc_parse_incoming (server=0x555555b96c40) at irc.c:383
#10 0x00005555555eb84d in irssi_io_invoke (source=<optimized out>, condition=<optimized out>, data=<optimized out>) at misc.c:55
#11 0x00007ffff6ba8dd5 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#12 0x00007ffff6ba91a0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#13 0x00007ffff6ba922c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#14 0x000055555557701f in main (argc=<optimized out>, argv=<optimized out>) at irssi.c:335

загружены ли какие-либо скрипты, которые могут объяснить разницу между конфигурациями или любые другие различия в конфигурациях?

какой клиент вылетает, тот кто библию шлет?

загружены ли какие-либо скрипты, которые могут объяснить разницу между конфигурациями или любые другие различия в конфигурациях?

Единственные загруженные мной скрипты - это несколько простых вещей, которые регистрируют команду. Ничего, что слушает все строки, входящие или исходящие, как я ожидал бы, что-то делать, если это вызывает segfault из большого текста. Единственные различия в конфигурациях также очень незначительны - всего несколько псевдонимов и цветовая схема. Когда у меня будет время позже, я попробую по крупицам включить что-то в моей обычной конфигурации в новой конфигурации и посмотреть, в какой момент она начнет давать сбой.

какой клиент вылетает, тот кто библию шлет?

да

Странная вещь в вашей трассировке заключается в том, что она дает сбой в каком-то входящем сообщении, поэтому это не должно быть связано с отправкой вами Библии. (но, может быть, эта отправка где-то вызывает повреждение памяти? Просто случайные предположения от меня ..)

Вы пробуете это с привязкой к библии?

у вас есть возможность получить захват сетевого трафика с помощью WireShark до его сбоя?

#4  0x00005555555c0858 in irc_server_event (server=0x555555b96c40, line=0x5555559b6c6b "ble != NULL' failed", nick=0x5555559b6c41 "", 
    address=0x5555559b6c4b "table_lookup: assertion 'hash_table != NULL' failed") at irc.c:308

уже не выглядит как реальная строка, которая должна поступать с IRC-сервера

если вы перейдете к первому кадру (f 0) и серверу p *, сохранится ли запись сервера? вы также можете попробовать показать нам bt full

странная вещь в вашей обратной трассировке - это то, что он вылетает в каком-то входящем сообщении

Да, это всегда первое входящее сообщение после того, как перестает отправляться библейский текст.

Вы пробуете это с привязкой к библии?

Я не думаю, что это одна и та же Библия, но они почти одинакового размера, и это всего лишь обычный текст в формате ascii.

если вы перейдете к первому кадру (f 0) и серверу p *, сохранится ли запись сервера?

(gdb) p *server
$1 = {type = 716, chat_type = 66, refcount = 1, connrec = 0x555555ab3680, connect_time = 1512491572, real_connect_time = 1512491574, tag = 0x555555c86b30 "test", 
  nick = 0x555555ccdde0 "test", connected = 1, disconnected = 1, connection_lost = 1, session_reconnect = 0, no_reconnect = 0, handle = 0x0, readtag = -1, connect_pipe = {0x0, 0x0}, 
  connect_tag = -1, connect_pid = 2281, rawlog = 0x555555c858e0, module_data = 0x555555a6a060, version = 0x555555ab4570 "InspIRCd-2.2", away_reason = 0x0, last_invite = 0x0, 
  server_operator = 1, usermode_away = 0, banned = 0, dns_error = 0, lag_sent = {tv_sec = 0, tv_usec = 0}, lag_last_check = 1512491575, lag = 132, channels = 0x0, queries = 0x0, 
  channels_join = 0x5555555c1980 <irc_channels_join>, isnickflag = 0x5555555c8670 <isnickflag_func>, ischannel = 0x5555555c9410 <ischannel_func>, 
  get_nick_flags = 0x5555555c6db0 <get_nick_flags>, send_message = 0x5555555c90e0 <send_message>, split_message = 0x5555555c8950 <split_message>, 
  channel_find_func = 0x5555555c1740 <irc_channel_find_server>, query_find_func = 0x5555555c8490 <irc_query_find>, mask_match_func = 0x0, nick_match_msg = 0x0, redirects = 0x0, 
  redirect_queue = 0x0, redirect_next = 0x0, redirect_active = 0x0, last_nick = 0x555555d6bcc0 "+i", real_address = 0x0, usermode = 0x0, wanted_usermode = 0x0, userhost = 0x0, 
  channels_formed = 30, whois_found = 0, whowas_found = 0, emode_known = 1, no_multi_mode = 0, no_multi_who = 0, one_endofwho = 0, disable_lag = 0, nick_collision = 0, motd_got = 1, 
  isupport_sent = 1, cap_complete = 1, sasl_success = 0, max_kicks_in_cmd = 1, max_modes_in_cmd = 20, max_whois_in_cmd = 4, max_msgs_in_cmd = 20, cap_supported = 0x0, 
  cap_active = 0x0, cap_queue = 0x0, sasl_buffer = 0x0, sasl_timeout = 0, cmdcount = 57070, cmdqueue = 0x0, wait_cmd = {tv_sec = 0, tv_usec = 346171}, last_cmd = {
    tv_sec = 1512491613, tv_usec = 92250}, max_cmds_at_once = 5, cmd_queue_speed = 0, max_query_chans = 1, idles = 0x0, ctcpqueue = 0x0, knockoutlist = 0x0, splits = 0x0, 
  split_servers = 0x0, rejoin_channels = 0x0, chanqueries = 0x0, isupport = 0x0, modes = {{func = 0x0, prefix = 0 '\000'} <repeats 65 times>, {func = 0x5555555cee90 <modes_type_d>, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x0, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555ce3f0 <modes_type_a>, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x0, 
      prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555cebb0 <modes_type_prefix>, 
      prefix = 33 '!'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555ce3f0 <modes_type_a>, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555ce3f0 <modes_type_a>, prefix = 0 '\000'}, {func = 0x0, 
      prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555cebb0 <modes_type_prefix>, prefix = 37 '%'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {
      func = 0x0, prefix = 0 '\000'}, {func = 0x5555555ce950 <modes_type_b>, prefix = 0 '\000'}, {func = 0x5555555ce8d0 <modes_type_c>, prefix = 0 '\000'}, {
      func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x5555555cebb0 <modes_type_prefix>, 
      prefix = 64 '@'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {
      func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, 
    {func = 0x5555555cebb0 <modes_type_prefix>, prefix = 43 '+'}, {func = 0x5555555ce3f0 <modes_type_a>, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'}, {func = 0x0, 
      prefix = 0 '\000'}, {func = 0x5555555cee90 <modes_type_d>, prefix = 0 '\000'}, {func = 0x0, prefix = 0 '\000'} <repeats 133 times>}, 
  prefix = '\000' <repeats 33 times>, "Y\000\000\000h\000\000\000\000\000v", '\000' <repeats 20 times>, "o", '\000' <repeats 190 times>, 
  nick_comp_func = 0x5555555c7ec0 <irc_nickcmp_rfc1459>}

вы также можете попробовать показать нам bt full

(gdb) bt full
#0  flood_newmsg (server=0x555555b96ae0, level=4, nick=0x5555559b6c81 "le_lookup: assertion 'hash_table != NULL' failed", 
    host=0x5555559b6c8c "assertion 'hash_table != NULL' failed", target=0x555556b0d0c0 "#test") at flood.c:196
        mserver = <optimized out>
        flood = <optimized out>
        rec = <optimized out>
        now = <optimized out>
        ttime = <optimized out>
        times = <optimized out>
        tnext = <optimized out>
        __func__ = "flood_newmsg"
#1  0x00005555555e053f in flood_privmsg (server=0x555555b96ae0, data=<optimized out>, nick=0x5555559b6c81 "le_lookup: assertion 'hash_table != NULL' failed", 
    addr=0x5555559b6c8c "assertion 'hash_table != NULL' failed") at flood.c:255
        params = 0x555556b0d0c0 "#test"
        target = 0x555556b0d0c0 "#test"
        text = 0x555556b0d0cc "no one will see this"
        level = 4
        nick = 0x5555559b6c81 "le_lookup: assertion 'hash_table != NULL' failed"
        server = 0x555555b96ae0
        data = <optimized out>
        addr = 0x5555559b6c8c "assertion 'hash_table != NULL' failed"
#2  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x555555870350, params=params@entry=4, va=va@entry=0x7fffffffe1f0, first_hook=<optimized out>) at signals.c:242
        arglist = {0x555555b96ae0, 0x555555d7c0ce, 0x5555559b6c81, 0x5555559b6c8c, 0x0, 0x0}
        prev_emitted_signal = 0x5555558743d0
        hook = 0x555555877000
        prev_emitted_hook = 0x55555586e470
        i = <optimized out>
        stopped = 0
        stop_emit_count = 0
        continue_emit_count = 0
        __func__ = "signal_emit_real"
#3  0x00005555555fa60d in signal_emit (signal=<optimized out>, params=params@entry=4) at signals.c:286
        rec = 0x555555870350
        va = {{gp_offset = 48, fp_offset = 48, overflow_arg_area = 0x7fffffffe2e0, reg_save_area = 0x7fffffffe210}}
        signal_id = <optimized out>
        __func__ = "signal_emit"
#4  0x00005555555c0858 in irc_server_event (server=0x555555b96ae0, line=0x5555559b6cb5 "[", nick=0x5555559b6c81 "le_lookup: assertion 'hash_table != NULL' failed", 
    address=0x5555559b6c8c "assertion 'hash_table != NULL' failed") at irc.c:308
        signal = <optimized out>
        event = 0x555555d7c0c0 "event privmsg"
        args = <optimized out>
        __func__ = "irc_server_event"
#5  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x5555558743d0, params=params@entry=4, va=va@entry=0x7fffffffe3b0, first_hook=<optimized out>) at signals.c:242
        arglist = {0x555555b96ae0, 0x5555559b6cb5, 0x5555559b6c81, 0x5555559b6c8c, 0x0, 0x0}
        prev_emitted_signal = 0x55555586ed00
        hook = 0x55555586e470
        prev_emitted_hook = 0x55555586ed30
        i = <optimized out>
        stopped = 0
        stop_emit_count = 0
        continue_emit_count = 0
        __func__ = "signal_emit_real"
#6  0x00005555555fa6e5 in signal_emit_id (signal_id=<optimized out>, params=4) at signals.c:304
        rec = 0x5555558743d0
        va = {{gp_offset = 48, fp_offset = 48, overflow_arg_area = 0x7fffffffe4a0, reg_save_area = 0x7fffffffe3d0}}
        __func__ = "signal_emit_id"
#7  0x00005555555fa0b6 in signal_emit_real (rec=rec@entry=0x55555586ed00, params=params@entry=2, va=va@entry=0x7fffffffe520, first_hook=<optimized out>) at signals.c:242
        arglist = {0x555555b96ae0, 0x5555559b6c80, 0x0, 0x0, 0x0, 0x0}
        prev_emitted_signal = 0x0
        hook = 0x55555586ed30
        prev_emitted_hook = 0x0
        i = <optimized out>
        stopped = 0
        stop_emit_count = 0
        continue_emit_count = 0
        __func__ = "signal_emit_real"
#8  0x00005555555fa6e5 in signal_emit_id (signal_id=<optimized out>, params=params@entry=2) at signals.c:304
        rec = 0x55555586ed00
        va = {{gp_offset = 32, fp_offset = 48, overflow_arg_area = 0x7fffffffe610, reg_save_area = 0x7fffffffe540}}
        __func__ = "signal_emit_id"
#9  0x00005555555c09b5 in irc_parse_incoming (server=0x555555b96ae0) at irc.c:383
        str = 0x5555559b6c80 "ble_lookup: assertion 'hash_table != NULL' failed"
        count = 0
        ret = 0
        server = 0x555555b96ae0
        count = 0
        ret = 0
#10 0x00005555555eb84d in irssi_io_invoke (source=<optimized out>, condition=<optimized out>, data=<optimized out>) at misc.c:55
        rec = <optimized out>
        icond = <optimized out>
#11 0x00007ffff6ba8dd5 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#12 0x00007ffff6ba91a0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#13 0x00007ffff6ba922c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
No symbol table info available.
#14 0x000055555557701f in main (argc=<optimized out>, argv=<optimized out>) at irssi.c:335
        version = 0
        options = {{long_name = 0x55555560ef4e "version", short_name = 118 'v', flags = 0, arg = G_OPTION_ARG_NONE, arg_data = 0x555555854a60 <version>, 
            description = 0x55555560c515 "Display irssi version", arg_description = 0x0}, {long_name = 0x0, short_name = 0 '\000', flags = 0, arg = G_OPTION_ARG_NONE, 
            arg_data = 0x0, description = 0x0, arg_description = 0x0}}
        loglev = 5

О, вот новая разработка.

Я вылетаю только тогда, когда отправляю текст на канал, в котором есть другие люди. Кажется, что происходит то, что пока текст заливается в канал, и мой клиент занят его отправкой, какой-то другой клиент в канале не может справиться и вылетает, и сообщение с сервера об их отключении отправляется мне. и мой библейский поток немедленно прекращается. Следующее сообщение мне тогда segfaults.

Если я сделаю это в пустом канале или с другими пользователями, которые, как я знаю, ничего не скажут или не вылетят во время флуда, я не вылетю, и весь текст будет отправлен.

Я не могу отследить его даже с учетом всей предоставленной вами информации. вам комфортно с компиляцией irssi? вы можете применить этот патч https://github.com/ailin-nemui/irssi/commit/4e56675d2fea8aed59d91875f317ec228c94da85.patch и записать трассировку излучения сигнала следующим образом: irssi 2>signal_trace.log

@ ailin-nemui Конечно, дай мне несколько минут

Итак, с версией irssi, которую я скомпилировал с патчем, она никогда не вылетает. Понятия не имею почему.

Также файл signal_trace.log имеет размер 645 МБ.

ну .. спасибо за попытку .. мэх. Интересно, можно ли запустить его под средством проверки памяти valgrind (без патча трассировки сигнала); но, возможно, он также будет слишком медленным, чтобы привести к сбою. или с помощью некоторых других методов @josephbisch у вас есть предложения, как лучше всего отсортировать эту проблему?

Я второе предложение @ ailin-nemui о попытке захвата сетевого трафика, если это возможно, с помощью Wireshark, чтобы увидеть, что сервер отправляет сбойному клиенту.

Тогда мы могли бы создать «поддельный» сервер, который отправляет те же команды с netcat, чтобы избежать необходимости в настройке реального сервера и клиента (ов) для воспроизведения проблемы на нашей стороне (надеюсь).

f WireShark слишком сложен, можете ли вы попробовать / connect -rawlog file, и, если нам повезет, он захватывает / записывает достаточно, прежде чем он выйдет из строя

Таким образом, irssi не дает сбоев ни с патчем отслеживания сигналов, ни при работе под valgrind. Я думаю, оба делают это слишком медленно?

Я не думаю, что wirehark возможен. На сервере, на котором я запускаю irssi, много пользователей, вызывающих большой сетевой трафик (включая другие клиенты irc). Это не так много трафика, чтобы, я думаю, он мог иметь какое-либо отношение к сбоям, но его достаточно, чтобы извлечь что-либо из журнала было бы затруднительно, если у wirehark нет действительно хороших инструментов фильтрации, о которых я не знаю.

можешь попробовать / подключить -rawlog файл

Конечно. Что именно это делает? Я просто попытался использовать его, и, похоже, он не создал никакого файла.

Для воспроизведения я еще раз упомяну, что это происходит только в том случае, если ircd отправляет сообщение вашему клиенту, отправляющему Библию, в то время, когда он находится в процессе отправки Библии. Если вы, ребята, пытались воспроизвести его в пустом канале, вероятно, это не сработает. Наличие бота в том же канале, который говорит что-то произвольное каждую секунду или около того, должно работать, как и подключение второго клиента, при котором вы просто вручную отправляете несколько сообщений, пока первый клиент отправляет Библию.

Вы, ребята, вероятно, поймете, что не так, намного легче, чем я, если бы только это можно было воспроизвести.

Вы уверены, что / connect -rawlog file не создает файл с именем file в том же каталоге, из которого вы запускаете irssi? Он должен записывать необработанные отправляемые сообщения IRC.

Я думаю, что если мы сможем получить от вас rawlog, мы сможем воспроизвести его без необходимости пытаться получить те же условия в отношении ботов или других клиентов, которые есть у вас.

В конечном итоге проблема здесь в том, что irssi дает сбой в ответ на что-то, полученное с сервера, даже если это сообщение с сервера отправляется сбойному irssi в результате сообщения от какого-то другого клиента. Итак, нам действительно нужны сообщения между сервером и клиентом, у которого происходит сбой, и тогда мы сможем воспроизвести ошибку.

Я не могу воспроизвести ошибку, даже используя инструкции в вашем последнем комментарии. Я думаю, что это более сложно, чем просто иметь бота или второго клиента, отправляющего сообщения одновременно с отправкой Библии.

кстати @ spaghetti2514 что именно вы сделали, когда сказали отключить защиту от флуда?

что именно вы сделали, когда сказали отключить защиту от флуда?

Я установил cmd_queue_speed в 0

Я заставил rawlog работать (я давал ему путь, а не просто имя файла, потому что мне нужен был файл где-то еще). Результаты не освещают. Это просто набор исходящих PRIVMSG от меня на сервер, содержащих отрывки из Библии, за которыми следует одно сообщение, которое меня убивает, будь то сообщение от бота или что-то еще. После этого ничего нет.

Пример:

...
<< PRIVMSG #test :13:27 So the servants of the householder came and said unto him, Sir,
<< PRIVMSG #test :didst not thou sow good seed in thy field? from whence then hath it
>> :[email protected] PRIVMSG #test :aaa

Может, вы, ребята, не можете воспроизвести это, потому что не можете достаточно быстро заполнить какой-то буфер? Если дисковый ввод-вывод является узким местом, есть модуль ядра, который вы можете скомпилировать и загрузить, чтобы получить символьное устройство, из которого вы можете читать библию прямо из.

Я не думаю, что дисковый ввод-вывод должен быть здесь узким местом. Вы сказали, что в одной конфигурации он не вылетал, а только отключался, у вас была возможность исследовать разницу в конфигурации?

Ладно, наконец-то разобрался, в чем разница в профилях. Если nickcolor.pl присутствует в scripts / autorun, irssi segfaults, в противном случае его нет.

Можно ли получить копию вашего каталога ~/.irssi (включая nickcolor.pl ), который вы используете для сбоя?

Также не могли бы вы указать мне на копию bible.txt которую вы используете?

Можно ли нам протестировать на IRC-сервере, который вы также используете? Если да, не могли бы вы сообщить нам информацию для подключения?

Может быть, мы сможем это воспроизвести, если скопируем все в точности!

Спасибо за вашу настойчивость и помогли нам разобраться!

Вот zip, содержащий минимальный каталог .irssi и bible.txt

Я тестирую это на irc.oppaiti.me, который работает под управлением inspircd 2.2.0. Если вы собираетесь присоединиться, имейте в виду, что motd - это весь сценарий фильма о пчелах.

Ах да, христианский официант.

Удалось воспроизвести аварию. Спасибо!

Краткая версия (точки останова на server_connect_init , server->connection_lost = TRUE , glog_func , server_disconnect ) уже почти полностью рассказывает всю историю. Журнал большего размера с трассировкой: log.txt

0x00007f095e233f30 in _start () from /lib64/ld-linux-x86-64.so.2
(rr) c
Continuing.

Breakpoint 9, server_connect_init (server=0x558ecd4099a0) at servers.c:357
357             g_return_if_fail(server != NULL);
(rr)
Continuing.
[New Thread 29950.29980]

Thread 1 hit Breakpoint 12, glog_func (log_domain=0x0, log_level=G_LOG_LEVEL_WARNING, message=0x558ecd88a9d0
    "Dropping some data on an outgoing connection") at fe-common-core.c:253
253             switch (log_level) {
(rr)
Continuing.

Thread 1 hit Breakpoint 11, irc_server_send_data (server=0x558ecd4099a0, data=<optimized out>, len=94) at irc-servers.c:529
529                     server->connection_lost = TRUE;
(rr)
Continuing.

Thread 1 hit Breakpoint 4, server_disconnect (server=0x558ecd4099a0) at servers.c:462
462     {
(rr)
Continuing.

Thread 1 hit Breakpoint 12, glog_func (log_domain=0x7f095d55efc5 "GLib", log_level=G_LOG_LEVEL_CRITICAL, message=0x558ecd5876b0
    "g_hash_table_lookup: assertion 'hash_table != NULL' failed") at fe-common-core.c:253
253             switch (log_level) {
(rr)
Continuing.

Thread 1 hit Breakpoint 12, glog_func (log_domain=0x7f095d55efc5 "GLib", log_level=G_LOG_LEVEL_CRITICAL, message=0x558ecd9f0200
    "g_hash_table_lookup: assertion 'hash_table != NULL' failed") at fe-common-core.c:253
253             switch (log_level) {
(rr)
Continuing.

[...]

Thread 1 received signal SIGSEGV, Segmentation fault.
flood_newmsg (server=0x558ecd4099a0, level=4, nick=0x558ecd40acd1 "|\237U",
    host=0x558ecd40acd9 "ble_lookup: assertion 'hash_table != NULL' failed",
    target=0x558ecd594720 "#christianity") at flood.c:196
196             flood = g_hash_table_lookup(mserver->floodlist, nick);
(rr)

server->connection_lost = TRUE происходит на несколько кадров стека выше того же пути, что и Dropping some data on an outgoing connection

Входящее сообщение, отправленное со второго irssi, обрабатывается sig_public nickcolor.pl, который выполняет $server->command(...) , который вызывает parse_command который замечает server->connection_lost и отключается.

server_disconnect еще не убивает его, но излучает сигнал "сервер отключен", который очищает такие вещи, как server->isupport что приводит к этим сообщениям хэш-таблицы NULL и вызывает flood_deinit_server который удаляет данные модуля этого флуда.

Поэтому, когда он доходит до flood_newmsg он делает mserver = MODULE_DATA(server); , не может его найти и поэтому возвращает NULL, и mserver->floodlist вылетает.

Я думаю, что здесь нет никакого смысла после бесплатного использования, что довольно круто. К моменту сбоя refcount сервера равен 1, там все хорошо. После того, как irc-часть сервера заполнена NULL, вызывается лишь несколько вещей.

@ spaghetti2514 можете ли вы протестировать https://github.com/irssi/irssi/pull/803 и посмотреть, решит ли это проблему?

Я был бы рад

@ ailin-nemui
Удивительно, но этого не произошло. Irssi по-прежнему выходит из строя после выполнения тех же действий.

информация gdb и обратная трассировка с примененным # 803

Thread 1 "irssi" received signal SIGSEGV, Segmentation fault.
flood_newmsg (server=0x5555559b60d0, level=4, 
    nick=0x5555559af021 "B\"\366\377\177", host=0x5555559af027 "", 
    target=0x555555b32000 "#test") at flood.c:196
196             flood = g_hash_table_lookup(mserver->floodlist, nick);

(gdb) bt
#0  flood_newmsg (server=0x5555559b60d0, level=4, 
    nick=0x5555559af021 "B\"\366\377\177", host=0x5555559af027 "", 
    target=0x555555b32000 "#test") at flood.c:196
#1  0x00005555555ddfff in flood_privmsg (server=0x5555559b60d0, 
    data=<optimized out>, nick=0x5555559af021 "B\"\366\377\177", 
    addr=0x5555559af027 "") at flood.c:255
#2  0x00005555555f7136 in signal_emit_real (rec=rec@entry=0x555555872340, 
    params=params@entry=4, va=va@entry=0x7fffffffe138, 
    first_hook=<optimized out>) at signals.c:242
#3  0x00005555555f7660 in signal_emit (signal=<optimized out>, 
    params=params@entry=4) at signals.c:286
#4  0x00005555555bf388 in irc_server_event (server=0x5555559b60d0, 
    line=0x5555559af040 "PRIVMSG #test :And all the prophets prophesied so, saying, Go up to Ramothgilead, and prosper: for the anime tiddies shall deliver it into the hand of the king.", nick=0x5555559af021 "B\"\366\377\177", 
    address=0x5555559af027 "") at irc.c:338
#5  0x00005555555f7136 in signal_emit_real (rec=rec@entry=0x555555876360, 
    params=params@entry=4, va=va@entry=0x7fffffffe2e8, 
    first_hook=<optimized out>) at signals.c:242
#6  0x00005555555f7738 in signal_emit_id (signal_id=<optimized out>, 
    params=4) at signals.c:304
#7  0x00005555555f7136 in signal_emit_real (rec=rec@entry=0x555555881210, 
    params=params@entry=2, va=va@entry=0x7fffffffe448,

@ spaghetti2514 :(

можешь попробовать с этим скриптом? сколько он печатает перед сбоем?

sub print_signal {
Irssi::active_win->print(Irssi::signal_get_emitted) ;
} 
for ("server connected", "server disconnected", "server destroyed") {
Irssi::signal_add_first ( $_, "print_signal" ) ;
} 

@ ailin-nemui На что он печатает? Я не вижу ничего лишнего, напечатанного с загруженным скриптом.

@ spaghetti2514 странно. он должен печатать в активном окне. вы можете изменить код на

sub print_signal {
print STDERR Irssi::signal_get_emitted() . "\n";
} 

вместо этого напечатать в stderr и запустить irssi 2>stderr.log

сначала проверьте это без Библии:

/connect irc.oppaiti.me
/disconnect

он должен напечатать что-то вроде этого, если все работает

 -!- Irssi: Looking up irc.oppaiti.me
 -!- Irssi: server connected
 -!- Irssi: Connection to irc.oppaiti.me established
 !irc.oppaiti.me *** Looking up your hostname...
 -!- Your host is irc.oppaiti.me, running version InspIRCd-2.2
...
 -!- Irssi: Disconnecting from server irc.oppaiti.me: [leaving]
 -!- Irssi: server disconnected
 -!- Irssi: Connection lost to irc.oppaiti.me
 -!- Irssi: server destroyed

3 сообщения "Irssi: server ..." взяты из этого небольшого отладочного скрипта

Я также протестировал изменения в # 803. От мастера по адресу d85f86726115a2f80d878254dd9773470d6dd9c1 я объединил ветку. Перед объединением я надежно увидел segfault. После применения ветки segfault отсутствует.

Один интересный момент: я вижу это в окне статуса (даже до обновления Irssi, чтобы показать, что соединение отсутствует):

19:39 -!- Irssi: warning Dropping some data on an outgoing connection
19:39 -!- Irssi: process 0 (cat /will/t/t/bible.txt) terminated with return code 0

Хотя сбоев нет, поведение после них странное. Irssi сидит и выглядит так, как будто он подключен, пока другой клиент в канале что-то не сделает (отправит сообщение). Затем Ирсси уходит. Выполнение чего-либо еще в Irssi, включая отправку сообщения на канал, не приводит к его завершению, но он кажется отключенным, поскольку если я попытаюсь отправить сообщение на канал, похоже, что оно сработало, но в канале в другой клиент. Это то же самое, что @ spaghetti2514 обнаружил в том, что что-то должно произойти извне после флуда, но теперь мы не вылетаем, а просто отключаемся.

Кстати, я могу надежно воспроизвести сбой, используя сервер, который я выставил для тестирования (я не хотел повторно тестировать на упомянутом сервере @ spaghetti2514 ).

спасибо за подробный анализ @horgh , звучит так, как будто мы должны дополнительно изучить, что там происходит и почему он не отключается (может быть, это ошибка / побочный эффект моего исправления?)

@horgh

Перед слиянием достоверно видел segfault. После применения ветки segfault отсутствует.

Странно. Может я неправильно наложил патч

@ ailin-nemui

почему он не отключается (может быть, это ошибка / побочный эффект моего исправления?)

Я не думаю, что это побочный эффект вашего исправления. Такое же поведение я наблюдал до вашего патча, когда nickcolor.pl не загружается. Загрузка nickcolor.pl заменяет отключение только на segfault. Любой из них все еще запускается сервером, отправляющим что-то после призрачного отключения клиента.

Также извините, если я не спешу пробовать что-то или помогать, в настоящее время я путешествую и очень занят.

Да, я думаю, что странное состояние полусвязи не вызвано исправлением, поскольку мы видели задержку раньше.

О отсроченном отключении:

Мы заканчиваем тем, что устанавливаем server->connection_lost true (в irc_server_send_data() ) после того, как увидим предупреждение об удалении некоторых данных. Так что в этот момент (или как можно скорее) нам, вероятно, следует полностью отключить сервер. Но мы пока этого не делаем.

Отключение происходит в irc_parse_incoming() это выглядит так: когда приходит сообщение (или что-то еще от сервера) и мы видим, что server->connection_lost истинно, мы вызываем server_disconnect() .

Эти изменения в этой фиксации заставляют нас немедленно вызвать server_disconnect() : horgh / irssi @ 9ce84040cf7308636ed6f7746f8bfa4e3ef82eb2

Это нормально работает для этого сценария. Если мы хотим это сделать, мы должны проверить любой сигнал, который использует SERVER_REC* который может привести к тому, что мы вызовем этот server_disconnect() , так как без удержания ссылки он может быть освобожден и SERVER_REC* может стать недействительным (и мы вылетим по-новому). Так что может быть лучший способ вызвать отключение.

Я также попытался установить таймер, который отключал все серверы с пометкой ->connection_lost . Функция таймера позволяет не беспокоиться о том, что SERVER_REC* станет недействительным в середине события, но будет промежуток времени, когда сервер находится в этом частично подключенном состоянии (между тем, когда мы получим ->connection_lost set и когда таймер срабатывает), поэтому он не кажется идеальным.

Изменить: мы, вероятно, не можем использовать этот подход (убивая SERVER_REC* в этот момент), поскольку я не думаю, что можно будет в достаточной степени защитить SERVER_REC* (например, сценарии Perl). Звонить куда-нибудь server_disconnect() кажется правильным, но я не знаю где!

@ spaghetti2514 может быть, вы можете просто повторить патч, когда у вас будет время. сначала убедитесь, что патч работает, с помощью простого случая, который я показал вам в https://github.com/irssi/irssi/issues/796#issuecomment -355636720

@horgh Я думаю, что вызов server_disconnect кажется правильным (и единственным) решением. Единственная другая идея, которая у меня есть, - это добавить проверку в основной цикл. Однажды у меня был план изменить модель излучателя сигнала (события) на значение по умолчанию «после события», то есть вы добавляете некоторые события, которые будут запускаться после завершения текущего стека сигналов ...

Ваша идея иметь способ запускать вещи после завершения текущей обработки сигнала - изящная! Я огляделся, чтобы увидеть, есть ли что-то вроде API. Это определенно было бы здесь полезно, и похоже, что были и другие ситуации, когда это было бы удобно.

Возможно, что-то простое, например, регистрация функций обратного вызова для запуска основного цикла, сработает. Я посмотрю на этот цикл!

У меня есть решение для этого аспекта отложенного отключения / segfault в horgh / irssi @ f8bdc01. Это заставляет нас очистить сервер в следующий раз через цикл событий. Как видите, интервал очень короткий. Идея заключалась в том, чтобы действовать мгновенно. Я тестировал его вместе с изменениями в # 803, и, похоже, он работает нормально. Нет segfault, и Irssi сразу показывает, что сервер отключен.

Я не смог придумать лучшего решения, несмотря на то, что продолжал ковыряться в этом.

803, похоже, хорошо решает проблему segfault.

Я думаю, что нам, вероятно, следует реализовать наш собственный источник событий для постановки событий в очередь вместо тайм-аута, 1 взлом :-)

Да, это не очень хорошо. Хотя коротко!

Я не уверен, как будет выглядеть такая очередь. У вас есть примерное представление о том, как, по вашему мнению, он должен выглядеть? Я не понимаю, как вообще работают события: flhed:

Была ли эта страница полезной?
0 / 5 - 0 рейтинги