}
sub FileNameHash
{
-# Please keep in sync this function with the FileNameHash function in
-# src/base/TextException.cc file
my($name) = @_;
+
+ # Keep in sync with FileNameHash() in src/base/Here.cc!
+
$name =~ s/.*\///g;
my($i) = 0;
my($j) =0;
for($j=0; $j < @na; $j++) {
$n = $n ^ (271 * ord($na[$j]));
}
- $i = $n ^ ($j *271);
-
- # Currently 18bits of a 32 bit integer used for filename hash
- # (max hash=262143), and 14 bits for storing line number
- $i = $i % 262143;
- return $i;
+ return $n ^ ($j *271);
}
sub ComputeMustIds
{
my($file) = @_;
- my($hash) = FileNameHash($file);
+
+ # Keep in sync with SourceLocation::id() in src/base/Here.cc!
+
+ my $fullHash = &FileNameHash($file);
+ my $hash = $fullHash % 0x3FFFF;
+
if(!open(IN, "<$file")) {
printf STDERR "error opening file $file. Ignore ...";
return;
}
while(<IN>) {
my($line) = $_;
+
+ next if $line =~ /^\s*#/; # ignore simple single-line C++ macros
+ $line =~ s@//.*@@; # strip simple // comments
+ $line =~ s@/[*].*?[*]/@@; # strip simple single-line /* comments */
+
my($id);
- if ( $line =~ /^\s*Must\s*\(/ || $line =~ /^\s*throw\s*TexcHere\s*\(/){
+ if ($line =~ /\bMust2?\s*\(/ || # Must(...) and Must2(...)
+ $line =~ /\bTexcHere\s*\(/ || # TexcHere(...)
+ $line =~ /\bHere\s*\(\s*\)/) { # Here()
$line =~ s/^\s*//;
$id= ($hash <<14) | ($. & 0x3FFF);
$id += ERR_DETAIL_EXCEPTION_START;
#ifndef SQUID_DEBUG_H
#define SQUID_DEBUG_H
+#include "base/Here.h"
// XXX should be mem/forward.h once it removes dependencies on typedefs.h
#include "mem/AllocatorProxy.h"
/// a hack for low-level file descriptor manipulations in ipcCreate()
void ResyncDebugLog(FILE *newDestination);
-size_t BuildPrefixInit();
-const char * SkipBuildPrefix(const char* path);
-
/* Debug stream
*
* Unit tests can enable full debugging to stderr for one
std::ostream &_dbo = Debug::Start((SECTION), _dbg_level); \
if (_dbg_level > DBG_IMPORTANT) { \
_dbo << (SECTION) << ',' << _dbg_level << "| " \
- << SkipBuildPrefix(__FILE__)<<"("<<__LINE__<<") "<<__FUNCTION__<<": "; \
+ << Here() << ": "; \
} \
_dbo << CONTENT; \
Debug::Finish(); \
IpcIoFile::~IpcIoFile()
{
- if (diskId >= 0) {
- const IpcIoFilesMap::iterator i = IpcIoFiles.find(diskId);
- // XXX: warn and continue?
- Must(i != IpcIoFiles.end());
- Must(i->second == this);
- IpcIoFiles.erase(i);
- }
+ SWALLOW_EXCEPTIONS({
+ if (diskId >= 0) {
+ const auto i = IpcIoFiles.find(diskId);
+ Must(i != IpcIoFiles.end());
+ Must(i->second == this);
+ IpcIoFiles.erase(i);
+ }
+ });
}
void
#include "squid.h"
#include "base/TextException.h"
+#include "Debug.h"
#include "FadingCounter.h"
#include "SquidTime.h"
#define SQUID_STRING_H
#include "base/TextException.h"
+#include "Debug.h"
#include <ostream>
Adaptation::Icap::ServiceRep::~ServiceRep()
{
- delete theIdleConns;
- Must(!theOptionsFetcher);
- delete theOptions;
+ SWALLOW_EXCEPTIONS({
+ delete theIdleConns;
+ Must(!theOptionsFetcher);
+ delete theOptions;
+ });
}
void
public:
AsyncJob(const char *aTypeName);
- virtual ~AsyncJob();
/// starts a freshly created job (i.e., makes the job asynchronous)
static Pointer Start(AsyncJob *job);
virtual void callException(const std::exception &e);
protected:
+ // external destruction prohibited to ensure swanSong() is called
+ virtual ~AsyncJob();
+
const char *stopReason; ///< reason for forcing done() to be true
const char *typeName; ///< kid (leaf) class name, for debugging
AsyncCall::Pointer inCall; ///< the asynchronous call being handled, if any
--- /dev/null
+/*
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "base/Here.h"
+
+#include <iostream>
+
+/* File name hashing helpers */
+
+// Build prefix is the file system path leading to Squid src/ source directory.
+// It is "." for in-tree builds but may be lengthy and sensitive otherwise.
+
+/// \returns the build prefix length or, if estimation is not possible, zero
+static size_t
+BuildPrefixLength()
+{
+ // The hard-coded tail must be kept in sync with this file actual name!
+ const char *tail = "src/base/Here.cc";
+ const char *full = __FILE__;
+
+ // Disable heuristic if it does not work.
+ if (strstr(full, tail) == 0)
+ return 0;
+
+ return strlen(full) - strlen(tail);
+}
+
+/// \returns filename portion without the build prefix
+static const char *
+SkipBuildPrefix(const char* path)
+{
+ static const size_t ToSkip = BuildPrefixLength();
+ return path + ToSkip;
+}
+
+/// quickly computes a (weak) hash of a file name
+static SourceLocationId
+FileNameHash(const char *path)
+{
+ // Keep in sync with FileNameHash() in scripts/calc-must-ids.pl!
+
+ const char *name = strrchr(path, '/');
+ if (name)
+ ++name; // skip '/'
+ else
+ name = path;
+
+ uint32_t hash = 0;
+ uint32_t iterations = 0;
+ while (*name) {
+ ++iterations;
+ hash ^= 271 * static_cast<uint32_t>(*name);
+ ++name;
+ }
+ return hash ^ (iterations * 271);
+}
+
+/* SourceLocation */
+
+SourceLocationId
+SourceLocation::id() const
+{
+ const auto fnameHashFull = fileNameHashCacher(fileName, &FileNameHash);
+ // 32 bits = 18 bits for the filename hash + 14 bits for the line number.
+ // Keep in sync with ComputeMustIds() in scripts/calc-must-ids.pl.
+ const auto fnameHash = fnameHashFull % 0x3FFFF;
+ return (fnameHash << 14) | (lineNo & 0x3FFF);
+}
+
+std::ostream &
+SourceLocation::print(std::ostream &os) const
+{
+ if (fileName) {
+ os << SkipBuildPrefix(fileName);
+
+ // TODO: Use more common and search-friendlier fileName:lineNo: format.
+ if (lineNo > 0)
+ os << '(' << lineNo << ')';
+ }
+ if (context) {
+ if (fileName)
+ os << ' ';
+ os << context;
+ }
+ return os;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_BASE_HERE_H
+#define SQUID_BASE_HERE_H
+
+#include <iosfwd>
+
+/// source code location of the caller
+#define Here() SourceLocation(__FUNCTION__, __FILE__, __LINE__)
+
+/// semi-uniquely identifies a source code location; stable across Squid runs
+typedef uint32_t SourceLocationId;
+
+/// returns a hash of a file name
+typedef SourceLocationId FileNameHasher(const char *fileName);
+
+/// a caching proxy for `hasher` results
+typedef SourceLocationId FileNameHashCacher(const char *fileName, FileNameHasher hasher);
+
+static FileNameHashCacher UnitFileNameHashCacher;
+
+/// a source code location that is cheap to create, copy, and store
+class SourceLocation
+{
+public:
+ SourceLocation(const char *aContext, const char *aFileName, const int aLineNo):
+ context(aContext),
+ fileName(aFileName),
+ lineNo(aLineNo),
+ fileNameHashCacher(&UnitFileNameHashCacher)
+ {}
+
+ /// \returns our location identifier
+ SourceLocationId id() const;
+
+ /// describes location using a compact but human-friendly format
+ std::ostream &print(std::ostream &os) const;
+
+ const char *context; ///< line-independent location description
+ const char *fileName; ///< source file name, often relative to build path
+ int lineNo; ///< line number inside the source file name (if positive)
+
+private:
+ SourceLocationId calculateId(FileNameHasher) const;
+ FileNameHashCacher *fileNameHashCacher;
+};
+
+inline std::ostream &
+operator <<(std::ostream &os, const SourceLocation &location)
+{
+ return location.print(os);
+}
+
+/// SourceLocation::id() speed optimization hack: Caches `hasher` results. The
+/// cache capacity is one filename hash. Each translation unit gets one cache.
+static SourceLocationId
+UnitFileNameHashCacher(const char *fileName, FileNameHasher hasher)
+{
+ static SourceLocationId cachedHash = 0;
+ static const char *hashedFilename = 0;
+ // Each file #included in a translation unit has its own __FILE__ value.
+ // Keep the cache fresh (and the result correct).
+ if (hashedFilename != fileName) { // cheap pointer comparison
+ hashedFilename = fileName;
+ cachedHash = hasher(fileName);
+ }
+ return cachedHash;
+}
+
+#endif
+
libbase_la_SOURCES = \
AsyncCall.cc \
AsyncCall.h \
+ AsyncCallQueue.cc \
+ AsyncCallQueue.h \
AsyncCbdataCalls.h \
- AsyncJob.h \
AsyncJob.cc \
+ AsyncJob.h \
AsyncJobCalls.h \
- AsyncCallQueue.cc \
- AsyncCallQueue.h \
ByteCounter.h \
CbcPointer.h \
CbDataList.h \
- CharacterSet.h \
CharacterSet.cc \
+ CharacterSet.h \
EnumIterator.h \
- File.h \
File.cc \
+ File.h \
HardFun.h \
+ Here.cc \
+ Here.h \
InstanceId.h \
Lock.h \
LookupTable.h \
#include "squid.h"
#include "base/RunnersRegistry.h"
#include "base/TextException.h"
+#include "Debug.h"
#include <set>
/// a collection of unique runners, in no particular order
#include "squid.h"
#include "base/TextException.h"
-#include "Debug.h"
#include "sbuf/SBuf.h"
-#include "util.h"
-TextException::TextException()
-{
- message=NULL;
- theFileName=NULL;
- theLineNo=0;
- theId=0;
-}
+#include <iostream>
+#include <sstream>
+#include <unordered_map>
-TextException::TextException(const TextException& right) :
- message((right.message?xstrdup(right.message):NULL)), theFileName(right.theFileName), theLineNo(right.theLineNo), theId(right.theId)
-{
-}
+/// a standard CoW string; avoids noise and circular dependencies of SBuf
+typedef std::runtime_error WhatString;
-TextException::TextException(const char *aMsg, const char *aFileName, int aLineNo, unsigned int anId):
- message(aMsg?xstrdup(aMsg):NULL), theFileName(aFileName), theLineNo(aLineNo), theId(anId)
-{}
+/// a collection of strings indexed by pointers to their creator objects
+typedef std::unordered_multimap<const void*, WhatString> WhatStrings;
+
+/// requested what() strings of alive TextException objects
+static WhatStrings *WhatStrings_ = nullptr;
-TextException::TextException(SBuf msg, const char *aFileName, int aLineNo, unsigned int anId):
- TextException(msg.c_str(), aFileName, aLineNo, anId)
+TextException::TextException(SBuf message, const SourceLocation &location):
+ TextException(message.c_str(), location)
{}
TextException::~TextException() throw()
{
- if (message) xfree(message);
+ if (WhatStrings_)
+ WhatStrings_->erase(this); // there only if what() has been called
}
-TextException& TextException::operator=(const TextException &right)
+std::ostream &
+TextException::print(std::ostream &os) const
{
- if (this==&right) return *this;
- if (message) xfree(message);
- message=(right.message?xstrdup(right.message):NULL);
- theFileName=right.theFileName;
- theLineNo=right.theLineNo;
- theId=right.theId;
- return *this;
+ os << std::runtime_error::what() << "\n" <<
+ " exception location: " << where << "\n";
+ // TODO: error_detail: " << (ERR_DETAIL_EXCEPTION_START+id()) << "\n";
+ return os;
}
-const char *TextException::what() const throw()
+const char *
+TextException::what() const throw()
{
- /// \todo add file:lineno
- return message ? message : "TextException without a message";
-}
+ std::ostringstream os;
+ print(os);
+ const WhatString result(os.str());
-unsigned int TextException::FileNameHash(const char *fname)
-{
- const char *s = NULL;
- unsigned int n = 0;
- unsigned int j = 0;
- unsigned int i = 0;
- s = strrchr(fname, '/');
-
- if (s)
- ++s;
- else
- s = fname;
+ // extend result.c_str() lifetime to this object lifetime
+ if (!WhatStrings_)
+ WhatStrings_ = new WhatStrings;
+ // *this could change, but we must preserve old results for they may be used
+ WhatStrings_->emplace(std::make_pair(this, result));
- while (*s) {
- ++j;
- n ^= 271 * (unsigned) *s;
- ++s;
- }
- i = n ^ (j * 271);
- /*18bits of a 32 bit integer used for filename hash (max hash=262143),
- and 14 bits for storing line number (16k max).
- If you change this policy remember to update the FileNameHash function
- in the scripts/calc-must-ids.pl script
- */
- return i % 262143;
+ return result.what();
}
-void Throw(const char *message, const char *fileName, int lineNo, unsigned int id)
+std::ostream &
+CurrentException(std::ostream &os)
{
-
- // or should we let the exception recepient print the exception instead?
-
- if (fileName) {
- debugs(0, 3, fileName << ':' << lineNo << ": exception" <<
- (message ? ": " : ".") << (message ? message : ""));
+ if (std::current_exception()) {
+ try {
+ throw; // re-throw to recognize the exception type
+ }
+ catch (const std::exception &ex) {
+ os << ex.what();
+ }
+ catch (...) {
+ os << "[unknown exception type]";
+ }
} else {
- debugs(0, 3, "exception" <<
- (message ? ": " : ".") << (message ? message : ""));
+ os << "[no active exception]";
}
-
- throw TextException(message, fileName, lineNo, id);
+ return os;
}
#ifndef SQUID__TEXTEXCEPTION_H
#define SQUID__TEXTEXCEPTION_H
-// Origin: xstd/TextException
+#include "base/Here.h"
#include <exception>
class SBuf;
-static unsigned int FileNameHashCached(const char *fname);
-
-// simple exception to report custom errors
-// we may want to change the interface to be able to report system errors
-
-class TextException: public std::exception
+/// an std::runtime_error with thrower location info
+class TextException: public std::runtime_error
{
public:
- TextException();
- TextException(const char *aMessage, const char *aFileName = 0, int aLineNo = -1, unsigned int anId =0);
- TextException(SBuf aMessage, const char *aFileName = 0, int aLineNo = -1, unsigned int anId =0);
- TextException(const TextException& right);
- virtual ~TextException() throw();
+ TextException(const char *message, const SourceLocation &location):
+ std::runtime_error(message),
+ where(location)
+ {}
- // unique exception ID for transaction error detail logging
- unsigned int id() const { return theId; }
+ TextException(SBuf message, const SourceLocation &location);
- virtual const char *what() const throw();
+ TextException(const TextException &) = default;
+ TextException(TextException &&) = default;
+ TextException& operator=(const TextException &) = default;
- TextException& operator=(const TextException &right);
+ /* std::runtime_error API */
+ virtual ~TextException() throw() override;
+ virtual const char *what() const throw() override;
-public:
- char *message; // read-only
+ /// same-location exceptions have the same ID
+ SourceLocationId id() const { return where.id(); }
-protected:
- /// a small integer hash value to semi-uniquely identify the source file
- static unsigned int FileNameHash(const char *fname);
+ /// dumps the exception text into the stream
+ std::ostream &print(std::ostream &) const;
- // optional location information
- const char *theFileName;
- int theLineNo;
- unsigned int theId;
+ /// code location related to the exception; usually the thrower location
+ SourceLocation where;
- friend unsigned int FileNameHashCached(const char *fname);
+ // TODO: Add support for arbitrary (re)thrower-supplied details:
+ // std::tuple<Details...> details;
};
-//inline
-//ostream &operator <<(ostream &os, const TextException &exx) {
-// return exx.print(os);
-//}
-
-/// caches the result of FileNameHash() for each translation unit
-static unsigned int
-FileNameHashCached(const char *fname)
-{
- static const char *lastFname = 0;
- static int lastHash = 0;
- // __FILE__ changes when we #include files
- if (lastFname != fname) { // cheap pointer comparison
- lastFname = fname;
- lastHash = TextException::FileNameHash(fname);
+/// prints active (i.e., thrown but not yet handled) exception
+std::ostream &CurrentException(std::ostream &);
+
+/// legacy convenience macro; it is not difficult to type Here() now
+#define TexcHere(msg) TextException((msg), Here())
+
+/// Like assert() but throws an exception instead of aborting the process
+/// and allows the caller to specify a custom exception message.
+#define Must2(condition, message) \
+ do { \
+ if (!(condition)) { \
+ const TextException Must_ex_((message), Here()); \
+ debugs(0, 3, Must_ex_.what()); \
+ throw Must_ex_; \
+ } \
+ } while (/*CONSTCOND*/ false)
+
+/// Like assert() but throws an exception instead of aborting the process.
+#define Must(condition) Must2((condition), "check failed: " #condition)
+
+/// Reports and swallows all exceptions to prevent compiler warnings and runtime
+/// errors related to throwing class destructors. Should be used for most dtors.
+#define SWALLOW_EXCEPTIONS(code) \
+ try { \
+ code \
+ } catch (...) { \
+ debugs(0, DBG_IMPORTANT, "BUG: ignoring exception;\n" << \
+ " bug location: " << Here() << "\n" << \
+ " ignored exception: " << CurrentException); \
}
- return lastHash;
-}
-
-/// Avoids "defined but not used" warnings for FileNameHashCached
-class FileNameHashCacheUser
-{
- bool use(void *ptr=NULL) { return ptr != (void*)&FileNameHashCached; }
-};
-
-#if !defined(TexcHere)
-# define TexcHere(msg) TextException((msg), __FILE__, __LINE__, \
- (FileNameHashCached(__FILE__)<<14) | (__LINE__ & 0x3FFF))
-#endif
-
-void Throw(const char *message, const char *fileName, int lineNo, unsigned int id);
-
-// Must(condition) is like assert(condition) but throws an exception instead
-#if !defined(Must)
-# define Must(cond) ((cond) ? \
- (void)0 : \
- (void)Throw(#cond, __FILE__, __LINE__, \
- (FileNameHashCached(__FILE__)<<14) | (__LINE__ & 0x3FFF)))
-#endif
#endif /* SQUID__TEXTEXCEPTION_H */
#define SQUID_YESNONONE_H_
#include "base/TextException.h"
+#include "Debug.h"
// TODO: generalize / template to non-boolean option types
// and make YesNoNone the boolean instance of the template
// else it was a static topContext from Debug::Start()
}
-size_t
-BuildPrefixInit()
-{
- // XXX: This must be kept in sync with the actual debug.cc location
- const char *ThisFileNameTail = "src/debug.cc";
-
- const char *file=__FILE__;
-
- // Disable heuristic if it does not work.
- if (!strstr(file, ThisFileNameTail))
- return 0;
-
- return strlen(file)-strlen(ThisFileNameTail);
-}
-
-const char*
-SkipBuildPrefix(const char* path)
-{
- static const size_t BuildPrefixLength = BuildPrefixInit();
-
- return path+BuildPrefixLength;
-}
-
/// print data bytes using hex notation
void
Raw::printHex(std::ostream &os) const
AsyncJob("Ipc::Forwarder"),
request(aRequest), timeout(aTimeout)
{
- debugs(54, 5, HERE);
}
Ipc::Forwarder::~Forwarder()
{
- debugs(54, 5, HERE);
- Must(request->requestId == 0);
- cleanup();
-}
-
-/// perform cleanup actions
-void
-Ipc::Forwarder::cleanup()
-{
+ SWALLOW_EXCEPTIONS({
+ Must(request->requestId == 0);
+ });
}
void
DequeueRequest(request->requestId);
request->requestId = 0;
}
- cleanup();
}
bool
virtual void swanSong();
virtual bool doneAll() const;
- virtual void cleanup(); ///< perform cleanup actions
virtual void handleError();
virtual void handleTimeout();
virtual void handleException(const std::exception& e);
configured_once = 1;
}
-/// describes active (i.e., thrown but not yet handled) exception
-static std::ostream &
-CurrentException(std::ostream &os)
-{
- if (std::current_exception()) {
- try {
- throw; // re-throw to recognize the exception type
- }
- catch (const std::exception &ex) {
- os << ex.what();
- }
- catch (...) {
- os << "[unknown exception type]";
- }
- } else {
- os << "[no active exception]";
- }
- return os;
-}
-
static void
OnTerminate()
{
Mgr::Forwarder::~Forwarder()
{
- debugs(16, 5, HERE);
- Must(httpRequest != NULL);
- Must(entry != NULL);
-
- HTTPMSGUNLOCK(httpRequest);
- entry->unregisterAbort();
- entry->unlock("Mgr::Forwarder");
- cleanup();
+ SWALLOW_EXCEPTIONS({
+ Must(entry);
+ entry->unlock("Mgr::Forwarder");
+ Must(httpRequest);
+ HTTPMSGUNLOCK(httpRequest);
+ });
}
/// closes our copy of the client HTTP connection socket
void
-Mgr::Forwarder::cleanup()
+Mgr::Forwarder::swanSong()
{
if (Comm::IsConnOpen(conn)) {
if (closer != NULL) {
conn->close();
}
conn = NULL;
+ Ipc::Forwarder::swanSong();
}
void
protected:
/* Ipc::Forwarder API */
- virtual void cleanup(); ///< perform cleanup actions
+ virtual void swanSong();
virtual void handleError();
virtual void handleTimeout();
virtual void handleException(const std::exception& e);
#include "squid.h"
#include "base/TextException.h"
+#include "Debug.h"
#include "ipc/TypedMsgHdr.h"
#include "mgr/IntParam.h"
+++ /dev/null
-/*
- * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#include "squid.h"
-#include "sbuf/Exceptions.h"
-#include "sbuf/OutOfBoundsException.h"
-#include "sbuf/SBuf.h"
-
-OutOfBoundsException::OutOfBoundsException(const SBuf &throwingBuf,
- SBuf::size_type &pos,
- const char *aFileName, int aLineNo)
- : TextException(NULL, aFileName, aLineNo),
- theThrowingBuf(throwingBuf),
- accessedPosition(pos)
-{
- SBuf explanatoryText("OutOfBoundsException");
- if (aLineNo != -1)
- explanatoryText.appendf(" at line %d", aLineNo);
- if (aFileName != NULL)
- explanatoryText.appendf(" in file %s", aFileName);
- explanatoryText.appendf(" while accessing position %d in a SBuf long %d",
- pos, throwingBuf.length());
- message = xstrdup(explanatoryText.c_str());
-}
-
-OutOfBoundsException::~OutOfBoundsException() throw()
-{ }
-
-InvalidParamException::InvalidParamException(const char *aFilename, int aLineNo)
- : TextException("Invalid parameter", aFilename, aLineNo)
-{ }
-
-SBufTooBigException::SBufTooBigException(const char *aFilename, int aLineNo)
- : TextException("Trying to create an oversize SBuf", aFilename, aLineNo)
-{ }
-
+++ /dev/null
-/*
- * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#ifndef SQUID_SBUFEXCEPTIONS_H
-#define SQUID_SBUFEXCEPTIONS_H
-
-#include "base/TextException.h"
-
-/**
- * Exception raised when call parameters are not valid
- * \todo move to an Exceptions.h?
- */
-class InvalidParamException : public TextException
-{
-public:
- explicit InvalidParamException(const char *aFilename = 0, int aLineNo = -1);
-};
-
-/**
- * Exception raised when an attempt to resize a SBuf would cause it to reserve too big
- */
-class SBufTooBigException : public TextException
-{
-public:
- explicit SBufTooBigException(const char *aFilename = 0, int aLineNo = -1);
-};
-
-#endif /* SQUID_SBUFEXCEPTIONS_H */
-
Algorithms.h \
DetailedStats.cc \
DetailedStats.h \
- Exceptions.cc \
- Exceptions.h \
forward.h \
List.cc \
List.h \
MemBlob.cc \
MemBlob.h \
- OutOfBoundsException.h \
SBuf.cc \
SBuf.h \
Stats.cc \
+++ /dev/null
-/*
- * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#ifndef _SQUID_SRC_OUTOFBOUNDSEXCEPTION_H
-#define _SQUID_SRC_OUTOFBOUNDSEXCEPTION_H
-
-#include "base/TextException.h"
-#include "sbuf/SBuf.h"
-
-/**
- * Exception raised when the user is going out of bounds when accessing
- * a char within the SBuf
- */
-class OutOfBoundsException : public TextException
-{
-public:
- OutOfBoundsException(const SBuf &buf, SBuf::size_type &pos, const char *aFileName = 0, int aLineNo = -1);
- virtual ~OutOfBoundsException() throw();
-
-protected:
- SBuf theThrowingBuf;
- SBuf::size_type accessedPosition;
-};
-
-#endif /* _SQUID_SRC_OUTOFBOUNDSEXCEPTION_H */
-
#include "base/RefCount.h"
#include "Debug.h"
#include "sbuf/DetailedStats.h"
-#include "sbuf/Exceptions.h"
-#include "sbuf/OutOfBoundsException.h"
#include "sbuf/SBuf.h"
#include "util.h"
debugs(24, 8, id << " finish appending " << actualSize << " bytes");
size_type newSize = length() + actualSize;
- if (newSize > min(maxSize,store_->capacity-off_))
- throw SBufTooBigException(__FILE__,__LINE__);
+ Must2(newSize <= min(maxSize,store_->capacity-off_), "raw append overflow");
len_ = newSize;
store_->size = off_ + newSize;
}
#else
sz = vsnprintf(space, spaceSize(), fmt, vargs);
#endif
+ Must2(sz >= 0, "vsnprintf() output error");
/* check for possible overflow */
/* snprintf on Linux returns -1 on output errors, or the size
requiredSpaceEstimate = sz*2; // TODO: tune heuristics
space = rawSpace(requiredSpaceEstimate);
sz = vsnprintf(space, spaceSize(), fmt, vargs);
- if (sz < 0) // output error in vsnprintf
- throw TextException("output error in second-go vsnprintf",__FILE__,
- __LINE__);
+ Must2(sz >= 0, "vsnprintf() output error despite increased buffer space");
}
- if (sz < 0) // output error in either vsnprintf
- throw TextException("output error in vsnprintf",__FILE__, __LINE__);
-
// data was appended, update internal state
len_ += sz;
++stats.caseChange;
}
-/**
- * checks whether the requested 'pos' is within the bounds of the SBuf
- * \throw OutOfBoundsException if access is out of bounds
- */
-void
-SBuf::checkAccessBounds(size_type pos) const
-{
- if (pos >= length())
- throw OutOfBoundsException(*this, pos, __FILE__, __LINE__);
-}
-
/** re-allocate the backing store of the SBuf.
*
* If there are contents in the SBuf, they will be copied over.
SBuf::reAlloc(size_type newsize)
{
debugs(24, 8, id << " new size: " << newsize);
- if (newsize > maxSize)
- throw SBufTooBigException(__FILE__, __LINE__);
+ Must(newsize <= maxSize);
MemBlob::Pointer newbuf = new MemBlob(newsize);
if (length() > 0)
newbuf->append(buf(), length());
#define SQUID_SBUF_H
#include "base/InstanceId.h"
+#include "base/TextException.h"
#include "Debug.h"
#include "globals.h"
-#include "sbuf/Exceptions.h"
#include "sbuf/forward.h"
#include "sbuf/MemBlob.h"
#include "sbuf/Stats.h"
/** random-access read to any char within the SBuf.
*
- * \throw OutOfBoundsException when access is out of bounds
+ * \throw std::exception when access is out of bounds
* \note bounds is 0 <= pos < length(); caller must pay attention to signedness
*/
char at(size_type pos) const {checkAccessBounds(pos); return operator[](pos);}
*
* \param pos the position to be overwritten
* \param toset the value to be written
- * \throw OutOfBoundsException when pos is of bounds
+ * \throw std::exception when pos is of bounds
* \note bounds is 0 <= pos < length(); caller must pay attention to signedness
* \note performs a copy-on-write if needed.
*/
/** Get the length of the SBuf, as a signed integer
*
* Compatibility function for printf(3) which requires a signed int
- * \throw SBufTooBigException if the SBuf is too big for a signed integer
+ * \throw std::exception if buffer length does not fit a signed integer
*/
int plength() const {
- if (length()>INT_MAX)
- throw SBufTooBigException(__FILE__, __LINE__);
+ Must(length() <= INT_MAX);
return static_cast<int>(length());
}
* After the reserveSpace request, the SBuf is guaranteed to have at
* least minSpace bytes of unused backing store following the currently
* used portion and single ownership of the backing store.
- * \throw SBufTooBigException if the user tries to allocate too big a SBuf
+ * \throw std::exception if the user tries to allocate a too big SBuf
*/
void reserveSpace(size_type minSpace) {
Must(minSpace <= maxSize);
* minCapacity bytes of total buffer size, including the currently-used
* portion; it is also guaranteed that after this call this SBuf
* has unique ownership of the underlying memory store.
- * \throw SBufTooBigException if the user tries to allocate too big a SBuf
+ * \throw std::exception if the user tries to allocate a too big SBuf
*/
void reserveCapacity(size_type minCapacity);
void cow(size_type minsize = npos);
- void checkAccessBounds(size_type pos) const;
+ void checkAccessBounds(const size_type pos) const { Must(pos < length()); }
/** Exports a writable pointer to the SBuf internal storage.
* \warning Use with EXTREME caution, this is a dangerous operation.
* buffer ownership. It is instead optimized for a one writer
* (appender), many readers scenario by avoiding unnecessary
* copying and allocations.
- * \throw SBufTooBigException if the user tries to allocate too big a SBuf
+ * \throw std::exception if the user tries to allocate a too big SBuf
*/
char *rawSpace(size_type minSize);
class SBufReverseIterator;
class SBufReservationRequirements;
-class OutOfBoundsException;
-class InvalidParamException;
-class SBufTooBigException;
-
class SBufStats;
typedef std::list<SBuf> SBufList;
/// removes our cleanup handler of the client connection socket
void
-Snmp::Forwarder::cleanup()
+Snmp::Forwarder::swanSong()
{
if (fd >= 0) {
if (closer != NULL) {
}
fd = -1;
}
+ Ipc::Forwarder::swanSong();
}
/// called when the client socket gets closed by some external force
protected:
/* Ipc::Forwarder API */
- virtual void cleanup(); ///< perform cleanup actions
+ virtual void swanSong();
virtual void handleTimeout();
virtual void handleException(const std::exception& e);
untrustedStack = sk_X509_new_null();
if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain, untrustedStack)) {
sk_X509_pop_free(untrustedStack, X509_free);
- throw TextException("Failed to attach untrusted certificates chain");
+ throw TextException("Failed to attach untrusted certificates chain", Here());
}
}
sk_X509_push(untrustedStack, cert);
Debug::parseOptions(char const *)
{}
-const char*
-SkipBuildPrefix(const char* path)
-{
- return path;
-}
-
Debug::Context *Debug::Current = nullptr;
Debug::Context::Context(const int aSection, const int aLevel):
//Mgr::Forwarder::Forwarder(int aFd, const ActionParams &aParams, HttpRequest* aRequest, StoreEntry* anEntry) STUB
//Mgr::Forwarder::~Forwarder() STUB
//protected:
-void Mgr::Forwarder::cleanup() STUB
+//void Mgr::Forwarder::swanSong() STUB
void Mgr::Forwarder::handleError() STUB
void Mgr::Forwarder::handleTimeout() STUB
void Mgr::Forwarder::handleException(const std::exception& e) STUB
#include <cppunit/extensions/HelperMacros.h>
-#include "sbuf/OutOfBoundsException.h"
+#include "base/TextException.h"
/*
* test the SBuf functionalities
CPPUNIT_TEST( testAppendStdString );
CPPUNIT_TEST( testAppendf );
CPPUNIT_TEST( testSubscriptOp );
- CPPUNIT_TEST_EXCEPTION( testSubscriptOpFail, OutOfBoundsException );
+ CPPUNIT_TEST_EXCEPTION( testSubscriptOpFail, TextException );
CPPUNIT_TEST( testComparisons );
CPPUNIT_TEST( testConsume );
CPPUNIT_TEST( testRawContent );
#include <cppunit/extensions/HelperMacros.h>
-#include "sbuf/OutOfBoundsException.h"
-
class testSBufList : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE( testSBufList );
/* DEBUG: section 19 Store Memory Primitives */
#include "squid.h"
-#include "base/TextException.h"
#include "Generic.h"
#include "mem_node.h"
#include "stmem.h"
#include <iostream>
#include <sstream>
-// required on some platforms
-unsigned int
-TextException::FileNameHash(const char *)
-{
- return 0;
-}
-
void
testLowAndHigh()
{
stub_debug.cc: $(top_srcdir)/src/tests/stub_debug.cc
cp $(top_srcdir)/src/tests/stub_debug.cc $@
+Here.cc: $(top_srcdir)/src/base/Here.cc
+ cp $(top_srcdir)/src/base/Here.cc $@
+
MemBuf.cc: $(top_srcdir)/src/MemBuf.cc
cp $(top_srcdir)/src/MemBuf.cc $@
# globals.cc is needed by test_tools.cc.
# Neither of these should be disted from here.
TESTSOURCES= test_tools.cc
-CLEANFILES += test_tools.cc MemBuf.cc stub_debug.cc time.cc stub_cbdata.cc stub_libmem.cc STUB.h
+CLEANFILES += test_tools.cc Here.cc MemBuf.cc stub_debug.cc time.cc stub_cbdata.cc stub_libmem.cc STUB.h
## Test Scripts
EXTRA_DIST += helper-ok-dying.pl helper-ok.pl
libexec_PROGRAMS = cachemgr$(CGIEXT)
cachemgr__CGIEXT__SOURCES = cachemgr.cc \
+ Here.cc \
MemBuf.cc \
stub_cbdata.cc \
stub_debug.cc \
LDADD = \
$(top_builddir)/src/ip/libip.la \
+ $(top_builddir)/src/base/libbase.la \
$(top_builddir)/lib/libmiscencoding.la \
$(top_builddir)/lib/libmiscutil.la \
$(COMPAT_LIB) \