mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 02:58:20 +00:00

The Logger class is now in charge of reporting all errors, warnings, informational messages, weirds, and syslogs. All other components route their messages through the global bro_logger singleton. The Logger class comes with these reporting methods: void Message(const char* fmt, ...); void Warning(const char* fmt, ...); void Error(const char* fmt, ...); void FatalError(const char* fmt, ...); // Terminate Bro. void Weird(const char* name); [ .. some more Weird() variants ... ] void Syslog(const char* fmt, ...); void InternalWarning(const char* fmt, ...); void InternalError(const char* fmt, ...); // Terminates Bro. See Logger.h for more information on these. Generally, the reporting now works as follows: - All non-fatal message are reported in one of two ways: (1) At startup (i.e., before we start processing packets), they are logged to stderr. (2) During processing, they turn into events: event log_message%(msg: string, location: string%); event log_warning%(msg: string, location: string%); event log_error%(msg: string, location: string%); The script level can then handle them as desired. If we don't have an event handler, we fall back to reporting on stderr. - All fatal errors are logged to stderr and Bro terminates immediately. - Syslog(msg) directly syslogs, but doesn't do anything else. The three main types of messages can also be generated on the scripting layer via new Log::* bifs: Log::error(msg: string); Log::warning(msg: string); Log::message(msg: string); These pass through the bro_logger as well and thus are handled in the same way. Their output includes location information. More changes: - Removed the alarm statement and the alarm_hook event. - Adapted lots of locations to use the bro_logger, including some of the messages that were previously either just written to stdout, or even funneled through the alarm mechanism. - No distinction anymore between Error() and RunTime(). There's now only one class of errors; the line was quite blurred already anyway. - util.h: all the error()/warn()/message()/run_time()/pinpoint() functions are gone. Use the bro_logger instead now. - Script errors are formatted a bit differently due to the changes. What I've seen so far looks ok to me, but let me know if there's something odd. Notes: - The default handlers for the new log_* events are just dummy implementations for now since we need to integrate all this into the new scripts anyway. - I'm not too happy with the names of the Logger class and its instance bro_logger. We now have a LogMgr as well, which makes this all a bit confusing. But I didn't have a good idea for better names so I stuck with them for now. Perhaps we should merge Logger and LogMgr?
229 lines
5.5 KiB
C++
229 lines
5.5 KiB
C++
// $Id: Obj.h 6781 2009-06-28 00:50:04Z vern $
|
|
//
|
|
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#ifndef obj_h
|
|
#define obj_h
|
|
|
|
#include <limits.h>
|
|
|
|
#include "input.h"
|
|
#include "Desc.h"
|
|
#include "SerialObj.h"
|
|
|
|
class Serializer;
|
|
class SerialInfo;
|
|
|
|
class Location : SerialObj {
|
|
public:
|
|
Location(const char* fname, int line_f, int line_l, int col_f, int col_l)
|
|
{
|
|
filename = fname;
|
|
first_line = line_f;
|
|
last_line = line_l;
|
|
first_column = col_f;
|
|
last_column = col_l;
|
|
delete_data = false;
|
|
|
|
timestamp = 0;
|
|
text = 0;
|
|
}
|
|
|
|
Location()
|
|
{
|
|
filename = 0;
|
|
first_line = last_line = first_column = last_column = 0;
|
|
delete_data = false;
|
|
timestamp = 0;
|
|
text = 0;
|
|
}
|
|
|
|
virtual ~Location()
|
|
{
|
|
if ( delete_data )
|
|
delete [] filename;
|
|
}
|
|
|
|
void Describe(ODesc* d) const;
|
|
|
|
bool Serialize(SerialInfo* info) const;
|
|
static Location* Unserialize(UnserialInfo* info);
|
|
|
|
bool operator==(const Location& l) const;
|
|
bool operator!=(const Location& l) const
|
|
{ return ! (*this == l); }
|
|
|
|
const char* filename;
|
|
int first_line, last_line;
|
|
int first_column, last_column;
|
|
bool delete_data;
|
|
|
|
// Timestamp and text for compatibility with Bison's default yyltype.
|
|
int timestamp;
|
|
char* text;
|
|
protected:
|
|
DECLARE_SERIAL(Location);
|
|
};
|
|
|
|
#define YYLTYPE yyltype
|
|
typedef Location yyltype;
|
|
YYLTYPE GetCurrentLocation();
|
|
|
|
// Used to mean "no location associated with this object".
|
|
extern Location no_location;
|
|
|
|
// Current start/end location.
|
|
extern Location start_location;
|
|
extern Location end_location;
|
|
|
|
// Used by parser to set the above.
|
|
inline void set_location(const Location loc)
|
|
{
|
|
start_location = end_location = loc;
|
|
}
|
|
|
|
inline void set_location(const Location start, const Location end)
|
|
{
|
|
start_location = start;
|
|
end_location = end;
|
|
}
|
|
|
|
class BroObj : public SerialObj {
|
|
public:
|
|
BroObj()
|
|
{
|
|
ref_cnt = 1;
|
|
in_ser_cache = false;
|
|
|
|
// A bit of a hack. We'd like to associate location
|
|
// information with every object created when parsing,
|
|
// since for them, the location is generally well-defined.
|
|
// We could maintain a separate flag that tells us whether
|
|
// we're inside a parse, but the parser also sets the
|
|
// location to no_location when it's done, so it makes
|
|
// sense to just check for that. *However*, start_location
|
|
// and end_location are maintained as their own objects
|
|
// rather than pointers or references, so we can't directly
|
|
// check them for equality with no_location. So instead
|
|
// we check for whether start_location has a line number
|
|
// of 0, which should only happen if it's been assigned
|
|
// to no_location (or hasn't been initialized at all).
|
|
location = 0;
|
|
if ( start_location.first_line != 0 )
|
|
SetLocationInfo(&start_location, &end_location);
|
|
}
|
|
|
|
virtual ~BroObj();
|
|
|
|
// Report user warnings/errors. If obj2 is given, then it's
|
|
// included in the message, though if pinpoint_only is non-zero,
|
|
// then obj2 is only used to pinpoint the location.
|
|
void Warn(const char* msg, const BroObj* obj2 = 0,
|
|
int pinpoint_only = 0) const;
|
|
void Error(const char* msg, const BroObj* obj2 = 0,
|
|
int pinpoint_only = 0) const;
|
|
|
|
// Report internal errors.
|
|
void BadTag(const char* msg, const char* t1 = 0,
|
|
const char* t2 = 0) const;
|
|
#define CHECK_TAG(t1, t2, text, tag_to_text_func) \
|
|
{ \
|
|
if ( t1 != t2 ) \
|
|
BadTag(text, tag_to_text_func(t1), tag_to_text_func(t2)); \
|
|
}
|
|
|
|
void Internal(const char* msg) const;
|
|
void InternalWarning(const char* msg) const;
|
|
|
|
virtual void Describe(ODesc* d) const { /* FIXME: Add code */ };
|
|
|
|
void AddLocation(ODesc* d) const;
|
|
|
|
// Get location info for debugging.
|
|
const Location* GetLocationInfo() const
|
|
{ return location ? location : &no_location; }
|
|
|
|
virtual bool SetLocationInfo(const Location* loc)
|
|
{ return SetLocationInfo(loc, loc); }
|
|
|
|
// Location = range from start to end.
|
|
virtual bool SetLocationInfo(const Location* start, const Location* end);
|
|
|
|
// Set new end-of-location information. This is used to
|
|
// extend compound objects such as statement lists.
|
|
virtual void UpdateLocationEndInfo(const Location& end);
|
|
|
|
int RefCnt() const { return ref_cnt; }
|
|
|
|
// Helper class to temporarily suppress errors
|
|
// as long as there exist any instances.
|
|
class SuppressErrors {
|
|
public:
|
|
SuppressErrors() { ++BroObj::suppress_errors; }
|
|
~SuppressErrors() { --BroObj::suppress_errors; }
|
|
};
|
|
|
|
bool in_ser_cache;
|
|
|
|
protected:
|
|
friend class SerializationCache;
|
|
|
|
DECLARE_ABSTRACT_SERIAL(BroObj);
|
|
|
|
Location* location; // all that matters in real estate
|
|
|
|
private:
|
|
friend class SuppressErrors;
|
|
|
|
void DoMsg(ODesc* d, const char s1[], const BroObj* obj2 = 0,
|
|
int pinpoint_only = 0) const;
|
|
void PinPoint(ODesc* d, const BroObj* obj2 = 0,
|
|
int pinpoint_only = 0) const;
|
|
|
|
friend inline void Ref(BroObj* o);
|
|
friend inline void Unref(BroObj* o);
|
|
|
|
int ref_cnt;
|
|
|
|
// If non-zero, do not print runtime errors. Useful for
|
|
// speculative evaluation.
|
|
static int suppress_errors;
|
|
};
|
|
|
|
// Prints obj to stderr, primarily for debugging.
|
|
extern void print(const BroObj* obj);
|
|
|
|
extern void bad_ref(int type);
|
|
|
|
// Sometimes useful when dealing with BroObj subclasses that have their
|
|
// own (protected) versions of Error.
|
|
inline void Error(const BroObj* o, const char* msg)
|
|
{
|
|
o->Error(msg);
|
|
}
|
|
|
|
inline void Ref(BroObj* o)
|
|
{
|
|
if ( ++o->ref_cnt <= 1 )
|
|
bad_ref(0);
|
|
if ( o->ref_cnt == INT_MAX )
|
|
bad_ref(1);
|
|
}
|
|
|
|
inline void Unref(BroObj* o)
|
|
{
|
|
if ( o && --o->ref_cnt <= 0 )
|
|
{
|
|
if ( o->ref_cnt < 0 )
|
|
bad_ref(2);
|
|
delete o;
|
|
|
|
// We could do the following if o were passed by reference.
|
|
// o = (BroObj*) 0xcd;
|
|
}
|
|
}
|
|
|
|
// A dict_delete_func that knows to Unref() dictionary entries.
|
|
extern void bro_obj_delete_func(void* v);
|
|
|
|
#endif
|