On Sun, Mar 7, 2010 at 3:35 AM, Pavel Sanda <[email protected]> wrote:
> you rely not only on gdb but also on bash i think. this wont help on win32.
The bash code is easy to remove. I am more worried about GDB. For
example the attached patch should work* on Windows if
a) Windows people actually use (or are willing/able to use) GDB
b) GDB works on windows the way I want it to.
I suspect many Windows people would prefer not to have to install GDB.
Apparently it is possible to use e.g. the MSVC debugger on the command
line and "attach it to the process by running vsjitdebugger.exe -p
ProcessId from the Windows command line".
http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx
I suspect that it would be easy for a Windows person to change a
couple of lines and check for vsjitdebugger or whatever their
favourite debugging tool is, but I don't know how they like to debug
and I don't really have a way of testing if it works.
* work as in collect backtraces for LASSERT. It does not try to do
this for SIGABRT or SIGSEGV. These are more tricky as we need
async-safe code. IMHO not much point worrying about this when we are
still considering how the simpler case could work.
> one can launch another binary which just gets lyx backtrace on stdin and
> puts into QEditText.
I'd pass in the LyX pid and do all of the debugging work inside the
second binary (would could just be a second instance of LyX, e.g. run
as lyx --debug-pid=12345 ).
--
John C. McCabe-Dansted
Index: support/lassert.cpp
===================================================================
--- support/lassert.cpp (revision 33650)
+++ support/lassert.cpp (working copy)
@@ -14,13 +14,104 @@
#include <boost/assert.hpp>
+#include <string>
+
+
+#ifndef NO_DEBUG_HELPER
+#include "support/lassert.h"
+#include "./support/docstring.h"
+#include "support/FileName.h"
+#include "support/os.h"
+
+#include "support/filetools.h"
+#include "support/gettext.h"
+#include "support/lstrings.h"
+
+#include <boost/regex.hpp>
+#include <QtGui/qmessagebox.h>
+
+#include <set>
+#include <cstdlib>
+#include <sstream>
+
+using namespace lyx;
+using namespace lyx::support;
+#endif
+
+
+using namespace std;
+
namespace lyx {
+// We could use callbacks instead of QtGUI here.
+// If not we should probably remove these
+void doAssert_callback_default(docstring s) { LYXERR0(s); }
+doAssert_callback_t doAssert_callback = doAssert_callback_default;
+void doAssert_set_callback(doAssert_callback_t c) {
+ doAssert_callback = c;
+}
+
+//doAssert_callback_t doAssert_callback = doAssert_callback_default;
+
void doAssert(char const * expr, char const * file, long line)
{
- LYXERR0("ASSERTION " << expr << " VIOLATED IN " << file << ":" << line);
+ stringstream assert_description;
+ assert_description << "ASSERTION " << expr << " VIOLATED IN " << file << ":" << line;
+
+ string assert_str = assert_description.str();
+
+ LYXERR0(assert_str);
// comment this out if not needed
+ // BOOST_ASSERT(false);
+
+#ifdef NO_DEBUG_HELPER
BOOST_ASSERT(false);
+#else
+ // We don't report the same assertion multiple times, because LyX sometimes
+ // produces the same assertion hundreds of times in a row.
+ static set<string> reported_assertions;
+ if (reported_assertions.find(assert_str) == reported_assertions.end()) {
+ // Is it safe to use tempName inside LASSERT?
+ FileName gdb_cmd_FName = FileName::tempName("lyx.gdb.command.XXXXXXXX");
+ string gdb_cmd_filename = gdb_cmd_FName.absFilename();
+ FILE* gdb_cmd_file = fopen(gdb_cmd_filename.c_str(), "w");
+ BOOST_ASSERT(gdb_cmd_file);
+ fputs("set height 0\nbt\nq\nq\nq\nq",gdb_cmd_file);
+ string backtrace_filename = FileName::tempName("lyx.backtrace.XXXXXXXX").absFilename();
+ fclose(gdb_cmd_file);
+ std::stringstream gdb_cmd;
+ gdb_cmd << "gdb -q " << os::utf8_argv(0) << " " << getpid()
+ << " -x " << gdb_cmd_filename << " > " << backtrace_filename;
+ LYXERR0("Generating backtrace\n");
+ LYXERR0(gdb_cmd.str());
+ LYXERR0("GDB RESULT: " << system(gdb_cmd.str().c_str()) << "\n");
+ LYXERR0("Backtrace generated\n");
+ gdb_cmd_FName.removeFile();
+
+ const docstring str = bformat(_("LyX has triggered the assertion\n\n"
+ "%1$s\n\n"
+ "Sorry, you have found a bug in LyX. \n"
+ "Please read the bug-reporting instructions \n"
+ "in Help->Introduction and send us a bug report, \n"
+ "and attach the backtrace file\n\n%2$s\n\n"
+ "Thanks !."),
+ from_utf8(assert_description.str()),
+ from_utf8(backtrace_filename));
+
+ // We could use a callback instead of using QtGui here
+ // doAssert_callback(str);
+
+ QMessageBox::critical( (QWidget*)0,
+ QString(to_utf8(_("Assertion Triggered")).c_str()),
+ QString(to_utf8(str).c_str()) );
+
+ reported_assertions.insert(assert_str);
+ }
+#endif
+
+// Cannot use frontend from lassert
+// frontend::Alert::error(_("Export Warning!"), str);
+
}
} // namespace lyx