mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 07:08:19 +00:00

* origin/topic/robin/interpreter-exceptions: Adding test for new error handling. Experimental code to better handle interpreter errors. This seems to work fine and it catches some potentially nasty crashes so I'm merging it in even though it's not the final word on error handling yet. #646 tracks the work scheduled for later.
135 lines
4.3 KiB
C++
135 lines
4.3 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#ifndef REPORTER_H
|
|
#define REPORTER_H
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <list>
|
|
#include <utility>
|
|
|
|
#include "util.h"
|
|
#include "net_util.h"
|
|
#include "EventHandler.h"
|
|
|
|
class Connection;
|
|
class Location;
|
|
class Reporter;
|
|
|
|
// One cannot raise this exception directly, go through the
|
|
// Reporter's methods instead.
|
|
|
|
class ReporterException {
|
|
protected:
|
|
friend class Reporter;
|
|
ReporterException() {}
|
|
};
|
|
|
|
class InterpreterException : public ReporterException {
|
|
protected:
|
|
friend class Reporter;
|
|
InterpreterException() {}
|
|
};
|
|
|
|
// Check printf-style variadic arguments if we can.
|
|
#if __GNUC__
|
|
#define FMT_ATTR __attribute__((format(printf, 2, 3))) // sic! 1st is "this" I guess.
|
|
#else
|
|
#define FMT_ATTR
|
|
#endif
|
|
|
|
class Reporter {
|
|
public:
|
|
Reporter();
|
|
~Reporter();
|
|
|
|
// Report an informational message, nothing that needs specific
|
|
// attention.
|
|
void Info(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Report a warning that may indicate a problem.
|
|
void Warning(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Report a non-fatal error. Processing proceeds normally after the error
|
|
// has been reported.
|
|
void Error(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Returns the number of errors reported so far.
|
|
int Errors() { return errors; }
|
|
|
|
// Report a fatal error. Bro will terminate after the message has been
|
|
// reported.
|
|
void FatalError(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Report a fatal error. Bro will terminate after the message has been
|
|
// reported and always generate a core dump.
|
|
void FatalErrorWithCore(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Report a runtime error in evaluating a Bro script expression. This
|
|
// function will not return but raise an InterpreterException.
|
|
void ExprRuntimeError(const Expr* expr, const char* fmt, ...);
|
|
|
|
// Report a traffic weirdness, i.e., an unexpected protocol situation
|
|
// that may lead to incorrectly processing a connnection.
|
|
void Weird(const char* name); // Raises net_weird().
|
|
void Weird(Connection* conn, const char* name, const char* addl = ""); // Raises conn_weird().
|
|
void Weird(Val* conn_val, const char* name, const char* addl = ""); // Raises conn_weird().
|
|
void Weird(const uint32* orig, const uint32* resp, const char* name); // Raises flow_weird().
|
|
|
|
// Syslog a message. This methods does nothing if we're running
|
|
// offline from a trace.
|
|
void Syslog(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Report about a potential internal problem. Bro will continue
|
|
// normally.
|
|
void InternalWarning(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Report an internal program error. Bro will terminate with a core
|
|
// dump after the message has been reported.
|
|
void InternalError(const char* fmt, ...) FMT_ATTR;
|
|
|
|
// Toggle whether non-fatal messages should be reported through the
|
|
// scripting layer rather on standard output. Fatal errors are always
|
|
// reported via stderr.
|
|
void ReportViaEvents(bool arg_via_events) { via_events = arg_via_events; }
|
|
|
|
// Associates the given location with subsequent output. We create a
|
|
// stack of location so that the most recent is always the one that
|
|
// will be assumed to be the current one. The pointer must remain
|
|
// valid until the location is popped.
|
|
void PushLocation(const Location* location)
|
|
{ locations.push_back(std::pair<const Location*, const Location*>(location, 0)); }
|
|
|
|
void PushLocation(const Location* loc1, const Location* loc2)
|
|
{ locations.push_back(std::pair<const Location*, const Location*>(loc1, loc2)); }
|
|
|
|
// Removes the top-most location information from stack.
|
|
void PopLocation()
|
|
{ locations.pop_back(); }
|
|
|
|
// Signals that we're entering processing an error handler event.
|
|
void BeginErrorHandler() { ++in_error_handler; }
|
|
|
|
// Signals that we're done processing an error handler event.
|
|
void EndErrorHandler() { --in_error_handler; }
|
|
|
|
private:
|
|
void DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
|
|
Connection* conn, val_list* addl, bool location, bool time,
|
|
const char* postfix, const char* fmt, va_list ap);
|
|
|
|
// The order if addl, name needs to be like that since fmt_name can
|
|
// contain format specifiers
|
|
void WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* addl, const char* fmt_name, ...);
|
|
void WeirdFlowHelper(const uint32* orig, const uint32* resp, const char* fmt_name, ...);
|
|
|
|
int errors;
|
|
bool via_events;
|
|
int in_error_handler;
|
|
|
|
std::list<std::pair<const Location*, const Location*> > locations;
|
|
};
|
|
|
|
extern Reporter* reporter;
|
|
|
|
#endif
|