-
Notifications
You must be signed in to change notification settings - Fork 154
UT[BMQ]: log default allocations #801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright 2014-2025 Bloomberg Finance L.P. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// bmqtst_loggingallocator.cpp -*-C++-*- | ||
#include <bmqtst_loggingallocator.h> | ||
|
||
#include <bmqscm_version.h> | ||
|
||
#include <bmqu_memoutstream.h> | ||
|
||
// BDE | ||
#include <balst_stacktraceprintutil.h> // balst::StackTracePrintUtil | ||
#include <bsl_iostream.h> // bsl::cerr | ||
|
||
namespace BloombergLP { | ||
namespace bmqtst { | ||
|
||
namespace { | ||
|
||
static bool isStackInExceptions(const bslstl::StringRef& str) | ||
{ | ||
struct StackExceptionRule { | ||
const char* d_stackStr; | ||
} k_RULES[] = { | ||
{"bdlmt::EventSchedulerTestTimeSource::EventSchedulerTestTimeSource"}, | ||
{"bdls::FilesystemUtil::makeUnsafeTemporaryFilename"}, | ||
{"bdls::FilesystemUtil::remove"}, | ||
{"MessageGUIDUtil::initialize"}}; | ||
|
||
const size_t k_NUM_RULES = sizeof(k_RULES) / sizeof(*k_RULES); | ||
for (size_t idx = 0; idx < k_NUM_RULES; ++idx) { | ||
const StackExceptionRule& rule = k_RULES[idx]; | ||
if (str.find(rule.d_stackStr) != bsl::string::npos) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} | ||
|
||
// ---------------------- | ||
// class LoggingAllocator | ||
// ---------------------- | ||
|
||
// CREATORS | ||
|
||
LoggingAllocator::LoggingAllocator(bool failFast, bslma::Allocator* allocator) | ||
: d_allocator_p(allocator) | ||
, d_failFast(failFast) | ||
, d_failed(false) | ||
{ | ||
// NOTHING | ||
} | ||
|
||
LoggingAllocator::~LoggingAllocator() | ||
{ | ||
// NOTHING | ||
} | ||
|
||
// MANIPULATORS | ||
|
||
void* LoggingAllocator::allocate(size_type size) | ||
{ | ||
bmqu::MemOutStream os(d_allocator_p); | ||
balst::StackTracePrintUtil::printStackTrace(os); | ||
|
||
if (!isStackInExceptions(os.str())) { | ||
bsl::cerr << os.str() << bsl::endl; | ||
bsl::flush(bsl::cerr); | ||
|
||
d_failed.storeRelaxed(true); | ||
if (d_failFast) { | ||
BSLS_ASSERT_OPT(false && "The allocation was recorded"); | ||
} | ||
Comment on lines
+84
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In theory BSLS_ASSERT_OPT is not guaranteed to be enabled in every build, it's probably more appropriate to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point! Alternatively, what about raising an exception? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We cannot raise exceptions in this code by policy. Oddly enough I don't think we document that policy anywhere! But we do not allow exceptions to be thrown in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently, any assert statement generates an exception that causes termination of the program if not handled.
|
||
} | ||
return d_allocator_p->allocate(size); | ||
} | ||
|
||
void LoggingAllocator::deallocate(void* address) | ||
{ | ||
d_allocator_p->deallocate(address); | ||
} | ||
|
||
void LoggingAllocator::checkNoAllocations() | ||
{ | ||
BSLS_ASSERT_OPT(!d_failed.load() && "The allocations were recorded"); | ||
} | ||
|
||
} // close package namespace | ||
} // close enterprise namespace |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright 2014-2025 Bloomberg Finance L.P. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// bmqtst_loggingallocator.h -*-C++-*- | ||
#ifndef INCLUDED_BMQTST_LOGGINGALLOCATOR | ||
#define INCLUDED_BMQTST_LOGGINGALLOCATOR | ||
|
||
//@PURPOSE: Provide a 'bslma::Allocator' caching allocation stack traces. | ||
// | ||
//@CLASSES: | ||
// bmqtst::LoggingAllocator : allocator adaptor. | ||
// | ||
//@DESCRIPTION: This component defines a mechanism, 'bmqtst::LoggingAllocator' | ||
// which implements the 'bslma::Allocator' protocol and which logs stack traces | ||
// on any allocation. | ||
|
||
// BDE | ||
#include <bsl_string.h> | ||
#include <bsl_vector.h> | ||
#include <bslma_allocator.h> | ||
#include <bsls_atomic.h> | ||
#include <bsls_keyword.h> | ||
|
||
namespace BloombergLP { | ||
|
||
namespace bmqtst { | ||
|
||
// ====================== | ||
// class LoggingAllocator | ||
// ====================== | ||
|
||
/// An allocator caching allocation stack traces. | ||
class LoggingAllocator BSLS_KEYWORD_FINAL : public bslma::Allocator { | ||
public: | ||
// PUBLIC TYPES | ||
|
||
/// Alias for a signed integral type capable of representing the number | ||
/// of bytes in this platform's virtual address space. | ||
typedef bsls::Types::size_type size_type; | ||
|
||
private: | ||
// DATA | ||
/// @brief Base allocator to use. | ||
bslma::Allocator* d_allocator_p; | ||
|
||
/// @brief The flag indicaing that the allocator must fail instantly if any | ||
/// undesired allocation happens. | ||
bool d_failFast; | ||
|
||
/// @brief The flag indicating that this allocator has failed. | ||
bsls::AtomicBool d_failed; | ||
|
||
private: | ||
// NOT IMPLEMENTED | ||
LoggingAllocator(const LoggingAllocator&) BSLS_KEYWORD_DELETED; | ||
LoggingAllocator& operator=(const LoggingAllocator&) BSLS_KEYWORD_DELETED; | ||
|
||
public: | ||
// CREATORS | ||
|
||
/// @brief Construct a logging allocator. | ||
/// @param failFast The flag indicating whether this allocator must raise | ||
/// an exception instantly on any undesired allocation. | ||
/// @param allocator The base allocator to use, or use the default | ||
/// allocator if this arg is null. | ||
explicit LoggingAllocator(bool failFast = false, | ||
bslma::Allocator* allocator = 0); | ||
|
||
/// Destroy this object. | ||
~LoggingAllocator() BSLS_KEYWORD_OVERRIDE; | ||
|
||
// MANIPULATORS | ||
|
||
// (virtual bslma::Allocator) | ||
|
||
/// @brief Return a newly allocated block of memory. If this allocator | ||
/// cannot return the requested number of bytes, then it will | ||
/// throw a `bsl::bad_alloc` exception in an exception-enabled | ||
/// build, or else will abort the program in a non-exception build. | ||
/// The behavior is undefined unless `0 <= size`. Note that the | ||
/// alignment of the address returned conforms to the platform | ||
/// requirement for any object of the specified `size`. | ||
/// @param size The minimum size of the newly allocated block (in bytes). | ||
/// If `size` is 0, a null pointer is returned with no other | ||
/// effect. | ||
/// @return The memory address of the allocated block or a null pointer. | ||
void* allocate(size_type size) BSLS_KEYWORD_OVERRIDE; | ||
|
||
/// @brief Return the memory block at the specified `address` back to this | ||
/// allocator. The behavior is undefined unless `address` was | ||
/// allocated using this allocator object and has not already been | ||
/// deallocated. | ||
/// @param address The address of the memory block to deallocate. If this | ||
/// argument is a null pointer, the function doesn't have an effect. | ||
void deallocate(void* address) BSLS_KEYWORD_OVERRIDE; | ||
|
||
/// @brief Check whether the undesired allocations were recorded and raise | ||
/// an exception if any. | ||
void checkNoAllocations(); | ||
Comment on lines
+109
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't raise an exception if it fails, rather it just ASSERTs. I think it would be better to return |
||
}; | ||
|
||
} // close package namespace | ||
} // close enterprise namespace | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
bmqtst_blobtestutil | ||
bmqtst_loggingallocator | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
bmqtst_scopedlogobserver | ||
bmqtst_testhelper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to
MANIPULATORS