diff --git a/doc/log_proc_vmmap.sh b/doc/log_proc_vmmap.sh new file mode 100644 index 00000000..3f827955 --- /dev/null +++ b/doc/log_proc_vmmap.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cat /proc/$PPID/maps > $1 diff --git a/doc/log_vmmap.sh b/doc/log_vmmap.sh new file mode 100755 index 00000000..893d78d8 --- /dev/null +++ b/doc/log_vmmap.sh @@ -0,0 +1,2 @@ +#!/bin/bash +vmmap -interleaved $PPID > $1 diff --git a/src/command_local.cc b/src/command_local.cc index e8763808..0c0890da 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,9 @@ #include #include #include +#include +#include "core/download.h" #include "core/download_list.h" #include "core/download_store.h" #include "core/manager.h" @@ -167,6 +170,27 @@ group_insert(const torrent::Object::list_type& args) { return name; } +torrent::Object +log_vmmap_dump(const std::string& str) { + core::DownloadList* d_list = control->core()->download_list(); + std::vector all_mappings; + + for (core::DownloadList::iterator itr = d_list->begin(), last = d_list->end(); itr != last; itr++) { + std::vector tmp_mappings = torrent::chunk_list_mapping((*itr)->download()); + + all_mappings.insert(all_mappings.end(), tmp_mappings.begin(), tmp_mappings.end()); + } + + FILE* log_file = fopen(str.c_str(), "w"); + + for (std::vector::iterator itr = all_mappings.begin(), last = all_mappings.end(); itr != last; itr++) { + fprintf(log_file, "%8p-%8p [%5llxk]\n", itr->ptr, (char*)itr->ptr + itr->length, itr->length / 1024); + } + + fclose(log_file); + return torrent::Object(); +} + void initialize_command_local() { torrent::ChunkManager* chunkManager = torrent::chunk_manager(); @@ -245,8 +269,9 @@ initialize_command_local() { CMD2_EXECUTE ("execute_capture", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture); CMD2_EXECUTE ("execute_capture_nothrow", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture); - CMD2_ANY_STRING ("log.execute", std::tr1::bind(&apply_log, std::tr1::placeholders::_2, 0)); - CMD2_ANY_STRING_V("log.xmlrpc", std::tr1::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::tr1::placeholders::_2)); + CMD2_ANY_STRING ("log.execute", std::tr1::bind(&apply_log, std::tr1::placeholders::_2, 0)); + CMD2_ANY_STRING ("log.vmmap.dump", std::tr1::bind(&log_vmmap_dump, std::tr1::placeholders::_2)); + CMD2_ANY_STRING_V("log.xmlrpc", std::tr1::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::tr1::placeholders::_2)); // TODO: Convert to new command types: *rpc::command_base::argument(0) = "placeholder.0"; diff --git a/src/main.cc b/src/main.cc index 858fe0d0..129747e3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -804,6 +804,8 @@ do_panic(int signum) { SignalHandler::set_default(signum); display::Canvas::cleanup(); + // Use printf here instead... + std::cout << "Caught " << SignalHandler::as_string(signum) << ", dumping stack:" << std::endl; #ifdef USE_EXECINFO @@ -820,6 +822,19 @@ do_panic(int signum) { std::cout << "Stack dump not enabled." << std::endl; #endif + // Dumping virtual memory map information to file: + // char dump_path[256]; + // snprintf(dump_path, 256, "./rtorrent.map.%u", getpid()); + + // int dump_fd = open(dump_path, O_RDWR | O_CREAT); + + // if (dump_fd == -1) { + // printf("Could not create vmmap dump file '%s'.", dump_path); + // goto do_panic_exit; + // } + +// do_panic_exit: + if (signum == SIGBUS) std::cout << "A bus error probably means you ran out of diskspace." << std::endl; diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index 6d3b8459..58db1d0f 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -66,7 +66,7 @@ ElementDownloadList::ElementDownloadList() : m_bindings['\x13'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.start="); m_bindings['\x04'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "branch=d.state=,d.stop=,d.erase="); m_bindings['\x0B'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.ignore_commands.set=1; d.stop=; d.close="); - m_bindings['\x12'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.check_hash="); + m_bindings['\x12'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.complete.set=0; d.check_hash="); m_bindings['\x05'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "f.multicall=,f.set_create_queued=,f.set_resize_queued=; print=\"Queued create/resize of files in torrent.\"");