ZNC crashes when user which is fixed to partyline channel is deleted. #43

Closed
opened 2026-10-05 03:55:31 +02:00 by adam · 1 comment
Owner

I tried to remove account (which I used only to test issue #94) which was just clone of my main account and it was fixed to partyline channel. I did this with *admin module (log below).

<Mkaysi>deluser Mkaysi-test
<*admin> User Mkaysi-test deleted!

  • Yhteys katkaistu (Vastapää sulki pistokkeen).
    (* Disconnected (remote host closed the connection).)

We were running ZNC with --debug and the last thing in output is:

(Mkaysi) CLI -> ZNC [PRIVMSG _admin :deluser Mkaysi-test]
charset: [PRIVMSG+%2Aadmin+%3Adeluser+Mkaysi-test] is valid [UTF-8] already.
(Mkaysi) ZNC -> CLI [:_admin!znc@znc.in PRIVMSG Mkaysi :User Mkaysi-test deleted!]
/usr/include/c++/4.4/debug/safe_iterator.h:204:error: attempt to increment
a singular iterator.

Objects involved in the operation:
iterator "this" @ 0x0x7fffd130fea0 {
type = N11__gnu_debug14_Safe_iteratorISt23_Rb_tree_const_iteratorIP17CPartylineChannelENSt7__debug3setIS3_St4lessIS3_ESaIS3_EEEEE (mutable iterator);
state = singular;
references sequence with type `NSt7__debug3setIP17CPartylineChannelSt4lessIS2_ESaIS2_EEE' @ 0x0x7fffd130fea0
}
zsh: abort znc --debug

I tried to remove account (which I used only to test issue #94) which was just clone of my main account and it was fixed to partyline channel. I did this with *admin module (log below). <Mkaysi>deluser Mkaysi-test <*admin> User Mkaysi-test deleted! - Yhteys katkaistu (Vastapää sulki pistokkeen). (\* Disconnected (remote host closed the connection).) We were running ZNC with --debug and the last thing in output is: (Mkaysi) CLI -> ZNC [PRIVMSG _admin :deluser Mkaysi-test] charset: [PRIVMSG+%2Aadmin+%3Adeluser+Mkaysi-test] is valid [UTF-8] already. (Mkaysi) ZNC -> CLI [:_admin!znc@znc.in PRIVMSG Mkaysi :User Mkaysi-test deleted!] /usr/include/c++/4.4/debug/safe_iterator.h:204:error: attempt to increment a singular iterator. Objects involved in the operation: iterator "this" @ 0x0x7fffd130fea0 { type = N11__gnu_debug14_Safe_iteratorISt23_Rb_tree_const_iteratorIP17CPartylineChannelENSt7__debug3setIS3_St4lessIS3_ESaIS3_EEEEE (mutable iterator); state = singular; references sequence with type `NSt7__debug3setIP17CPartylineChannelSt4lessIS2_ESaIS2_EEE' @ 0x0x7fffd130fea0 } zsh: abort znc --debug <!-- github-sync-id:2487863 -->
adam closed this issue 2026-10-05 03:55:31 +02:00
Author
Owner

I can reproduce, it looks like the problem lies where partyline invalidates iterators by erasing the channel in this case. The code which is causing this is as follows:

virtual EModRet OnDeleteUser(CUser& User) {
    // Loop through each chan
    for (set<CPartylineChannel*>::iterator it = m_ssChannels.begin(); it != m_ssChannels.end(); ++it) {
        RemoveUser(&User, *it, "KICK", "User deleted", true);
    }

    return CONTINUE;
}


void RemoveUser(CUser* pUser, CPartylineChannel* pChannel, const CString& sCommand,
        const CString& sMessage = "", bool bNickAsTarget = false) {

            ...

    if (ssNicks.empty()) {
        delete pChannel;
        m_ssChannels.erase(pChannel);
    }
}

And a full backtrace.

(gdb) bt full
#0  0x00007ffff6b45965 in raise () from /lib/libc.so.6
No symbol table info available.
#1  0x00007ffff6b46ddb in abort () from /lib/libc.so.6
No symbol table info available.
#2  0x00007ffff7118ddd in __gnu_debug::_Error_formatter::_M_error() const ()
   from /usr/lib/libstdc++.so.6
No symbol table info available.
#3  0x00007ffff52ff92c in __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<CPartylineChannel*>, std::__debug::set<CPartylineChannel*, std::
less<CPartylineChannel*>, std::allocator<CPartylineChannel*> > >::operator++ (
    this=0x7fffffffe210)
    at /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/debug/safe_iterator.h:220
No locals.
#4  0x00007ffff52f49bf in CPartylineMod::OnDeleteUser (this=0x953bf0, User=...)
    at partyline.cpp:126
        it = {<__gnu_debug::_Safe_iterator_base> = {_M_sequence = 0x953de8, 
            _M_version = 0, _M_prior = 0x0, _M_next = 0x0}, _M_current = {
            _M_node = 0x952890}}
#5  0x000000000061b068 in CModules::OnDeleteUser (this=0x946c90, User=...)
    at src/Modules.cpp:747
        pMod = 0x953bf0
---Type <return> to continue, or q <return> to quit---
        e = CModule::CONTINUE
        pOldClient = 0x0
        pOldUser = 0x0
        pNetwork = 0x0
        a = 2
        bHaltCore = false
#6  0x000000000057e893 in CZNC::HandleUserDeletion (this=0x92e040)
    at src/znc.cpp:118
        pUser = 0x94eae0
        it = {<__gnu_debug::_Safe_iterator_base> = {_M_sequence = 0x92e100, 
            _M_version = 1, _M_prior = 0x0, _M_next = 0x7fffffffe360}, 
          _M_current = {_M_node = 0x94bef0}}
        end = {<__gnu_debug::_Safe_iterator_base> = {_M_sequence = 0x92e100, 
            _M_version = 1, _M_prior = 0x7fffffffe330, _M_next = 0x0}, 
          _M_current = {_M_node = 0x92e0d8}}
#7  0x000000000057ebcf in CZNC::Loop (this=0x92e040) at src/znc.cpp:161
        sError = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >> = {static npos = <optimized out>, 
            _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
              _M_p = 0x92cf38 ""}}, <No data fields>}
