Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rtorrent (git) crashed due to 'save_input_history' #928

Open
vp1981 opened this issue Oct 17, 2019 · 18 comments · May be fixed by #929
Open

rtorrent (git) crashed due to 'save_input_history' #928

vp1981 opened this issue Oct 17, 2019 · 18 comments · May be fixed by #929

Comments

@vp1981
Copy link

vp1981 commented Oct 17, 2019

Hello,
I faced with rtorrent crash on Archlinux. The distribution packages libtorrent and rtorrent don't have debug symbols so I rebuild both packages from git repo. In gdb I see:

run
Starting program: /usr/bin/rtorrent 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7ffff6926700 (LWP 358966)]

Thread 1 "rtorrent" received signal SIGSEGV, Segmentation fault.
0x000055555565358e in ui::Root::save_input_history (this=0x55555576f930) at root.cc:462
462     root.cc: No such file or directory.
(gdb) bt
#0  0x000055555565358e in ui::Root::save_input_history (this=0x55555576f930) at root.cc:462
#1  0x00005555555b7e31 in std::__invoke_impl<void, void (core::DownloadList::*&)(), core::DownloadList*&> (__f=<optimized out>, __f=<optimized out>, __t=<optimized out>) at /usr/include/c++/9.2.0/bits/invoke.h:70
#2  std::__invoke<void (core::DownloadList::*&)(), core::DownloadList*&> (__fn=<optimized out>) at /usr/include/c++/9.2.0/bits/invoke.h:95
#3  std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>::__call<void, rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&, 0ul>(std::tuple<rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&>&&, std::_Index_tuple<0ul>) (__args=..., this=<optimized out>) at /usr/include/c++/9.2.0/functional:400#4  std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>::operator()<rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&, void>(rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (this=<optimized out>) at /usr/include/c++/9.2.0/functional:484#5  object_convert_type<std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>, void>::operator()<rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > >(rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (arg1=..., arg2=..., this=<optimized out>) at command_helpers.h:182#6  std::_Function_handler<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&), object_convert_type<std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>, void> >::_M_invoke(std::_Any_data const&, rpc::rt_triple<int, void*, void*>&&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (__functor=..., __args#0=..., __args#1=...) at /usr/include/c++/9.2.0/bits/std_function.h:286#7  0x00005555556c9482 in std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&)>::operator()(rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) const (__args#1=std::vector of length 1, capacity 1 = {...}, __args#0=..., this=0x5555557bedd8) at /usr/include/c++/9.2.0/bits/std_function.h:685#8  rpc::command_base::_call<std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&)>, rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > >(rpc::command_base*, rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> >) (args=std::vector of length 10, capacity -977343616694 = {...}, target=...,     cmd=0x5555557bedd8) at command.h:245#9  rpc::command_base_call_list<rpc::rt_triple<int, void*, void*> > (rawCommand=0x5555557bedd8, target=..., rawArgs=...) at command.cc:122#10 0x00005555556d3316 in rpc::CommandMap::call_command (this=this@entry=0x55555575be40 <rpc::commands>, key=<optimized out>, key@entry=0x7fffffffc6a0 "session.save", arg=..., target=...) at /usr/include/c++/9.2.0/bits/stl_pair.h:260#11 0x00005555556e896d in rpc::parse_command (target=..., first=0x7fffffffca62 "", last=<optimized out>) at /usr/include/c++/9.2.0/bits/stl_pair.h:260#12 0x00005555556ea830 in rpc::parse_command_file (path="~/.rtorrent.rc") at /usr/include/c++/9.2.0/bits/stl_pair.h:260#13 0x0000555555622040 in apply_try_import (path="~/.rtorrent.rc") at command_events.cc:216#14 0x000055555562bcad in std::__invoke_impl<void, void (*&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (    __f=<optimized out>) at /usr/include/c++/9.2.0/bits/invoke.h:89#15 std::__invoke<void (*&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (__fn=<optimized out>)    at /usr/include/c++/9.2.0/bits/invoke.h:95#16 std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::__call<void, rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, 0ul>(std::tuple<rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>&&, std::_Index_tuple<0ul>) (__args=...,     this=<optimized out>) at /usr/include/c++/9.2.0/functional:400
#17 std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()<rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, void>(rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=<optimized out>) at /usr/include/c++/9.2.0/functional:484#18 object_convert_type<std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, void>::operator()<rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (arg1=..., arg2=..., this=<optimized out>)    at command_helpers.h:182
#19 std::_Function_handler<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), object_convert_type<std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, void> >::_M_invoke(std::_Any_data const&, rpc::rt_triple<int, void*, void*>&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (__functor=..., __args#0=..., __args#1=...) at /usr/include/c++/9.2.0/bits/std_function.h:286#20 0x00005555556c6e86 in std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()(rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (__args#1="~/.rtorrent.rc", __args#0=..., this=0x5555557b71c8) at /usr/include/c++/9.2.0/bits/std_function.h:685#21 rpc::command_base::_call<std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rpc::command_base*, rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (args="", target=..., cmd=0x5555557b71c8)    at command.h:245
#22 rpc::command_base_call_string<rpc::rt_triple<int, void*, void*> > (rawCommand=0x5555557b71c8, target=..., rawArgs=...) at command.cc:106
#23 0x00005555556d3316 in rpc::CommandMap::call_command (this=this@entry=0x55555575be40 <rpc::commands>, key=<optimized out>, key@entry=0x7fffffffdd20 "try_import", arg=..., target=...) at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#24 0x00005555556e896d in rpc::parse_command (target=..., first=0x55555570530b "", first@entry=0x5555557052f0 "try_import = ~/.rtorrent.rc", last=<optimized out>) at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#25 0x00005555555a2d09 in rpc::parse_command_single (target=..., first=first@entry=0x5555557052f0 "try_import = ~/.rtorrent.rc") at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#26 0x0000555555595be2 in main (argc=<optimized out>, argv=0x7fffffffe128) at /usr/include/c++/9.2.0/bits/stl_pair.h:260

