core/DebugReporter.cpp
author Scott Ehlert <ds@alliedmods.net>
Wed Aug 15 06:19:30 2007 +0000 (2007-08-15)
changeset 1330 ab94316bb52b
parent 1270 a6e3a3b8b7f3
child 1339 02e8f2c0f8af
permissions -rw-r--r--
Updated license headers on virtually all files with extremely minor changes in the name of some sort of strange consistency.
All plugin and include file headers also have been changed to say about GPL3 instead of GPL2.

(This day shall henceforth be known as the Eighty Column Massacre of '07)
dvander@592
     1
/**
ds@653
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@592
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@592
    28
 *
dvander@592
    29
 * Version: $Id$
dvander@592
    30
 */
dvander@592
    31
dvander@592
    32
#include "DebugReporter.h"
dvander@592
    33
#include "Logger.h"
dvander@592
    34
#include "PluginSys.h"
dvander@1269
    35
#include "sm_stringutil.h"
dvander@592
    36
dvander@616
    37
DebugReport g_DbgReporter;
dvander@592
    38
dvander@1269
    39
/* I'm really lazy.  This should probably be exported to ISourcePawnEngine someday,
dvander@1269
    40
 * but we need to make sure the JIT will deal with the version bump.
dvander@1269
    41
 */
dvander@1269
    42
extern const char *GetSourcePawnErrorMessage(int error);
dvander@1269
    43
dvander@616
    44
void DebugReport::OnSourceModAllInitialized()
dvander@592
    45
{
dvander@592
    46
	g_pSourcePawn->SetDebugListener(this);
dvander@592
    47
}
dvander@592
    48
dvander@1269
    49
void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
dvander@1269
    50
{
dvander@1269
    51
	va_list ap;
dvander@1269
    52
	char buffer[512];
dvander@1269
    53
dvander@1269
    54
	va_start(ap, message);
dvander@1269
    55
	UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
dvander@1269
    56
	va_end(ap);
dvander@1269
    57
dvander@1269
    58
	const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename();
dvander@1269
    59
	const char *error = GetSourcePawnErrorMessage(err);
dvander@1269
    60
dvander@1269
    61
	if (error)
dvander@1269
    62
	{
dvander@1269
    63
		g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
dvander@1269
    64
	} else {
dvander@1269
    65
		g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
dvander@1269
    66
	}
dvander@1269
    67
dvander@1269
    68
	g_Logger.LogError("[SM] %s", buffer);
dvander@1269
    69
dvander@1269
    70
	if (func_idx != -1)
dvander@1269
    71
	{
dvander@1269
    72
		if (func_idx & 1)
dvander@1269
    73
		{
dvander@1269
    74
			func_idx >>= 1;
dvander@1269
    75
			sp_public_t *function;
dvander@1269
    76
			if (ctx->GetPublicByIndex(func_idx, &function) == SP_ERROR_NONE)
dvander@1269
    77
			{
dvander@1269
    78
				g_Logger.LogError("[SM] Unable to call function \"%s\" due to above errors.", function->name);
dvander@1269
    79
			}
dvander@1269
    80
		}
dvander@1269
    81
	}
dvander@1269
    82
}
dvander@1269
    83
dvander@616
    84
void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *error)
dvander@592
    85
{
dvander@592
    86
	const char *lastname;
dvander@592
    87
	const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename();
dvander@592
    88
	int n_err = error->GetErrorCode();
dvander@592
    89
dvander@592
    90
	if (n_err != SP_ERROR_NATIVE)
dvander@592
    91
	{
dvander@1036
    92
		g_Logger.LogError("[SM] Plugin encountered error %d: %s",
dvander@592
    93
			n_err,
dvander@592
    94
			error->GetErrorString());
dvander@592
    95
	}
dvander@592
    96
dvander@592
    97
	if ((lastname=error->GetLastNative(NULL)) != NULL)
dvander@592
    98
	{
dvander@592
    99
		const char *custerr;
dvander@592
   100
		if ((custerr=error->GetCustomErrorString()) != NULL)
dvander@592
   101
		{
dvander@592
   102
			g_Logger.LogError("[SM] Native \"%s\" reported: %s", lastname, custerr);
dvander@592
   103
		} else {
dvander@592
   104
			g_Logger.LogError("[SM] Native \"%s\" encountered a generic error.", lastname);
dvander@592
   105
		}
dvander@592
   106
	}
dvander@592
   107
dvander@592
   108
	if (!error->DebugInfoAvailable())
dvander@592
   109
	{
dvander@1036
   110
		g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
dvander@592
   111
		g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
dvander@592
   112
			_GetPluginIndex(ctx));
dvander@592
   113
		return;
dvander@592
   114
	}
dvander@592
   115
dvander@592
   116
	CallStackInfo stk_info;
dvander@592
   117
	int i = 0;
dvander@592
   118
	g_Logger.LogError("[SM] Displaying call stack trace:");
dvander@592
   119
	while (error->GetTraceInfo(&stk_info))
dvander@592
   120
	{
dvander@592
   121
		g_Logger.LogError("[SM]   [%d]  Line %d, %s::%s()",
dvander@592
   122
			i++,
dvander@592
   123
			stk_info.line,
dvander@592
   124
			stk_info.filename,
dvander@592
   125
			stk_info.function);
dvander@592
   126
	}
dvander@592
   127
}
dvander@592
   128
dvander@616
   129
int DebugReport::_GetPluginIndex(IPluginContext *ctx)
dvander@592
   130
{
dvander@592
   131
	int id = 1;
dvander@592
   132
	IPluginIterator *iter = g_PluginSys.GetPluginIterator();
dvander@592
   133
dvander@592
   134
	for (; iter->MorePlugins(); iter->NextPlugin(), id++)
dvander@592
   135
	{
dvander@592
   136
		IPlugin *pl = iter->GetPlugin();
dvander@592
   137
		if (pl->GetBaseContext() == ctx)
dvander@592
   138
		{
dvander@592
   139
			iter->Release();
dvander@592
   140
			return id;
dvander@592
   141
		}
dvander@592
   142
	}
dvander@592
   143
dvander@592
   144
	iter->Release();
dvander@592
   145
	return -1;
dvander@592
   146
}
dvander@592
   147