Replace auto_ptr with scoped_ptr (#56). r=bryner

http://groups.google.com/group/airbag-dev/browse_thread/thread/54c66451ed8e2835


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@46 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
mmentovai 2006-10-23 20:25:42 +00:00
parent d119a921ea
commit 2466d8e993
12 changed files with 377 additions and 47 deletions

View file

@ -71,6 +71,7 @@ src_libairbag_la_SOURCES = \
src/processor/postfix_evaluator-inl.h \
src/processor/range_map.h \
src/processor/range_map-inl.h \
src/processor/scoped_ptr.h \
src/processor/source_line_resolver.cc \
src/processor/source_line_resolver.h \
src/processor/stack_frame_info.h \

View file

@ -371,6 +371,7 @@ src_libairbag_la_SOURCES = \
src/processor/postfix_evaluator-inl.h \
src/processor/range_map.h \
src/processor/range_map-inl.h \
src/processor/scoped_ptr.h \
src/processor/source_line_resolver.cc \
src/processor/source_line_resolver.h \
src/processor/stack_frame_info.h \

View file

@ -49,17 +49,16 @@ typedef SSIZE_T ssize_t;
#endif // _WIN32
#include <map>
#include <memory>
#include <vector>
#include "processor/minidump.h"
#include "processor/range_map-inl.h"
#include "processor/scoped_ptr.h"
namespace google_airbag {
using std::auto_ptr;
using std::vector;
@ -163,7 +162,7 @@ static inline void Swap(MDGUID* guid) {
// of making it a dependency when we don't care about anything but UTF-16.
static string* UTF16ToUTF8(const vector<u_int16_t>& in,
bool swap) {
auto_ptr<string> out(new string());
scoped_ptr<string> out(new string());
// Set the string's initial capacity to the number of UTF-16 characters,
// because the UTF-8 representation will always be at least this long.
@ -288,7 +287,7 @@ bool MinidumpContext::Read(u_int32_t expected_size) {
if (expected_size != sizeof(MDRawContextX86))
return false;
auto_ptr<MDRawContextX86> context_x86(new MDRawContextX86());
scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86());
// Set the context_flags member, which has already been read, and
// read the rest of the structure beginning with the first member
@ -355,7 +354,7 @@ bool MinidumpContext::Read(u_int32_t expected_size) {
if (expected_size != sizeof(MDRawContextPPC))
return false;
auto_ptr<MDRawContextPPC> context_ppc(new MDRawContextPPC());
scoped_ptr<MDRawContextPPC> context_ppc(new MDRawContextPPC());
// Set the context_flags member, which has already been read, and
// read the rest of the structure beginning with the first member
@ -647,7 +646,7 @@ const u_int8_t* MinidumpMemoryRegion::GetMemory() {
return NULL;
// TODO(mmentovai): verify rational size!
auto_ptr< vector<u_int8_t> > memory(
scoped_ptr< vector<u_int8_t> > memory(
new vector<u_int8_t>(descriptor_->memory.data_size));
if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size))
@ -817,7 +816,7 @@ MinidumpContext* MinidumpThread::GetContext() {
if (!minidump_->SeekSet(thread_.thread_context.rva))
return NULL;
auto_ptr<MinidumpContext> context(new MinidumpContext(minidump_));
scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_));
if (!context->Read(thread_.thread_context.data_size))
return NULL;
@ -916,7 +915,7 @@ bool MinidumpThreadList::Read(u_int32_t expected_size) {
}
// TODO(mmentovai): verify rational size!
auto_ptr<MinidumpThreads> threads(
scoped_ptr<MinidumpThreads> threads(
new MinidumpThreads(thread_count, MinidumpThread(minidump_)));
for (unsigned int thread_index = 0;
@ -1086,7 +1085,7 @@ const u_int8_t* MinidumpModule::GetCVRecord() {
// variable-sized due to their pdb_file_name fields; these structures
// are not sizeof(MDCVInfoPDB70) or sizeof(MDCVInfoPDB20) and treating
// them as such would result in incomplete structures or overruns.
auto_ptr< vector<u_int8_t> > cv_record(
scoped_ptr< vector<u_int8_t> > cv_record(
new vector<u_int8_t>(module_.cv_record.data_size));
if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size))
@ -1161,7 +1160,7 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord() {
// because the MDImageDebugMisc is variable-sized due to its data field;
// this structure is not sizeof(MDImageDebugMisc) and treating it as such
// would result in an incomplete structure or an overrun.
auto_ptr< vector<u_int8_t> > misc_record_mem(
scoped_ptr< vector<u_int8_t> > misc_record_mem(
new vector<u_int8_t>(module_.misc_record.data_size));
MDImageDebugMisc* misc_record =
reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_mem)[0]);
@ -1443,7 +1442,7 @@ bool MinidumpModuleList::Read(u_int32_t expected_size) {
}
// TODO(mmentovai): verify rational size!
auto_ptr<MinidumpModules> modules(
scoped_ptr<MinidumpModules> modules(
new MinidumpModules(module_count, MinidumpModule(minidump_)));
for (unsigned int module_index = 0;
@ -1557,7 +1556,8 @@ bool MinidumpMemoryList::Read(u_int32_t expected_size) {
}
// TODO(mmentovai): verify rational size!
auto_ptr<MemoryDescriptors> descriptors(new MemoryDescriptors(region_count));
scoped_ptr<MemoryDescriptors> descriptors(
new MemoryDescriptors(region_count));
// Read the entire array in one fell swoop, instead of reading one entry
// at a time in the loop.
@ -1566,7 +1566,7 @@ bool MinidumpMemoryList::Read(u_int32_t expected_size) {
return false;
}
auto_ptr<MemoryRegions> regions(
scoped_ptr<MemoryRegions> regions(
new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_)));
for (unsigned int region_index = 0;
@ -1720,7 +1720,7 @@ MinidumpContext* MinidumpException::GetContext() {
if (!minidump_->SeekSet(exception_.thread_context.rva))
return NULL;
auto_ptr<MinidumpContext> context(new MinidumpContext(minidump_));
scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_));
if (!context->Read(exception_.thread_context.data_size))
return NULL;
@ -2060,7 +2060,7 @@ bool Minidump::Read() {
return false;
// TODO(mmentovai): verify rational size!
auto_ptr<MinidumpDirectoryEntries> directory(
scoped_ptr<MinidumpDirectoryEntries> directory(
new MinidumpDirectoryEntries(header_.stream_count));
// Read the entire array in one fell swoop, instead of reading one entry
@ -2069,7 +2069,7 @@ bool Minidump::Read() {
sizeof(MDRawDirectory) * header_.stream_count))
return false;
auto_ptr<MinidumpStreamMap> stream_map(new MinidumpStreamMap());
scoped_ptr<MinidumpStreamMap> stream_map(new MinidumpStreamMap());
for (unsigned int stream_index = 0;
stream_index < header_.stream_count;
@ -2312,7 +2312,7 @@ T* Minidump::GetStream(T** stream) {
if (!SeekToStreamType(stream_type, &stream_length))
return NULL;
auto_ptr<T> new_stream(new T(this));
scoped_ptr<T> new_stream(new T(this));
if (!new_stream->Read(stream_length))
return NULL;

View file

@ -27,14 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory>
#include "google/minidump_processor.h"
#include "processor/minidump.h"
#include "processor/scoped_ptr.h"
#include "processor/stackwalker_x86.h"
using std::auto_ptr;
namespace google_airbag {
MinidumpProcessor::MinidumpProcessor(SymbolSupplier *supplier)
@ -71,7 +68,7 @@ CallStack* MinidumpProcessor::Process(const string &minidump_file) {
return NULL;
}
auto_ptr<Stackwalker> walker(
scoped_ptr<Stackwalker> walker(
Stackwalker::StackwalkerForCPU(exception->GetContext(), thread_memory,
dump.GetModuleList(), supplier_));
if (!walker.get()) {

View file

@ -30,18 +30,18 @@
// Unit test for MinidumpProcessor. Uses a pre-generated minidump and
// corresponding symbol file, and checks the stack frames for correctness.
#include <memory>
#include <string>
#include "google/call_stack.h"
#include "google/minidump_processor.h"
#include "google/stack_frame.h"
#include "google/symbol_supplier.h"
#include "processor/minidump.h"
#include "processor/scoped_ptr.h"
using std::auto_ptr;
using std::string;
using google_airbag::CallStack;
using google_airbag::MinidumpProcessor;
using google_airbag::scoped_ptr;
#define ASSERT_TRUE(cond) \
if (!(cond)) { \
@ -79,7 +79,7 @@ static bool RunTests() {
string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
"/src/processor/testdata/minidump2.dmp";
auto_ptr<CallStack> stack(processor.Process(minidump_file));
scoped_ptr<CallStack> stack(processor.Process(minidump_file));
ASSERT_TRUE(stack.get());
ASSERT_EQ(stack->frames()->size(), 4);

View file

@ -35,16 +35,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <memory>
#include <string>
#include "google/call_stack.h"
#include "google/stack_frame.h"
#include "processor/minidump.h"
#include "processor/scoped_ptr.h"
#include "processor/stackwalker_x86.h"
using std::auto_ptr;
using std::string;
using google_airbag::CallStack;
using google_airbag::MemoryRegion;
@ -54,6 +53,7 @@ using google_airbag::MinidumpException;
using google_airbag::MinidumpModuleList;
using google_airbag::MinidumpThread;
using google_airbag::MinidumpThreadList;
using google_airbag::scoped_ptr;
using google_airbag::StackFrame;
using google_airbag::Stackwalker;
@ -107,14 +107,14 @@ int main(int argc, char **argv) {
exit(1);
}
auto_ptr<Stackwalker> stackwalker(
scoped_ptr<Stackwalker> stackwalker(
Stackwalker::StackwalkerForCPU(context, stack_memory, modules, NULL));
if (!stackwalker.get()) {
fprintf(stderr, "Stackwalker::StackwalkerForCPU failed\n");
exit(1);
}
auto_ptr<CallStack> stack(stackwalker->Walk());
scoped_ptr<CallStack> stack(stackwalker->Walk());
unsigned int index;
for (index = 0; index < stack->frames()->size(); ++index) {

View file

@ -34,14 +34,14 @@
#include <climits>
#include <cstdio>
#include <memory>
#include "processor/linked_ptr.h"
#include "processor/range_map-inl.h"
#include "processor/scoped_ptr.h"
using std::auto_ptr;
using google_airbag::linked_ptr;
using google_airbag::scoped_ptr;
using google_airbag::RangeMap;
@ -331,7 +331,7 @@ bool RunTests() {
// Maintain the range map in a pointer so that deletion can be meaningfully
// tested.
auto_ptr<TestMap> range_map(new TestMap());
scoped_ptr<TestMap> range_map(new TestMap());
// Run all of the test sets in sequence.
unsigned int range_test_set_count = sizeof(range_test_sets) /

335
src/processor/scoped_ptr.h Normal file
View file

@ -0,0 +1,335 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
//
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
// of the object pointed to, either on destruction of the scoped_ptr or via
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
// use shared_ptr or std::auto_ptr if your needs are more complex.
// *** NOTE ***
// If your scoped_ptr is a class member of class FOO pointing to a
// forward declared type BAR (as shown below), then you MUST use a non-inlined
// version of the destructor. The destructor of a scoped_ptr (called from
// FOO's destructor) must have a complete definition of BAR in order to
// destroy it. Example:
//
// -- foo.h --
// class BAR;
//
// class FOO {
// public:
// FOO();
// ~FOO(); // Required for sources that instantiate class FOO to compile!
//
// private:
// scoped_ptr<BAR> bar_;
// };
//
// -- foo.cc --
// #include "foo.h"
// FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition.
// scoped_ptr_malloc added by Google
// When one of these goes out of scope, instead of doing a delete or
// delete[], it calls free(). scoped_ptr_malloc<char> is likely to see
// much more use than any other specializations.
// release() added by Google
// Use this to conditionally transfer ownership of a heap-allocated object
// to the caller, usually on method success.
#ifndef PROCESSOR_SCOPED_PTR_H__
#define PROCESSOR_SCOPED_PTR_H__
#include <cstddef> // for std::ptrdiff_t
#include <assert.h> // for assert
#include <stdlib.h> // for free() decl
namespace google_airbag {
template <typename T>
class scoped_ptr {
private:
T* ptr;
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
public:
typedef T element_type;
explicit scoped_ptr(T* p = 0): ptr(p) {}
~scoped_ptr() {
typedef char type_must_be_complete[sizeof(T)];
delete ptr;
}
void reset(T* p = 0) {
typedef char type_must_be_complete[sizeof(T)];
if (ptr != p) {
delete ptr;
ptr = p;
}
}
T& operator*() const {
assert(ptr != 0);
return *ptr;
}
T* operator->() const {
assert(ptr != 0);
return ptr;
}
bool operator==(T* p) const {
return ptr == p;
}
bool operator!=(T* p) const {
return ptr != p;
}
T* get() const {
return ptr;
}
void swap(scoped_ptr & b) {
T* tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
T* release() {
T* tmp = ptr;
ptr = 0;
return tmp;
}
private:
// no reason to use these: each scoped_ptr should have its own object
template <typename U> bool operator==(scoped_ptr<U> const& p) const;
template <typename U> bool operator!=(scoped_ptr<U> const& p) const;
};
template<typename T> inline
void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
a.swap(b);
}
template<typename T> inline
bool operator==(T* p, const scoped_ptr<T>& b) {
return p == b.get();
}
template<typename T> inline
bool operator!=(T* p, const scoped_ptr<T>& b) {
return p != b.get();
}
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
// is guaranteed, either on destruction of the scoped_array or via an explicit
// reset(). Use shared_array or std::vector if your needs are more complex.
template<typename T>
class scoped_array {
private:
T* ptr;
scoped_array(scoped_array const &);
scoped_array & operator=(scoped_array const &);
public:
typedef T element_type;
explicit scoped_array(T* p = 0) : ptr(p) {}
~scoped_array() {
typedef char type_must_be_complete[sizeof(T)];
delete[] ptr;
}
void reset(T* p = 0) {
typedef char type_must_be_complete[sizeof(T)];
if (ptr != p) {
delete [] ptr;
ptr = p;
}
}
T& operator[](std::ptrdiff_t i) const {
assert(ptr != 0);
assert(i >= 0);
return ptr[i];
}
bool operator==(T* p) const {
return ptr == p;
}
bool operator!=(T* p) const {
return ptr != p;
}
T* get() const {
return ptr;
}
void swap(scoped_array & b) {
T* tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
T* release() {
T* tmp = ptr;
ptr = 0;
return tmp;
}
private:
// no reason to use these: each scoped_array should have its own object
template <typename U> bool operator==(scoped_array<U> const& p) const;
template <typename U> bool operator!=(scoped_array<U> const& p) const;
};
template<class T> inline
void swap(scoped_array<T>& a, scoped_array<T>& b) {
a.swap(b);
}
template<typename T> inline
bool operator==(T* p, const scoped_array<T>& b) {
return p == b.get();
}
template<typename T> inline
bool operator!=(T* p, const scoped_array<T>& b) {
return p != b.get();
}
// This class wraps the c library function free() in a class that can be
// passed as a template argument to scoped_ptr_malloc below.
class ScopedPtrMallocFree {
public:
inline void operator()(void* x) const {
free(x);
}
};
// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
// second template argument, the functor used to free the object.
template<typename T, typename FreeProc = ScopedPtrMallocFree>
class scoped_ptr_malloc {
private:
T* ptr;
scoped_ptr_malloc(scoped_ptr_malloc const &);
scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
public:
typedef T element_type;
explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
~scoped_ptr_malloc() {
typedef char type_must_be_complete[sizeof(T)];
free_((void*) ptr);
}
void reset(T* p = 0) {
typedef char type_must_be_complete[sizeof(T)];
if (ptr != p) {
free_((void*) ptr);
ptr = p;
}
}
T& operator*() const {
assert(ptr != 0);
return *ptr;
}
T* operator->() const {
assert(ptr != 0);
return ptr;
}
bool operator==(T* p) const {
return ptr == p;
}
bool operator!=(T* p) const {
return ptr != p;
}
T* get() const {
return ptr;
}
void swap(scoped_ptr_malloc & b) {
T* tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
T* release() {
T* tmp = ptr;
ptr = 0;
return tmp;
}
private:
// no reason to use these: each scoped_ptr_malloc should have its own object
template <typename U, typename GP>
bool operator==(scoped_ptr_malloc<U, GP> const& p) const;
template <typename U, typename GP>
bool operator!=(scoped_ptr_malloc<U, GP> const& p) const;
static FreeProc const free_;
};
template<typename T, typename FP>
FP const scoped_ptr_malloc<T,FP>::free_ = FP();
template<typename T, typename FP> inline
void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) {
a.swap(b);
}
template<typename T, typename FP> inline
bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) {
return p == b.get();
}
template<typename T, typename FP> inline
bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) {
return p != b.get();
}
} // namespace google_airbag
#endif // PROCESSOR_SCOPED_PTR_H__

View file

@ -30,7 +30,6 @@
#include <stdio.h>
#include <string.h>
#include <map>
#include <memory>
#include <vector>
#include <utility>
#include "processor/source_line_resolver.h"
@ -39,9 +38,9 @@
#include "processor/address_map-inl.h"
#include "processor/contained_range_map-inl.h"
#include "processor/range_map-inl.h"
#include "processor/scoped_ptr.h"
#include "processor/stack_frame_info.h"
using std::auto_ptr;
using std::map;
using std::vector;
using std::make_pair;
@ -278,7 +277,7 @@ StackFrameInfo* SourceLineResolver::Module::LookupAddress(
stack_info_[STACK_INFO_FPO].RetrieveRange(address, &retrieved_info);
}
auto_ptr<StackFrameInfo> frame_info;
scoped_ptr<StackFrameInfo> frame_info;
if (retrieved_info.get()) {
frame_info.reset(new StackFrameInfo());
frame_info->CopyFrom(*retrieved_info.get());

View file

@ -28,16 +28,16 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include <memory>
#include <string>
#include "processor/source_line_resolver.h"
#include "google/stack_frame.h"
#include "processor/linked_ptr.h"
#include "processor/scoped_ptr.h"
#include "processor/stack_frame_info.h"
using std::auto_ptr;
using std::string;
using google_airbag::linked_ptr;
using google_airbag::scoped_ptr;
using google_airbag::SourceLineResolver;
using google_airbag::StackFrame;
using google_airbag::StackFrameInfo;
@ -78,7 +78,7 @@ static bool RunTests() {
StackFrame frame;
frame.instruction = 0x1000;
frame.module_name = "module1";
auto_ptr<StackFrameInfo> frame_info(resolver.FillSourceLineInfo(&frame));
scoped_ptr<StackFrameInfo> frame_info(resolver.FillSourceLineInfo(&frame));
ASSERT_EQ(frame.function_name, "Function1_1");
ASSERT_EQ(frame.source_file_name, "file1_1.cc");
ASSERT_EQ(frame.source_line, 44);

View file

@ -34,14 +34,13 @@
// Author: Mark Mentovai
#include <memory>
#include "processor/stackwalker.h"
#include "google/call_stack.h"
#include "google/stack_frame.h"
#include "google/symbol_supplier.h"
#include "processor/linked_ptr.h"
#include "processor/minidump.h"
#include "processor/scoped_ptr.h"
#include "processor/source_line_resolver.h"
#include "processor/stack_frame_info.h"
#include "processor/stackwalker_ppc.h"
@ -49,8 +48,6 @@
namespace google_airbag {
using std::auto_ptr;
Stackwalker::Stackwalker(MemoryRegion *memory, MinidumpModuleList *modules,
SymbolSupplier *supplier)
@ -61,7 +58,7 @@ Stackwalker::Stackwalker(MemoryRegion *memory, MinidumpModuleList *modules,
CallStack* Stackwalker::Walk() {
SourceLineResolver resolver;
auto_ptr<CallStack> stack(new CallStack());
scoped_ptr<CallStack> stack(new CallStack());
// stack_frame_info parallels the CallStack. The vector is passed to the
// GetCallerFrame function. It contains information that may be helpful
@ -72,7 +69,7 @@ CallStack* Stackwalker::Walk() {
// no more.
// Take ownership of the pointer returned by GetContextFrame.
auto_ptr<StackFrame> frame(GetContextFrame());
scoped_ptr<StackFrame> frame(GetContextFrame());
while (frame.get()) {
// frame already contains a good frame with properly set instruction and

View file

@ -38,7 +38,6 @@
#include <cstdio>
#include <memory>
#include "google/airbag_types.h"
#include "google/call_stack.h"
@ -46,10 +45,11 @@
#include "google/stack_frame_cpu.h"
#include "processor/memory_region.h"
#include "processor/minidump_format.h"
#include "processor/scoped_ptr.h"
using std::auto_ptr;
using google_airbag::CallStack;
using google_airbag::MemoryRegion;
using google_airbag::scoped_ptr;
using google_airbag::StackFrame;
using google_airbag::StackFramePPC;
using google_airbag::StackFrameX86;
@ -218,7 +218,7 @@ static unsigned int CountCallerFrames() {
StackwalkerPPC stackwalker = StackwalkerPPC(&context, &memory, NULL, NULL);
#endif // __i386__ || __ppc__
auto_ptr<CallStack> stack(stackwalker.Walk());
scoped_ptr<CallStack> stack(stackwalker.Walk());
#ifdef PRINT_STACKS
printf("\n");