My system:
Archlinux x86_64
gcc: 9.2.0

@vp1981
Copy link
Author

vp1981 commented Oct 17, 2019

Seems that commit a3a384b introduced this regression. I tried to debug that function but managed to just check that it is possible to enter into this function. The very first call

  if (!m_control->core()->download_store()->is_enabled())
    return;

seems causes all troubles. I added code to check m_control vs nullptr and found that it is really nullptr at this point. I suspect that some code is run too early therefore m_control is nullptr as it should be because Root::Root object is initialized with m_control(NULL).

I applied locally the patch to ui/root.cc just adding the check of m_control against nullptr and seems rtorrent works without flaws (didn't try to add a torrent or a magnet yet). By the way, why do you use NULL instead of nullptr? Don't have time to convert to nullptr?

P.S. Before to begin to dig the problem I updated my .rtorrent.rc file but either way rtorrent didn't complain about wrong syntax or unknown settings.

@chros73
Copy link
Contributor

chros73 commented Oct 17, 2019

I faced with rtorrent crash on Archlinux.

In which circumstances?

@vp1981
Copy link
Author

vp1981 commented Oct 17, 2019

@chros73 , just start in terminal and rtorrent immediately crashes.

@chros73
Copy link
Contributor

chros73 commented Oct 17, 2019

The very first call ... seems causes all troubles.

That would be strange, because:

But your original report was different:

ui::Root::save_input_history (this=0x55555576f930) at root.cc:462
462     root.cc: No such file or directory.

Since it's working fine on Debian / Ubuntu, I don't have a clue.

@pyroscope
Copy link
Contributor

nullptr – what works on your platform doesn't necessarily do on the supported spectrum. Checking that it DOES work can be loads of work.

@chros73
Copy link
Contributor

chros73 commented Oct 17, 2019

@vp1981, @QDesjardin just created packages for rtorrent-ps-ch, and he states that he doesn't have this issue.

@vp1981
Copy link
Author

vp1981 commented Oct 18, 2019

@chros73

But your original report was different:

ui::Root::save_input_history (this=0x55555576f930) at root.cc:462
462     root.cc: No such file or directory.

This is because I ran rtorrent on host that doesn't have sources, laterly I copied them to the host and run rtorrent from build dir to get full "power" of gdb.

@pyroscope

nullptr – what works on your platform doesn't necessarily do on the supported spectrum. Checking that it DOES work can be loads of work.

Isn't nullptr is part of C++ standard? I usually use this site: cppreference.com to check C++ features and some syntax hints, so on this site https://en.cppreference.com/w/cpp/language/nullptr tells that nullptr is part of C++11. Don't take this that seriously, I rarely program on C++, so this was just a wonder. Besides, AFAIK rtorrent could be built on plenty of platforms supporting C++11 and (optionally) ncurses, so I was a bit confused.

@chros73

@vp1981, @QDesjardin just created packages for rtorrent-ps-ch, and he states that he doesn't have this issue.

Thanks, I'll have to investigate this closely. When I openned the issue I didn't have time to make close look on the problem.

Some additional information:
before the issue I used locally build libtorrent/rtorrent packages (0.9.7 and corresponding libtorrent). Then I noticed that my distro (Archlinux) has newer version for both. I installed them, started rtorrent and it crashed. I tried to adapt my ~/.rtorrent.rc to new syntax and tried to run rtorrent again, it crashed.

I decided to find out the reason but as distro packages don't have debug symbols (gdb shows nothing) and were build with --disable-debug I had to rebuild both packages locally (packages in sense of Archlinux), that's why you see No such file or directory: they were build on special host. Finally, I managed to get meaningful backtrace (bt) from gdb. (Side note: when I ran rtorrent on build host, without any ~/.rtorrent.rc and any saved session, it started fine).

Still I didn't get why rtorrent crashes at this point and remembered that it is possible due to null pointer dereference. Indeed, it was that, but it bothered me, how it is possible that the m_control at this stage is NULL, it must be NULL before initialization and immediately after the structure initialization. But as with the additional check rtorrent was running without evident issues I stopped on that.

Laterly that day I found that some of torrent files (with non-latin enconding in names, repeat, SOME, not all) are shown very strangely, something like ^M-~ etc. They were stopped, but I couldn't start a hash recheck for them, so I simply deleted them. I double checked that encoding_list was renamed to encoding.add, I added also as additional value to it not only utf8 but utf-8 as was for encoding_list but after that I didn't test much.

Right now I use

$ pkg-query libtorrent
local/libtorrent-git 0.13.8_4_g9bbbee6d-4
    A BitTorrent library written in C++.
local/rtorrent-git 0.9.8_9_g8ac98c6-4
    A ncurses BitTorrent client written in C++, based on the libTorrent libraries for Unix.

(for Archlinux users, yeah, I had to rebuild packages three times before I could get debug symbols and the fourth is without them).

On weekend I'll continue to investigate my problem because I don't understand why previous rtorrent (0.9.7) worked fine while new one (0.9.8) shown me a crash.

Just to be sure that I have correct ~/.rtorrent.rc, this is it:

# This is an example resource file for rTorrent. Copy to
# ~/.rtorrent.rc and enable/modify the options as needed. Remember to
# uncomment the options you wish to enable.

## Instance layout (base paths)
method.insert = cfg.basedir,  private|const|string, (cat,"/home/vladimir/.cache/rtorrent/")
method.insert = cfg.download, private|const|string, (cat,"/mnt/data/")
method.insert = cfg.logs,     private|const|string, (cat,(cfg.basedir),"log/")
method.insert = cfg.logfile,  private|const|string, (cat,(cfg.logs),"rtorrent-",(system.time),".log")
method.insert = cfg.session,  private|const|string, (cat,(cfg.basedir),"session/")
method.insert = cfg.watch,    private|const|string, (cat,(cfg.basedir),"watch/")

execute.throw = sh, -c, (cat,\
  "mkdir -p \"",(cfg.download),"\" ",\
  "\"",(cfg.logs),"\" ",\
  "\"",(cfg.session),"\" ",\
  "\"",(cfg.watch),"\" ")

# Maximum and minimum number of peers to connect to per torrent.
throttle.max_uploads.set = 100
throttle.max_uploads.global.set = 250

throttle.min_peers.normal.set = 2
throttle.max_peers.normal.set = 1500
throttle.min_peers.seed.set = 2
throttle.max_peers.seed.set = 1500
trackers.numwant.set = 80

# min_peers = 1
# max_peers = 1000

# Same as above but for seeding completed torrents (-1 = same as downloading)
# min_peers_seed = -1
#max_peers_seed = 50

# Maximum number of simultanious uploads per torrent.
# max_uploads = 100

# Global upload and download rate in KiB. "0" for unlimited.
download_rate = 0
upload_rate = 0

# Default directory to save the downloaded torrents.
# directory.default.set = /mnt/data
directory.default.set = (cat, (cfg.download))

# Default session directory. Make sure you don't run multiple instance
# of rtorrent using the same session directory. Perhaps using a
# relative path?
# session.path.set = /home/vladimir/.rtorrent/session
session.path.set = (cat, (cfg.session))
session.save = yes

execute.nothrow = sh, -c, (cat, "echo >",\
  (session.path), "rtorrent.pid", " ",(system.pid))

# Watch a directory for new torrents, and stop those that have been
# deleted.
# schedule = watch_directory,5,5,load.start=/home/lomov/.rtorrent/watch/*.torrent
schedule2 = watch_load, 11, 10, ((load.verbose, (cat, (cfg.watch), "*.torrent")))
#schedule = untied_directory,5,5,stop_untied=

# Close torrents when diskspace is low.
# schedule = low_diskspace,5,60,close_low_diskspace=100M
schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M))

