Files @ r27443:1150c64644d0
Branch filter:

Location: cpp/openttd-patchpack/source/src/os/unix/crashlog_unix.cpp - annotation

Loïc Guilloux
Fix: Check max member count in squirrel classes (#10883)

Manual cherry-pick from https://github.com/albertodemichelis/squirrel/commit/23a0620658714b996d20da3d4dd1a0dcf9b0bd98
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r14269:cb886fbeaf44
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r15214:245fcdeca80a
r15214:245fcdeca80a
r15214:245fcdeca80a
r15214:245fcdeca80a
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r27432:005dbba2ae93
r27432:005dbba2ae93
r27432:005dbba2ae93
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r27432:005dbba2ae93
r27432:005dbba2ae93
r27432:005dbba2ae93
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r26818:9df12eaf020a
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r27432:005dbba2ae93
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r13814:efdf86742c58
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r13499:0af2aac7f5aa
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r27223:23146c90355d
r27404:8b233646def8
r27404:8b233646def8
r12959:bcf2bd652e20
r12950:14eee29b545d
r12950:14eee29b545d
r14269:cb886fbeaf44
r27404:8b233646def8
r27404:8b233646def8
r27404:8b233646def8
r14269:cb886fbeaf44
r14269:cb886fbeaf44
r14269:cb886fbeaf44
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12959:bcf2bd652e20
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r12950:14eee29b545d
r25047:a8e131d1e25b
r25047:a8e131d1e25b
r25047:a8e131d1e25b
r25047:a8e131d1e25b
/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file crashlog_unix.cpp Unix crash log handler */

#include "../../stdafx.h"
#include "../../crashlog.h"
#include "../../string_func.h"
#include "../../gamelog.h"
#include "../../saveload/saveload.h"

#include <errno.h>
#include <signal.h>
#include <sys/utsname.h>

#if defined(__GLIBC__)
/* Execinfo (and thus making stacktraces) is a GNU extension */
#	include <execinfo.h>
#elif defined(SUNOS)
#	include <ucontext.h>
#	include <dlfcn.h>
#endif

#if defined(__NetBSD__)
#include <unistd.h>
#endif

#include "../../safeguards.h"

/**
 * Unix implementation for the crash logger.
 */
class CrashLogUnix : public CrashLog {
	/** Signal that has been thrown. */
	int signum;

	void LogOSVersion(std::back_insert_iterator<std::string> &output_iterator) const override
	{
		struct utsname name;
		if (uname(&name) < 0) {
			 fmt::format_to(output_iterator, "Could not get OS version: {}\n", strerror(errno));
			 return;
		}

		fmt::format_to(output_iterator,
				"Operating system:\n"
				" Name:     {}\n"
				" Release:  {}\n"
				" Version:  {}\n"
				" Machine:  {}\n",
				name.sysname,
				name.release,
				name.version,
				name.machine
		);
	}

	void LogError(std::back_insert_iterator<std::string> &output_iterator, const std::string_view message) const override
	{
		fmt::format_to(output_iterator,
			   "Crash reason:\n"
				" Signal:  {} ({})\n"
				" Message: {}\n\n",
				strsignal(this->signum),
				this->signum,
				message
		);
	}

#if defined(SUNOS)
	/** Data needed while walking up the stack */
	struct StackWalkerParams {
		std::back_insert_iterator<std::string> *output_iterator; ///< Buffer
		int counter; ///< We are at counter-th stack level
	};

	/**
	 * Callback used while walking up the stack.
	 * @param pc program counter
	 * @param sig 'active' signal (unused)
	 * @param params parameters
	 * @return always 0, continue walking up the stack
	 */
	static int SunOSStackWalker(uintptr_t pc, int sig, void *params)
	{
		StackWalkerParams *wp = (StackWalkerParams *)params;

		/* Resolve program counter to file and nearest symbol (if possible) */
		Dl_info dli;
		if (dladdr((void *)pc, &dli) != 0) {
			fmt::format_to(*wp->output_iterator, " [{:02}] {}({}+0x{:x}) [0x{:x}]\n",
					wp->counter, dli.dli_fname, dli.dli_sname, (int)((byte *)pc - (byte *)dli.dli_saddr), (uint)pc);
		} else {
			fmt::format_to(*wp->output_iterator, " [{:02}] [0x{:x}]\n", wp->counter, (uint)pc);
		}
		wp->counter++;

		return 0;
	}
#endif

	void LogStacktrace(std::back_insert_iterator<std::string> &output_iterator) const override
	{
		fmt::format_to(output_iterator, "Stacktrace:\n");
#if defined(__GLIBC__)
		void *trace[64];
		int trace_size = backtrace(trace, lengthof(trace));

		char **messages = backtrace_symbols(trace, trace_size);
		for (int i = 0; i < trace_size; i++) {
			fmt::format_to(output_iterator, " [{:02}] {}\n", i, messages[i]);
		}
		free(messages);
#elif defined(SUNOS)
		ucontext_t uc;
		if (getcontext(&uc) != 0) {
			fmt::format_to(output_iterator, " getcontext() failed\n\n");
			return buffer;
		}

		StackWalkerParams wp = { &output_iterator, 0 };
		walkcontext(&uc, &CrashLogUnix::SunOSStackWalker, &wp);
#else
		fmt::format_to(output_iterator, " Not supported.\n");
#endif
		fmt::format_to(output_iterator, "\n");
	}
public:
	/**
	 * A crash log is always generated by signal.
	 * @param signum the signal that was caused by the crash.
	 */
	CrashLogUnix(int signum) :
		signum(signum)
	{
	}
};

/** The signals we want our crash handler to handle. */
static const int _signals_to_handle[] = { SIGSEGV, SIGABRT, SIGFPE, SIGBUS, SIGILL };

/**
 * Entry point for the crash handler.
 * @note Not static so it shows up in the backtrace.
 * @param signum the signal that caused us to crash.
 */
static void CDECL HandleCrash(int signum)
{
	/* Disable all handling of signals by us, so we don't go into infinite loops. */
	for (const int *i = _signals_to_handle; i != endof(_signals_to_handle); i++) {
		signal(*i, SIG_DFL);
	}

	if (_gamelog.TestEmergency()) {
		fmt::print("A serious fault condition occurred in the game. The game will shut down.\n");
		fmt::print("As you loaded an emergency savegame no crash information will be generated.\n");
		abort();
	}

	if (SaveloadCrashWithMissingNewGRFs()) {
		fmt::print("A serious fault condition occurred in the game. The game will shut down.\n");
		fmt::print("As you loaded an savegame for which you do not have the required NewGRFs\n");
		fmt::print("no crash information will be generated.\n");
		abort();
	}

	CrashLogUnix log(signum);
	log.MakeCrashLog();

	CrashLog::AfterCrashLogCleanup();
	abort();
}

/* static */ void CrashLog::InitialiseCrashLog()
{
	for (const int *i = _signals_to_handle; i != endof(_signals_to_handle); i++) {
		signal(*i, HandleCrash);
	}
}

/* static */ void CrashLog::InitThread()
{
}