#8  0x000000000054a8f7 in main (argc=2, argv=0x7fffffffe958)
---Type <return> to continue, or q <return> to quit---
    at src/main.cpp:320
        sConfig = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >> = {static npos = <optimized out>, 
            _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
              _M_p = 0x92cf38 ""}}, <No data fields>}
        iOptIndex = -1
        bForeground = true
        bMakePass = false
        bAllowRoot = false
        pZNC = 0x92e040
        sa = {__sigaction_handler = {sa_handler = 0x549a50 <die(int)>, 
            sa_sigaction = 0x549a50 <die(int)>}, sa_mask = {__val = {
              0 <repeats 16 times>}}, sa_flags = -2147483648, 
          sa_restorer = 0x1}
        iRet = 0
        sDataDir = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >> = {static npos = <optimized out>, 
            _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
              _M_p = 0x92cf38 ""}}, <No data fields>}
        iArg = -1
---Type <return> to continue, or q <return> to quit---
        bMakeConf = false
        bMakePem = false
(gdb) 
I can reproduce, it looks like the problem lies where partyline invalidates iterators by erasing the channel in this case. The code which is causing this is as follows: ``` virtual EModRet OnDeleteUser(CUser& User) { // Loop through each chan for (set<CPartylineChannel*>::iterator it = m_ssChannels.begin(); it != m_ssChannels.end(); ++it) { RemoveUser(&User, *it, "KICK", "User deleted", true); } return CONTINUE; } void RemoveUser(CUser* pUser, CPartylineChannel* pChannel, const CString& sCommand, const CString& sMessage = "", bool bNickAsTarget = false) { ... if (ssNicks.empty()) { delete pChannel; m_ssChannels.erase(pChannel); } } ``` And a full backtrace. ``` (gdb) bt full #0 0x00007ffff6b45965 in raise () from /lib/libc.so.6 No symbol table info available. #1 0x00007ffff6b46ddb in abort () from /lib/libc.so.6 No symbol table info available. #2 0x00007ffff7118ddd in __gnu_debug::_Error_formatter::_M_error() const () from /usr/lib/libstdc++.so.6 No symbol table info available. #3 0x00007ffff52ff92c in __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<CPartylineChannel*>, std::__debug::set<CPartylineChannel*, std:: less<CPartylineChannel*>, std::allocator<CPartylineChannel*> > >::operator++ ( this=0x7fffffffe210) at /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/debug/safe_iterator.h:220 No locals. #4 0x00007ffff52f49bf in CPartylineMod::OnDeleteUser (this=0x953bf0, User=...) at partyline.cpp:126 it = {<__gnu_debug::_Safe_iterator_base> = {_M_sequence = 0x953de8, _M_version = 0, _M_prior = 0x0, _M_next = 0x0}, _M_current = { _M_node = 0x952890}} #5 0x000000000061b068 in CModules::OnDeleteUser (this=0x946c90, User=...) at src/Modules.cpp:747 pMod = 0x953bf0 ---Type <return> to continue, or q <return> to quit--- e = CModule::CONTINUE pOldClient = 0x0 pOldUser = 0x0 pNetwork = 0x0 a = 2 bHaltCore = false #6 0x000000000057e893 in CZNC::HandleUserDeletion (this=0x92e040) at src/znc.cpp:118 pUser = 0x94eae0 it = {<__gnu_debug::_Safe_iterator_base> = {_M_sequence = 0x92e100, _M_version = 1, _M_prior = 0x0, _M_next = 0x7fffffffe360}, _M_current = {_M_node = 0x94bef0}} end = {<__gnu_debug::_Safe_iterator_base> = {_M_sequence = 0x92e100, _M_version = 1, _M_prior = 0x7fffffffe330, _M_next = 0x0}, _M_current = {_M_node = 0x92e0d8}} #7 0x000000000057ebcf in CZNC::Loop (this=0x92e040) at src/znc.cpp:161 sError = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >> = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x92cf38 ""}}, <No data fields>} #8 0x000000000054a8f7 in main (argc=2, argv=0x7fffffffe958) ---Type <return> to continue, or q <return> to quit--- at src/main.cpp:320 sConfig = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >> = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x92cf38 ""}}, <No data fields>} iOptIndex = -1 bForeground = true bMakePass = false bAllowRoot = false pZNC = 0x92e040 sa = {__sigaction_handler = {sa_handler = 0x549a50 <die(int)>, sa_sigaction = 0x549a50 <die(int)>}, sa_mask = {__val = { 0 <repeats 16 times>}}, sa_flags = -2147483648, sa_restorer = 0x1} iRet = 0 sDataDir = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >> = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x92cf38 ""}}, <No data fields>} iArg = -1 ---Type <return> to continue, or q <return> to quit--- bMakeConf = false bMakePem = false (gdb) ``` <!-- github-comment-id:3063071 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/znc#43