system.umask.set = 0027
system.cwd.set = (directory.default)

# Stop torrents when reaching upload ratio in percent,
# when also reaching total upload in bytes, or when
# reaching final upload ratio in percent.
# example: stop at ratio 2.0 with at least 200 MB uploaded, or else ratio 20.0
#schedule = ratio,60,60,"stop_on_ratio=200,200M,2000"

# The ip address reported to the tracker.
#ip = 127.0.0.1
#ip = rakshasa.no

# The ip address the listening socket and outgoing connections is
# bound to.
#bind = 127.0.0.1
#bind = rakshasa.no

# Port range to use for listening.
network.port_range.set = 40890-40891

# Start opening ports at a random position within the port range.
network.port_random.set = no

network.http.max_open.set = 150
network.max_open_files.set = 600
network.max_open_sockets.set = 300

# Check hash for finished torrents. Might be usefull until the bug is
# fixed that causes lack of diskspace not to be properly reported.
check_hash = yes

### trackers, dht, dht_port and peer_exchange should be commented for any version after rev. 1148
# From wikitutorial
#enable_trackers = yes
trackers.enable = yes

# Set whetever the client should try to connect to UDP trackers.
#use_udp_trackers = yes
trackers.use_udp.set = yes

# Alternative calls to bind and ip that should handle dynamic ip's.
#schedule = ip_tick,0,1800,ip=rakshasa
#schedule = bind_tick,0,1800,bind=rakshasa

