eiskaltdcpp / eiskaltdcpp

File sharing program using DC and ADC protocols
GNU General Public License v3.0
370 stars 76 forks source link

Abort in dcpp::HashManager::StreamStore::saveTree due to TigerTree having no leaves #513

Open kblaschke opened 3 months ago

kblaschke commented 3 months ago

While hashing files, EiskaltDC++ crashes at the same file over and over again, causing an abort due to calling p_Tree.getLeaves()[0].data on a zero-size vector.

Backtrace:

#0  0x00007ffff66ad35c in ??? () at /usr/lib64/libc.so.6
#1  0x00007ffff665d1f6 in raise () at /usr/lib64/libc.so.6
#2  0x00007ffff66458f7 in abort () at /usr/lib64/libc.so.6
#3  0x00007ffff62d8f9f in std::__glibcxx_assert_fail(char const*, int, char const*, char const*) ()
    at /usr/lib/gcc/x86_64-pc-linux-gnu/13/libstdc++.so.6
#4  0x00007ffff7503ea5 in std::vector<dcpp::HashValue<dcpp::TigerHash>, std::allocator<dcpp::HashValue<dcpp::TigerHash> > >::operator[]
    (this=0x7fffe73ff6f8, __n=0) at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1145
#5  std::vector<dcpp::HashValue<dcpp::TigerHash>, std::allocator<dcpp::HashValue<dcpp::TigerHash> > >::operator[]
    (__n=0, this=0x7fffe73ff6f8) at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1145
#6  dcpp::HashManager::StreamStore::saveTree
    (this=this@entry=0x7ffff762ebc0 <dcpp::HashManager::Hasher::fastHash(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*, dcpp::MerkleTree<dcpp::TigerHash, 1024ul>&, long, dcpp::CRC32Filter*)::streamStore>, p_filePath="<redacted>", p_Tree=...)
    at /var/tmp/portage/net-p2p/eiskaltdcpp-2.4.2/work/eiskaltdcpp-2.4.2/dcpp/HashManager.cpp:157
#7  0x00007ffff7509e13 in dcpp::HashManager::Hasher::fastHash
    (this=this@entry=0x555555bc03a0, filename="<redacted>", tth=..., size=size@entry=39556, xcrc32=xcrc32@entry=0x0)
    at /var/tmp/portage/net-p2p/eiskaltdcpp-2.4.2/work/eiskaltdcpp-2.4.2/dcpp/HashManager.cpp:943
#8  0x00007ffff750a38e in dcpp::HashManager::Hasher::run (this=0x555555bc03a0)
    at /var/tmp/portage/net-p2p/eiskaltdcpp-2.4.2/work/eiskaltdcpp-2.4.2/dcpp/HashManager.cpp:1021
#9  0x00007ffff75840de in dcpp::Thread::starter (p=<optimized out>)
    at /var/tmp/portage/net-p2p/eiskaltdcpp-2.4.2/work/eiskaltdcpp-2.4.2/dcpp/Thread.h:119
#10 0x00007ffff66ab652 in ??? () at /usr/lib64/libc.so.6
#11 0x00007ffff67278ac in ??? () at /usr/lib64/libc.so.6
(gdb) frame 4
#4  0x00007ffff7503ea5 in std::vector<dcpp::HashValue<dcpp::TigerHash>, std::allocator<dcpp::HashValue<dcpp::TigerHash> > >::operator[] (
    this=0x7fffe73ff6f8, __n=0) at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1145
1145          operator[](size_type __n) const _GLIBCXX_NOEXCEPT

p_Tree is empty:

(gdb) p p_Tree
$1 = (const dcpp::TigerTree &) @0x7fffe73ff6e0: {blocks = std::vector of length 4, capacity 8 = {{
      first = {<dcpp::FastAlloc<dcpp::HashValue<dcpp::TigerHash> >> = {<dcpp::FastAllocBase> = {<No data fields>}, <No data fields>}, 
        static BYTES = 24, data = "!\377\214*s\226 \035\3201\374\3028\331?\035\370}2\326\3104\246"}, second = 32768}, {
      first = {<dcpp::FastAlloc<dcpp::HashValue<dcpp::TigerHash> >> = {<dcpp::FastAllocBase> = {<No data fields>}, <No data fields>}, 
        static BYTES = 24, data = "\213\330\320\360\226}\233\024\234\022\206X(\37531cbW\260\212M>9"}, second = 4096}, {
      first = {<dcpp::FastAlloc<dcpp::HashValue<dcpp::TigerHash> >> = {<dcpp::FastAllocBase> = {<No data fields>}, <No data fields>}, 
        static BYTES = 24, data = "Z${\273\341c?3?\217\021\275\362<<\2665\361\0044\n"}, second = 2048}, {
      first = {<dcpp::FastAlloc<dcpp::HashValue<dcpp::TigerHash> >> = {<dcpp::FastAllocBase> = {<No data fields>}, <No data fields>}, 
        static BYTES = 24, data = "\373Fn\241\t\034\016\374-+\034\r\025\350Y\321/*\270\234@\t\327|"}, second = 1024}}, 
  leaves = std::vector of length 0, capacity 0, 
  root = {<dcpp::FastAlloc<dcpp::HashValue<dcpp::TigerHash> >> = {<dcpp::FastAllocBase> = {<No data fields>}, <No data fields>}, 
    static BYTES = 24, data = '\000' <repeats 23 times>}, fileSize = 39556, blockSize = 65536}

A potential fix might be to skip the save function if the tree has no leaves.

kblaschke commented 3 months ago

Edit: Seems to be an issue with share size, either too many files or too much data. Will investigate further.

tehnick commented 2 months ago

Hi kblaschke,

Any progress with your investigation?

I have never seen anything similar...

kblaschke commented 1 month ago

I've deleted the database and re-hashed twice, which took about two days each. First time it broke again, but I didn't have had a debug build ready at that time. Second time I had, but the hashing finished without crashing. Will keep the debug build, so once it happens again, I'll be able to properly debug and see what goes wrong and provide an update!