Try to make scope info logging more robust.
Add checks for validity of Vehicle ptrs in scope_dumper::VehicleInfo. In Unix mode, try to handle SIGSEGVs when dumping scope info.
This commit is contained in:
@@ -81,6 +81,13 @@ char *CrashLog::LogCompiler(char *buffer, const char *last) const
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SCOPE_INFO
|
||||||
|
/* virtual */ char *CrashLog::LogScopeInfo(char *buffer, const char *last) const
|
||||||
|
{
|
||||||
|
return buffer + WriteScopeLog(buffer, last);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes OpenTTD's version to the buffer.
|
* Writes OpenTTD's version to the buffer.
|
||||||
* @param buffer The begin where to write at.
|
* @param buffer The begin where to write at.
|
||||||
|
@@ -80,6 +80,16 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual char *LogModules(char *buffer, const char *last) const;
|
virtual char *LogModules(char *buffer, const char *last) const;
|
||||||
|
|
||||||
|
#ifdef USE_SCOPE_INFO
|
||||||
|
/**
|
||||||
|
* Writes the scope info log to the buffer.
|
||||||
|
* This may only be called when IsMainThread() returns true
|
||||||
|
* @param buffer The begin where to write at.
|
||||||
|
* @param last The last position in the buffer to write to.
|
||||||
|
* @return the position of the \c '\0' character after the buffer.
|
||||||
|
*/
|
||||||
|
virtual char *LogScopeInfo(char *buffer, const char *last) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
char *LogOpenTTDVersion(char *buffer, const char *last) const;
|
char *LogOpenTTDVersion(char *buffer, const char *last) const;
|
||||||
char *LogConfiguration(char *buffer, const char *last) const;
|
char *LogConfiguration(char *buffer, const char *last) const;
|
||||||
|
@@ -251,6 +251,38 @@ class CrashLogUnix : public CrashLog {
|
|||||||
#endif
|
#endif
|
||||||
return buffer + seprintf(buffer, last, "\n");
|
return buffer + seprintf(buffer, last, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_SCOPE_INFO) && defined(__GLIBC__)
|
||||||
|
/**
|
||||||
|
* This is a wrapper around the generic LogScopeInfo function which sets
|
||||||
|
* up a signal handler to catch any SIGSEGVs which may occur due to invalid data
|
||||||
|
*/
|
||||||
|
/* virtual */ char *LogScopeInfo(char *buffer, const char *last) const
|
||||||
|
{
|
||||||
|
logStacktraceSavedBuffer = buffer;
|
||||||
|
|
||||||
|
if (setjmp(logStacktraceJmpBuf) != 0) {
|
||||||
|
buffer = logStacktraceSavedBuffer;
|
||||||
|
buffer += seprintf(buffer, last, "\nSomething went seriously wrong when attempting to dump the scope info (SIGSEGV in signal handler).\n");
|
||||||
|
buffer += seprintf(buffer, last, "This is probably due to an invalid pointer or other corrupt data.\n\n");
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGSEGV, LogStacktraceSigSegvHandler);
|
||||||
|
sigset_t sigs;
|
||||||
|
sigset_t oldsigs;
|
||||||
|
sigemptyset(&sigs);
|
||||||
|
sigaddset(&sigs, SIGSEGV);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &sigs, &oldsigs);
|
||||||
|
|
||||||
|
buffer = this->CrashLog::LogScopeInfo(buffer, last);
|
||||||
|
|
||||||
|
signal(SIGSEGV, SIG_DFL);
|
||||||
|
sigprocmask(SIG_SETMASK, &oldsigs, NULL);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* A crash log is always generated by signal.
|
* A crash log is always generated by signal.
|
||||||
|
@@ -56,10 +56,18 @@ const char *scope_dumper::VehicleInfo(const Vehicle *v)
|
|||||||
const char *last = lastof(this->buffer);
|
const char *last = lastof(this->buffer);
|
||||||
if (v) {
|
if (v) {
|
||||||
b += seprintf(b, last, "veh: %u: (", v->index);
|
b += seprintf(b, last, "veh: %u: (", v->index);
|
||||||
|
if (Vehicle::GetIfValid(v->index) != v) {
|
||||||
|
b += seprintf(b, last, "INVALID PTR: %p)", v);
|
||||||
|
return this->buffer;
|
||||||
|
}
|
||||||
SetDParam(0, v->index);
|
SetDParam(0, v->index);
|
||||||
b = GetString(b, STR_VEHICLE_NAME, last);
|
b = GetString(b, STR_VEHICLE_NAME, last);
|
||||||
if (v->First() && v->First() != v) {
|
if (v->First() && v->First() != v) {
|
||||||
b += seprintf(b, last, "), front: %u: (", v->First()->index);
|
b += seprintf(b, last, "), front: %u: (", v->First()->index);
|
||||||
|
if (Vehicle::GetIfValid(v->First()->index) != v->First()) {
|
||||||
|
b += seprintf(b, last, "INVALID PTR: %p)", v->First());
|
||||||
|
return this->buffer;
|
||||||
|
}
|
||||||
SetDParam(0, v->First()->index);
|
SetDParam(0, v->First()->index);
|
||||||
b = GetString(b, STR_VEHICLE_NAME, last);
|
b = GetString(b, STR_VEHICLE_NAME, last);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user