# Encryption options, set to none (default) or any combination of the following:
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
#
# The example value allows incoming encrypted connections, starts unencrypted
# outgoing connections but retries with encryption if they fail, preferring
# plaintext to RC4 encryption after the encrypted handshake
#
#encryption = enable_retry,allow_incoming
protocol.encryption.set = none

# Encoding
encoding.add = utf8
encoding.add = utf-8
# encoding_list = utf-8

# Enable DHT support for trackerless torrents or when all trackers are down.
# May be set to "disable" (completely disable DHT), "off" (do not start DHT),
# "auto" (start and stop DHT as needed), or "on" (start DHT immediately).
# The default is "off". For DHT to work, a session directory must be defined.
# 
#dht = auto
dht.mode.set = auto

# UDP port to use for DHT. 
# 
#dht_port = 6881
dht.port.set = 6881

# Enable peer exchange (for torrents not marked private)
#
protocol.pex.set = yes

# proxy
network.http.proxy_address.set = "px1.blockme.site:23128"
# not sure about for what this one proxy is used.
#network.proxy_address.set = "px1.blockme.site:23128"

# Memory usage.
#max_memory_usage = 2147483648
# pieces.memory.max.set = 1800M

#
# Do not modify the following parameters unless you know what you're doing.
#

# Hash read-ahead controls how many MB to request the kernel to read
# ahead. If the value is too low the disk may not be fully utilized,
# while if too high the kernel might not be able to keep the read
# pages in memory thus end up trashing.
#hash_read_ahead = 10

# Interval between attempts to check the hash, in milliseconds.
#hash_interval = 100

# Number of attempts to check the hash while using the mincore status,
# before forcing. Overworked systems might need lower values to get a
# decent hash checking rate.
#hash_max_tries = 10

## Remote managment.
## Only if compiled with xml-rpc support.
# scgi_port = localhost:5000
# scgi_local = /var/run/rtorrent/rtorrent-rpc.socket

@chros73
Copy link
Contributor

chros73 commented Oct 18, 2019

~/.rtorrent.rc, this is it

I use these instead of yours' (and here's the complete example config):

# Encryption options (encryption), set to none (default) or any combination of the following: allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
# This will only allow encrypted connections: protocol.encryption.set = require,require_RC4
# The example value allows incoming encrypted connections, starts unencrypted outgoing connections but retries with encryption if they fail, preferring plaintext to RC4 encryption after the encrypted handshake
protocol.encryption.set = allow_incoming,prefer_plaintext,enable_retry

# Port range to use for listening.
network.port_range.set = 40890-40890

# Adding public DHT servers for easy bootstrapping
schedule2 = dht_node_1, 5, 0, "dht.add_node=router.utorrent.com:6881"
schedule2 = dht_node_2, 5, 0, "dht.add_node=dht.transmissionbt.com:6881"
schedule2 = dht_node_3, 5, 0, "dht.add_node=router.bitcomet.com:6881"
schedule2 = dht_node_4, 5, 0, "dht.add_node=dht.aelitis.com:6881"

# Check hash for finished torrents. (check_hash)
pieces.hash.on_completion.set = no

# you don't need this
#trackers.enable = yes

I don't understand why previous rtorrent (0.9.7) worked fine while new one (0.9.8) shown me a crash

Me neither :) , although the mentioned commit was introduced in v0.9.8

Isn't nullptr ... Still I didn't get why rtorrent crashes at this point and remembered that it is possible due to null pointer dereference.

As I said above, this shouldn't ever happen, that tells me your problem is something completely different.

On weekend I'll continue

