Add debug string and ODesc support to HashKey class

This allows tracing of hash key buffer reservations, reads, and writes via a new
debug stream, and supports printing a summary of a HashKey object via
Describe(). The latter comes in handy e.g. in TableVal::Describe() (where
including the hash key is now available but commented out).
This commit is contained in:
Christian Kreibich 2021-09-16 17:18:09 -07:00
parent 82822b1e07
commit b6a11a69db
5 changed files with 76 additions and 1 deletions

View file

@ -21,7 +21,9 @@ DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = {
{"packet_analysis", 0, false}, {"file_analysis", 0, false}, {"tm", 0, false},
{"logging", 0, false}, {"input", 0, false}, {"threading", 0, false},
{"plugins", 0, false}, {"zeekygen", 0, false}, {"pktio", 0, false},
{"broker", 0, false}, {"scripts", 0, false}, {"supervisor", 0, false}};
{"broker", 0, false}, {"scripts", 0, false}, {"supervisor", 0, false},
{"hashkey", 0, false},
};
DebugLogger::DebugLogger()
{

View file

@ -54,6 +54,7 @@ enum DebugStream
DBG_BROKER, // Broker communication
DBG_SCRIPTS, // Script initialization
DBG_SUPERVISOR, // Process supervisor
DBG_HASHKEY, // HashKey buffers
NUM_DBGS // Has to be last
};

View file

@ -6,6 +6,8 @@
#include <highwayhash/instruction_sets.h>
#include <highwayhash/sip_hash.h>
#include "zeek/DebugLogger.h"
#include "zeek/Desc.h"
#include "zeek/Reporter.h"
#include "zeek/Val.h" // needed for const.bif
#include "zeek/ZeekString.h"
@ -198,6 +200,11 @@ hash_t HashKey::Hash() const
{
if ( hash == 0 )
hash = HashBytes(key, size);
#ifdef DEBUG
ODesc d;
Describe(&d);
DBG_LOG(DBG_HASHKEY, "HashKey %p %s", this, d.Description());
#endif
return hash;
}
@ -212,6 +219,46 @@ void* HashKey::TakeKey()
return CopyKey(key, size);
}
void HashKey::Describe(ODesc* d) const
{
char buf[64];
snprintf(buf, 16, "%0" PRIx64, hash);
d->Add(buf);
d->SP();
if ( size > 0 )
{
d->Add(IsAllocated() ? "(" : "[");
for ( size_t i = 0; i < size; i++ )
{
if ( i > 0 )
{
d->SP();
// Extra spacing every 8 bytes, for readability.
if ( i % 8 == 0 )
d->SP();
}
// Don't display unwritten content, only say how much there is.
if ( i > write_size )
{
d->Add("<+");
d->Add(static_cast<uint64_t>(size - write_size - 1));
d->Add(" of ");
d->Add(static_cast<uint64_t>(size));
d->Add(" available>");
break;
}
snprintf(buf, 3, "%02x", key[i]);
d->Add(buf);
}
d->Add(IsAllocated() ? ")" : "]");
}
}
char* HashKey::CopyKey(const char* k, size_t s) const
{
char* k_copy = new char[s]; // s == 0 is okay, returns non-nil
@ -279,6 +326,9 @@ void HashKey::Reserve(const char* tag, size_t addl_size, size_t alignment)
size_t s0 = size;
size_t s1 = util::memory_size_align(size, alignment);
size = s1 + addl_size;
DBG_LOG(DBG_HASHKEY, "HashKey %p reserving %lu/%lu: %lu -> %lu -> %lu [%s]", this, addl_size,
alignment, s0, s1, size, tag);
}
void HashKey::Allocate()
@ -358,7 +408,9 @@ void HashKey::Write(const char* tag, double d, bool align)
void HashKey::Write(const char* tag, const void* bytes, size_t n, size_t alignment)
{
size_t s0 = write_size;
AlignWrite(alignment);
size_t s1 = write_size;
EnsureWriteSpace(n);
memcpy(key + write_size, bytes, n);
@ -370,6 +422,9 @@ void HashKey::Write(const char* tag, const void* bytes, size_t n, size_t alignme
void HashKey::SkipWrite(const char* tag, size_t n)
{
DBG_LOG(DBG_HASHKEY, "HashKey %p skip-writing %lu: %lu -> %lu [%s]", this, n, write_size,
write_size + n, tag);
EnsureWriteSpace(n);
write_size += n;
}
@ -443,7 +498,9 @@ void HashKey::Read(const char* tag, double& d, bool align) const
void HashKey::Read(const char* tag, void* out, size_t n, size_t alignment) const
{
size_t s0 = read_size;
AlignRead(alignment);
size_t s1 = read_size;
EnsureReadSpace(n);
// In case out is nil, make sure nothing is to be read, and only memcpy
@ -456,10 +513,16 @@ void HashKey::Read(const char* tag, void* out, size_t n, size_t alignment) const
memcpy(out, key + read_size, n);
read_size += n;
}
DBG_LOG(DBG_HASHKEY, "HashKey %p reading %lu/%lu: %lu -> %lu -> %lu [%s]", this, n, alignment,
s0, s1, read_size, tag);
}
void HashKey::SkipRead(const char* tag, size_t n) const
{
DBG_LOG(DBG_HASHKEY, "HashKey %p skip-reading %lu: %lu -> %lu [%s]", this, n, read_size,
read_size + n, tag);
EnsureReadSpace(n);
read_size += n;
}

View file

@ -28,8 +28,12 @@
namespace zeek
{
class String;
class ODesc;
}
namespace zeek::detail
{
@ -354,6 +358,8 @@ public:
const void* KeyAtRead() const { return static_cast<void*>(key + read_size); }
const void* KeyEnd() const { return static_cast<void*>(key + size); }
void Describe(ODesc* d) const;
protected:
char* CopyKey(const char* key, size_t size) const;

View file

@ -2395,6 +2395,9 @@ void TableVal::Describe(ODesc* d) const
d_ptr->SP();
}
// The following shows the HashKey state as well:
// k->Describe(d_ptr);
// d_ptr->SP();
vl->Describe(d_ptr);
if ( table_type->IsSet() )