+/** -*- c-basic-offset: 4; default-tab-width: 4; indent-tabs-mode: nil; -*- */
+
// Copyright 2007 Edd Dawson.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
struct find_data
{
std::string func;
+ unsigned int line;
asymbol **symbol_table;
bfd_vma counter;
};
bfd_close(abfd_);
}
- std::string get_function_name(DWORD offset)
+ std::pair<std::string, unsigned int> get_function_name_and_line(DWORD offset)
{
find_data data;
data.symbol_table = symbol_table_;
bfd_map_over_sections(abfd_, &find_function_name_in_section, &data);
- return data.func;
+ return std::make_pair(data.func, data.line);
}
private:
const char *file = 0;
unsigned line = 0;
- if (bfd_find_nearest_line(abfd, sec, data.symbol_table, data.counter - vma, &file, &func, &line) && func)
+ if (bfd_find_nearest_line(abfd, sec, data.symbol_table, data.counter - vma, &file, &func, &line) && func) {
data.func = demangle(func);
+ data.line = line;
+ }
}
private:
module_name = module_name_raw;
#if defined(__MINGW32__)
- std::string func = bfdc.get_function_name(frame.AddrPC.Offset);
+ std::pair<std::string, unsigned int> func_and_line = bfdc.get_function_name_and_line(frame.AddrPC.Offset);
- if (func.empty())
+ if (func_and_line.first.empty())
{
#if defined(_WIN64)
DWORD64 dummy = 0;
DWORD dummy = 0;
#endif
BOOL got_symbol = SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol);
- func = got_symbol ? symbol->Name : unknown_function;
+ func_and_line.first = got_symbol ? symbol->Name : unknown_function;
}
#else
DWORD dummy = 0;
std::string func = got_symbol ? symbol->Name : unknown_function;
#endif
- dbg::stack_frame f(reinterpret_cast<const void *>(frame.AddrPC.Offset), func, module_name);
+ dbg::stack_frame f(reinterpret_cast<const void *>(frame.AddrPC.Offset), func_and_line.first, func_and_line.second, module_name);
frames.push_back(f);
}
}
namespace dbg
{
- stack_frame::stack_frame(const void *instruction, const std::string &function, const std::string &module) :
+ stack_frame::stack_frame(const void *instruction, const std::string &function, unsigned int line, const std::string &module) :
instruction(instruction),
function(function),
+ line(line),
module(module)
{
}
std::ostream &operator<< (std::ostream &out, const stack_frame &frame)
{
- return out << frame.instruction << ": " << frame.function << " in " << frame.module;
+ return out << frame.instruction << ": " << frame.function << ":" << frame.line << " in " << frame.module;
}
stack::stack(depth_type limit)
+/** -*- c-basic-offset: 4; default-tab-width: 4; indent-tabs-mode: nil; -*- */
+
// Copyright 2007 Edd Dawson.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//! the name of the corresponding function and the "module" (executable or library) in which the function resides.
struct stack_frame
{
- stack_frame(const void *instruction, const std::string &function, const std::string &module);
+ stack_frame(const void *instruction, const std::string &function, unsigned int line, const std::string &module);
const void *instruction;
std::string function;
+ unsigned int line;
std::string module;
};
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>
+#include <glib.h>
#include <openjpeg.h>
#include <openssl/md5.h>
#include <magick/MagickCore.h>
#include "filter.h"
#include "sound_processor.h"
#include "config.h"
+#ifdef DVDOMATIC_WINDOWS
+#include "stack.hpp"
+#endif
#include "i18n.h"
using std::max;
using std::multimap;
using std::pair;
+using std::ofstream;
using boost::shared_ptr;
using boost::lexical_cast;
using boost::optional;
using libdcp::Size;
boost::thread::id ui_thread;
+boost::filesystem::path backtrace_file;
/** Convert some number of seconds to a string representation
* in hours, minutes and seconds.
return t.tv_sec + (double (t.tv_usec) / 1e6);
}
+#ifdef DVDOMATIC_WINDOWS
+LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS *)
+{
+ dbg::stack s;
+ ofstream f (backtrace_file.string().c_str());
+ std::copy(s.begin(), s.end(), std::ostream_iterator<dbg::stack_frame>(f, "\n"));
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
/** Call the required functions to set up DVD-o-matic's static arrays, etc.
* Must be called from the UI thread, if there is one.
*/
void
dvdomatic_setup ()
{
+#ifdef DVDOMATIC_WINDOWS
+ backtrace_file /= g_get_user_config_dir ();
+ backtrace_file /= "backtrace.txt";
+ SetUnhandledExceptionFilter(exception_handler);
+#endif
+
avfilter_register_all ();
Format::setup_formats ();