I suggest try out @QDesjardin's packages, they should work fine (he worked on it during this week). (I can't help you with Arch specific issues since I never used it.)

@vp1981
Copy link
Author

vp1981 commented Oct 19, 2019

Okey,
I built both libtorrent-ps-ch and rtorrent-ps-ch packages and installed them on affected host, but I still get the same crash.

$ cd rtorrent-0.9.8/src
$ gdb ./rtorrent
(gdb) directory ./ui/
(gdb) run
Starting program: /home/vladimir/tmp/rtorrent-0.9.8/src/rtorrent 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7ffff6902700 (LWP 586693)]
[Detaching after fork from child process 586694]

Thread 1 "rtorrent" received signal SIGSEGV, Segmentation fault.
0x000055555566dece in ui::Root::save_input_history (this=0x555555794d60) at root.cc:462
462     Root::save_input_history() {
(gdb) bt
#0  0x000055555566dece in ui::Root::save_input_history (this=0x555555794d60) at root.cc:462
#1  0x00005555555bc911 in std::__invoke_impl<void, void (core::DownloadList::*&)(), core::DownloadList*&> (__f=<optimized out>, __f=<optimized out>, __t=<optimized out>) at /usr/include/c++/9.2.0/bits/invoke.h:70
#2  std::__invoke<void (core::DownloadList::*&)(), core::DownloadList*&> (__fn=<optimized out>) at /usr/include/c++/9.2.0/bits/invoke.h:95
#3  std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>::__call<void, rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&, 0ul>(std::tuple<rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&>&&, std::_Index_tuple<0ul>) (__args=..., this=<optimized out>) at /usr/include/c++/9.2.0/functional:400
#4  std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>::operator()<rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&, void>(rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (this=<optimized out>) at /usr/include/c++/9.2.0/functional:484
#5  object_convert_type<std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>, void>::operator()<rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > >(rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (arg1=..., arg2=..., this=<optimized out>) at command_helpers.h:182
#6  std::_Function_handler<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&), object_convert_type<std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>, void> >::_M_invoke(std::_Any_data const&, rpc::rt_triple<int, void*, void*>&&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (__functor=..., __args#0=..., __args#1=...) at /usr/include/c++/9.2.0/bits/std_function.h:286
#7  0x00005555556e5f72 in std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&)>::operator()(rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) const (__args#1=std::vector of length 1, capacity 1 = {...}, __args#0=..., this=0x55555580ffe8) at /usr/include/c++/9.2.0/bits/std_function.h:685
#8  rpc::command_base::_call<std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&)>, rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > >(rpc::command_base*, rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> >) (args=std::vector of length 10, capacity -977343605136 = {...}, target=..., cmd=0x55555580ffe8) at command.h:247
#9  rpc::command_base_call_list<rpc::rt_triple<int, void*, void*> > (rawCommand=0x55555580ffe8, target=..., rawArgs=...) at command.cc:122
#10 0x00005555556efc06 in rpc::CommandMap::call_command (this=this@entry=0x55555577f2e0 <rpc::commands>, key=<optimized out>, key@entry=0x7fffffffc630 "session.save", arg=..., target=...) at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#11 0x00005555557053ad in rpc::parse_command (target=..., first=0x7fffffffc9f2 "", last=<optimized out>) at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#12 0x0000555555707248 in rpc::parse_command_file (path="~/.rtorrent.rc") at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#13 0x000055555563de00 in apply_try_import (path="~/.rtorrent.rc") at command_events.cc:216
#14 0x0000555555647e0d in std::__invoke_impl<void, void (*&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (__f=<optimized out>)
    at /usr/include/c++/9.2.0/bits/invoke.h:89
#15 std::__invoke<void (*&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (__fn=<optimized out>) at /usr/include/c++/9.2.0/bits/invoke.h:95
#16 std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::__call<void, rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, 0ul>(std::tuple<rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>&&, std::_Index_tuple<0ul>) (__args=..., this=<optimized out>) at /usr/include/c++/9.2.0/functional:400
#17 std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()<rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, void>(rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=<optimized out>) at /usr/include/c++/9.2.0/functional:484
#18 object_convert_type<std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, void>::operator()<rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (arg1=..., arg2=..., this=<optimized out>) at command_helpers.h:182
#19 std::_Function_handler<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), object_convert_type<std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, void> >::_M_invoke(std::_Any_data const&, rpc::rt_triple<int, void*, void*>&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (__functor=..., __args#0=..., __args#1=...)
    at /usr/include/c++/9.2.0/bits/std_function.h:286
#20 0x00005555556e3976 in std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()(rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (__args#1="~/.rtorrent.rc", __args#0=..., this=0x555555808d28) at /usr/include/c++/9.2.0/bits/std_function.h:685
#21 rpc::command_base::_call<std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rpc::command_base*, rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (args="", target=..., cmd=0x555555808d28) at command.h:247
#22 rpc::command_base_call_string<rpc::rt_triple<int, void*, void*> > (rawCommand=0x555555808d28, target=..., rawArgs=...) at command.cc:106
#23 0x00005555556efc06 in rpc::CommandMap::call_command (this=this@entry=0x55555577f2e0 <rpc::commands>, key=<optimized out>, key@entry=0x7fffffffdcb0 "try_import", arg=..., target=...) at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#24 0x00005555557053ad in rpc::parse_command (target=..., first=0x55555572176f "", first@entry=0x555555721754 "try_import = ~/.rtorrent.rc", last=<optimized out>) at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#25 0x00005555555a8269 in rpc::parse_command_single (target=..., first=first@entry=0x555555721754 "try_import = ~/.rtorrent.rc") at /usr/include/c++/9.2.0/bits/stl_pair.h:260
#26 0x000055555559b0fa in main (argc=<optimized out>, argv=0x7fffffffe0b8) at /usr/include/c++/9.2.0/bits/stl_pair.h:260

I'll dig it further.

@vp1981
Copy link
Author

vp1981 commented Oct 19, 2019

@chros73

That would be strange, because:

load_input_history() is only called after initialize()
that calls init(Control c)
which should set Control before load_input_history() is called

If I read the stack correctly, the control even don't go to

control->initialize();
.

@QDesjardin
Copy link

What are your CFLAGS/CXXFLAGS in makepkg.conf?

@vp1981
Copy link
Author

vp1981 commented Oct 20, 2019

@QDesjardin nothing special, distro defaults:

$ grep 'C*FLAGS' /etc/makepkg.conf | grep -v '^#'
CPPFLAGS="-D_FORTIFY_SOURCE=2"
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt"
CXXFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
DEBUG_CFLAGS="-g -fvar-tracking-assignments"
DEBUG_CXXFLAGS="-g -fvar-tracking-assignments"

but that reminded me that I should set not only --enable-debug to configure for libtorrent/rtorrent but also set 'debug' in options.

@vp1981
Copy link
Author

vp1981 commented Oct 20, 2019

@chros73 seems your suggestions are correct and wrong at the same time:

(gdb) break main.cc:455
Breakpoint 2 at 0x417b0: file main.cc, line 456.
(gdb) break main.cc:471
Breakpoint 3 at 0x41829: file main.cc, line 472.
(gdb) run
Starting program: /home/vladimir/tmp/rtorrent/src/rtorrent 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7ffff68f6700 (LWP 635217)]

