diff --git a/code/nel/include/nel/misc/report.h b/code/nel/include/nel/misc/report.h index 6bf3df959..11745b6e3 100644 --- a/code/nel/include/nel/misc/report.h +++ b/code/nel/include/nel/misc/report.h @@ -21,8 +21,21 @@ namespace NLMISC { -/// Prepares the error report, writes it to disk and launches the error reporter -void report ( const std::string &body ); +/** Display a custom message box. + * + * \param title set the title of the report. If empty, it'll display "NeL report". + * \param header message displayed before the edit text box. If empty, it displays the default message. + * \param body message displayed in the edit text box. This string will be sent by email. + * \param debugButton 0 for disabling it, 1 for enable with default behaviors (generate a breakpoint), 2 for enable with no behavior + * + * + * + * \return the button clicked or error + */ + +enum TReportResult { ReportDebug, ReportIgnore, ReportQuit, ReportError }; + +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const std::string &attachedFile = ""); /** call this in the main of your appli to enable email: setReportEmailFunction (sendEmail); */ diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp index 67c8cb0f3..aaa551f1f 100644 --- a/code/nel/src/misc/debug.cpp +++ b/code/nel/src/misc/debug.cpp @@ -553,7 +553,7 @@ public: // yoyo: allow only to send the crash report once. Because users usually click ignore, // which create noise into list of bugs (once a player crash, it will surely continues to do it). bool i = false; - report ( _Reason ); + report (progname+shortExc, "", subject, _Reason, true, 1, true, 1, !isCrashAlreadyReported(), i, NL_CRASH_DUMP_FILE); // no more sent mail for crash setCrashAlreadyReported(true); diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp index 8296d1c0b..35ae27964 100644 --- a/code/nel/src/misc/displayer.cpp +++ b/code/nel/src/misc/displayer.cpp @@ -529,7 +529,114 @@ void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mes // in release "" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { - + + bool needSpace = false; +// stringstream ss; + string str; + + // create the string for the clipboard + + if (args.Date != 0) + { + str += dateToHumanString(args.Date); + needSpace = true; + } + + if (args.LogType != CLog::LOG_NO) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += logTypeToString(args.LogType); + needSpace = true; + } + + if (!args.ProcessName.empty()) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += args.ProcessName; + needSpace = true; + } + + if (args.FileName != NULL) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += CFile::getFilename(args.FileName); + needSpace = true; + } + + if (args.Line != -1) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += NLMISC::toString(args.Line); + needSpace = true; + } + + if (args.FuncName != NULL) + { + //if (needSpace) { ss << " "; needSpace = false; } + if (needSpace) { str += " "; needSpace = false; } + str += args.FuncName; + needSpace = true; + } + + if (needSpace) { str += ": "; needSpace = false; } + + str += message; + + CSystemUtils::copyTextToClipboard(str); + + // create the string on the screen + needSpace = false; +// stringstream ss2; + string str2; + +#ifdef NL_DEBUG + if (!args.ProcessName.empty()) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += args.ProcessName; + needSpace = true; + } + + if (args.FileName != NULL) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += CFile::getFilename(args.FileName); + needSpace = true; + } + + if (args.Line != -1) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += NLMISC::toString(args.Line); + needSpace = true; + } + + if (args.FuncName != NULL) + { + if (needSpace) { str2 += " "; needSpace = false; } + str2 += args.FuncName; + needSpace = true; + } + + if (needSpace) { str2 += ": "; needSpace = false; } + +#endif // NL_DEBUG + + str2 += message; + str2 += "\n\n(this message was copied in the clipboard)"; + +/* if (IsDebuggerPresent ()) + { + // Must break in assert call + DebugNeedAssert = true; + } + else +*/ { + // Display the report string body; @@ -549,8 +656,69 @@ void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *m body += "Reason: " + toString(message); body += args.CallstackAndLog; - - report( body ); + + string subject; + + // procname is host/service_name-sid we only want the service_name to avoid redondant mail + string procname; + string::size_type pos = args.ProcessName.find ("/"); + if (pos == string::npos) + { + procname = args.ProcessName; + } + else + { + string::size_type pos2 = args.ProcessName.find ("-", pos+1); + if (pos2 == string::npos) + { + procname = args.ProcessName.substr (pos+1); + } + else + { + procname = args.ProcessName.substr (pos+1, pos2-pos-1); + } + } + + subject += procname + " NeL " + toString(LogTypeToString[0][args.LogType]) + " " + (args.FileName?string(args.FileName):"") + " " + toString(args.Line) + " " + (args.FuncName?string(args.FuncName):""); + + // Check the envvar NEL_IGNORE_ASSERT + if (getenv ("NEL_IGNORE_ASSERT") == NULL) + { + // yoyo: allow only to send the crash report once. Because users usually click ignore, + // which create noise into list of bugs (once a player crash, it will surely continues to do it). + std::string filename = getLogDirectory() + NL_CRASH_DUMP_FILE; + + if (ReportDebug == report (args.ProcessName + " NeL " + toString(logTypeToString(args.LogType, true)), "", subject, body, true, 2, true, 1, !isCrashAlreadyReported(), IgnoreNextTime, filename.c_str())) + { + INelContext::getInstance().setDebugNeedAssert(true); + } + + // no more sent mail for crash + setCrashAlreadyReported(true); + } + +/* // Check the envvar NEL_IGNORE_ASSERT + if (getenv ("NEL_IGNORE_ASSERT") == NULL) + { + // Ask the user to continue, debug or ignore + int result = MessageBox (NULL, ss2.str().c_str (), logTypeToString(args.LogType, true), MB_ABORTRETRYIGNORE | MB_ICONSTOP); + if (result == IDABORT) + { + // Exit the program now + exit (EXIT_FAILURE); + } + else if (result == IDRETRY) + { + // Give the debugger a try + DebugNeedAssert = true; + } + else if (result == IDIGNORE) + { + // Continue, do nothing + } + } +*/ } + } diff --git a/code/nel/src/misc/report.cpp b/code/nel/src/misc/report.cpp index 54c456ade..b165e29f5 100644 --- a/code/nel/src/misc/report.cpp +++ b/code/nel/src/misc/report.cpp @@ -22,8 +22,23 @@ #include "nel/misc/report.h" #include "nel/misc/path.h" +#ifdef NL_OS_WINDOWS +# ifndef NL_COMP_MINGW +# define NOMINMAX +# endif +# include +# include +# include +#endif // NL_OS_WINDOWS + +#define NL_NO_DEBUG_FILES 1 + using namespace std; +#ifdef DEBUG_NEW + #define new DEBUG_NEW +#endif + namespace NLMISC { @@ -37,7 +52,7 @@ void setReportEmailFunction (void *emailFunction) EmailFunction = (TEmailFunction)emailFunction; } -void report ( const std::string &body ) +TReportResult report (const std::string &title, const std::string &header, const std::string &subject, const std::string &body, bool enableCheckIgnore, uint debugButton, bool ignoreButton, sint quitButton, bool sendReportButton, bool &ignoreNextTime, const string &attachedFile) { std::string fname = "rcerrorlog.txt"; @@ -63,6 +78,8 @@ void report ( const std::string &body ) #endif // quit without calling atexit or static object dtors. abort(); + + return ReportQuit; }