Thread 1 "rtorrent" hit Breakpoint 2, main (argc=1, argv=0x7fffffffe0d8) at main.cc:456
456         if (OptionParser::has_flag('n', argc, argv)) {
(gdb) next
459           char* config_dir = std::getenv("XDG_CONFIG_HOME");
(gdb) n
460           char* home_dir = std::getenv("HOME");
(gdb) n
462           if (config_dir != NULL && config_dir[0] == '/' &&
(gdb) n
465           } else if (home_dir != NULL && access((std::string(home_dir) + "/.config/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) {
(gdb) n
80            new_allocator() _GLIBCXX_USE_NOEXCEPT { }
(gdb) n
465           } else if (home_dir != NULL && access((std::string(home_dir) + "/.config/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) {
(gdb) n
260           constexpr pair(const _T1& __a, const _T2& __b)
(gdb) n
[Detaching after fork from child process 635235]

Thread 1 "rtorrent" received signal SIGSEGV, Segmentation fault.
0x000055555565358e in ui::Root::save_input_history (this=0x5555557709f0) at root.cc:462
462     Root::save_input_history() {

so the control even don't reach the line 474 (the line with control->initialize) and my "fix" is correct (it is wrong because the program shouldn't call the object before it was initialized but it is correct as makes the program run).

P.S. I changed location of .rtorrent.rc file simply moved it to $HOME/.config/rtorrent.

@vp1981
Copy link
Author

vp1981 commented Oct 20, 2019

Okey, I'm getting close to the reason of the crash (I think, I hope). Now I compiled rtorrent with -O0 -ggdb and see on what command in rtorrent.rc the rtorrent crashes:

(gdb) run
Starting program: /home/vladimir/tmp/rtorrent/src/rtorrent 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7ffff68f6700 (LWP 666871)]
[Detaching after fork from child process 666872]

Thread 1 "rtorrent" received signal SIGSEGV, Segmentation fault.
0x00005555555782d0 in Control::core (this=0x0) at control.h:93
93        core::Manager*      core()                        { return m_core; }
(gdb) bt
#0  0x00005555555782d0 in Control::core (this=0x0) at control.h:93
#1  0x000055555569899c in ui::Root::save_input_history (this=0x55555583a9f0) at root.cc:463
#2  0x00005555556c249a in core::DownloadList::session_save (this=0x55555583f4a0) at download_list.cc:97
#3  0x00005555555a48f2 in std::__invoke_impl<void, void (core::DownloadList::*&)(), core::DownloadList*&> (__f=@0x5555558b3d40: (void (core::DownloadList::*)(core::DownloadList * const)) 0x5555556c233e <core::DownloadList::session_save()>, 
    __t=@0x5555558b3d50: 0x55555583f4a0) at /usr/include/c++/9.2.0/bits/invoke.h:73
#4  0x00005555555a40f6 in std::__invoke<void (core::DownloadList::*&)(), core::DownloadList*&> (__fn=@0x5555558b3d40: (void (core::DownloadList::*)(core::DownloadList * const)) 0x5555556c233e <core::DownloadList::session_save()>, __args#0=@0x5555558b3d50: 0x55555583f4a0)
    at /usr/include/c++/9.2.0/bits/invoke.h:95
#5  0x00005555555a30cb in std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>::__call<void, rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&, 0ul>(std::tuple<rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&>&&, std::_Index_tuple<0ul>) (this=0x5555558b3d40, __args=...) at /usr/include/c++/9.2.0/functional:400
#6  0x00005555555a1f3f in std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>::operator()<rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&, void>(rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (this=0x5555558b3d40, __args#0=..., __args#1=std::vector of length 1, capacity 1 = {...}) at /usr/include/c++/9.2.0/functional:484
#7  0x00005555555a091b in object_convert_type<std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>, void>::operator()<rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > >(rpc::rt_triple<int, void*, void*> const&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (this=0x5555558b3d40, arg1=..., arg2=std::vector of length 1, capacity 1 = {...}) at command_helpers.h:182
#8  0x000055555559dbfa in std::_Function_handler<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&), object_convert_type<std::_Bind<void (core::DownloadList::*(core::DownloadList*))()>, void> >::_M_invoke(std::_Any_data const&, rpc::rt_triple<int, void*, void*>&&, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) (__functor=..., __args#0=..., __args#1=std::vector of length 1, capacity 1 = {...}) at /usr/include/c++/9.2.0/bits/std_function.h:286
#9  0x0000555555710dbc in std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&)>::operator()(rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&) const (this=0x5555558b3cf8, __args#0=..., __args#1=std::vector of length 1, capacity 1 = {...}) at /usr/include/c++/9.2.0/bits/std_function.h:690
#10 0x000055555570feeb in rpc::command_base::_call<std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > const&)>, rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> > >(rpc::command_base*, rpc::rt_triple<int, void*, void*>, std::vector<torrent::Object, std::allocator<torrent::Object> >) (cmd=0x5555558b3cf8, target=..., args=std::vector of length 1, capacity 1 = {...}) at command.h:245
#11 0x000055555570e0e4 in rpc::command_base_call_list<rpc::rt_triple<int, void*, void*> > (rawCommand=0x5555558b3cf8, target=..., rawArgs=...) at command.cc:122
#12 0x00005555557123ae in rpc::CommandMap::call_command (this=0x555555825d60 <rpc::commands>, key=0x7fffffffc480 "session.save", arg=..., target=...) at command_map.cc:171
#13 0x0000555555721c93 in rpc::parse_command (target=..., first=0x7fffffffc7e2 "", last=0x7fffffffc7e2 "") at parse_commands.cc:166
#14 0x00005555557221cc in rpc::parse_command_file (path="~/.config/rtorrent/rtorrent.rc") at parse_commands.cc:224
#15 0x0000555555671b37 in apply_try_import (path="~/.config/rtorrent/rtorrent.rc") at command_events.cc:216
#16 0x000055555557f9bb in std::__invoke_impl<void, void (*&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (
    __f=@0x5555558ac1e0: 0x555555671b0e <apply_try_import(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, __args#0="~/.config/rtorrent/rtorrent.rc") at /usr/include/c++/9.2.0/bits/invoke.h:60
#17 0x000055555557f150 in std::__invoke<void (*&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (
    __fn=@0x5555558ac1e0: 0x555555671b0e <apply_try_import(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, __args#0="~/.config/rtorrent/rtorrent.rc") at /usr/include/c++/9.2.0/bits/invoke.h:95
#18 0x0000555555677ce5 in std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::__call<void, rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, 0ul>(std::tuple<rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>&&, std::_Index_tuple<0ul>) (this=0x5555558ac1e0, __args=...)
    at /usr/include/c++/9.2.0/functional:400
#19 0x0000555555677889 in std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()<rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, void>(rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=0x5555558ac1e0, __args#0=..., __args#1="~/.config/rtorrent/rtorrent.rc")
    at /usr/include/c++/9.2.0/functional:484
#20 0x0000555555676fcb in object_convert_type<std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, void>::operator()<rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rpc::rt_triple<int, void*, void*> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=0x5555558ac1e0, arg1=..., arg2="~/.config/rtorrent/rtorrent.rc") at command_helpers.h:182
#21 0x0000555555676539 in std::_Function_handler<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), object_convert_type<std::_Bind<void (*(std::_Placeholder<2>))(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, void> >::_M_invoke(std::_Any_data const&, rpc::rt_triple<int, void*, void*>&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (__functor=..., __args#0=..., 
    __args#1="~/.config/rtorrent/rtorrent.rc") at /usr/include/c++/9.2.0/bits/std_function.h:286
#22 0x00005555557109f4 in std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()(rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (this=0x5555558ac198, __args#0=..., __args#1="~/.config/rtorrent/rtorrent.rc") at /usr/include/c++/9.2.0/bits/std_function.h:690
#23 0x000055555570fb59 in rpc::command_base::_call<std::function<torrent::Object (rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rpc::command_base*, rpc::rt_triple<int, void*, void*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (cmd=0x5555558ac198, target=..., args="~/.config/rtorrent/rtorrent.rc")
    at command.h:245
#24 0x000055555570d648 in rpc::command_base_call_string<rpc::rt_triple<int, void*, void*> > (rawCommand=0x5555558ac198, target=..., rawArgs=...) at command.cc:106
#25 0x00005555557123ae in rpc::CommandMap::call_command (this=0x555555825d60 <rpc::commands>, key=0x7fffffffdd10 "try_import", arg=..., target=...) at command_map.cc:171
#26 0x0000555555721c93 in rpc::parse_command (target=..., first=0x555555732b23 "", last=0x555555732b23 "") at parse_commands.cc:166
#27 0x0000555555577bea in rpc::parse_command_single (target=..., first=0x555555732af8 "try_import = ~/.config/rtorrent/rtorrent.rc") at rpc/parse_commands.h:67
#28 0x000055555557525f in main (argc=1, argv=0x7fffffffe108) at main.cc:466

Now I don't know how to proceed further except to run step in gdb. Any ideas?

@chros73
Copy link
Contributor

chros73 commented Oct 20, 2019

Ok, so you don't have issue anymore with the load_input_history method, but the save_input_history method:

Remove/comment out the session.save = yes from your rtorrent config:

  • seems, for whatever reason, it triggers the save_input_history method before the Control object is passed into root.cc via initialize() method in main.cc
  • btw, that line isn't valid in your config (doesn't accept any argument), use this instead

If it fixes your issue, you can try to fix it and create a pull request for it :)

@vp1981
Copy link
Author

vp1981 commented Oct 21, 2019

@chros73 Yes, you are right. I commented out this option rebuild the rtorrent package without my dirty hack and rtorrent launched without issue.

Now about that session.save. I don't remember when and why I set this option (it was long ago, may be 10 years ago, that time it was session_save) and I didn't find it in configuration template page but seems was fooled by sed migration script because it shows how to transform session_save to session.save but nothing more. The community documentation doesn't give any more information about the option except that is should be a integer (?).

I'll continue to investigate the issue because it is unexpected behavior: rtorrent 0.9.7 works fine but 0.9.8 assumes that the session.save=yes means immediately save the session (at startup).

@chros73
Copy link
Contributor

chros73 commented Oct 21, 2019

session.save = yes config entry
... about the option except that is should be a integer (?)

I went back in time, it was introduced in v0.5.1 as session_save ini like entry, and it never accepted any value, it was always the same command as it is now. So proper way to use it in the config is: session.save=.
Actually, the session_save ini like entry was removed at some point from the redirects, probably to do not be able to set it in the config as it was.

My point is:

  • it doesn't make sense to use this option in your config the way you used, because it fires up session_save() method at the beginning of everything:

rtorrent 0.9.7 works fine but 0.9.8 assumes that the session.save=yes means immediately save the session (at startup)

That's not the issue, it worked the same way in the last 5-7 years at least. :) The problem is that now is crashing (due to the commit you found), and you're right about this: rtorrent should never crash, no matter what silly config entries a user have :)

The solution for this is exactly what you suggested above, replace this check to this (tested on Ubuntu):

if (m_control == NULL || !m_control->core()->download_store()->is_enabled())

Since you worked hard on this already, the honour of creating a pull request for this can be Yours :)

Thanks for the bug report!

@chros73
Copy link
Contributor

chros73 commented Oct 22, 2019

PR has been created: #929

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants