Use zone memory for StackTrace::ToCString.

Fixes memory leak of the TextBuffer's buffer.

R=fschneider@google.com

Review-Url: https://codereview.chromium.org/2689563003 .
This commit is contained in:
Ryan Macnak
2017-02-09 12:34:16 -08:00
parent 29c77519d0
commit 4e8b265ea0
4 changed files with 109 additions and 3 deletions
+4 -3
View File
@@ -47,6 +47,7 @@
#include "vm/type_table.h"
#include "vm/unicode.h"
#include "vm/weak_code.h"
#include "vm/zone_text_buffer.h"
namespace dart {
@@ -22332,7 +22333,7 @@ const char* StackTrace::ToCString() const {
static void PrintStackTraceFrame(Zone* zone,
TextBuffer* buffer,
ZoneTextBuffer* buffer,
const Function& function,
TokenPosition token_pos,
intptr_t frame_index) {
@@ -22370,7 +22371,7 @@ const char* StackTrace::ToCStringInternal(intptr_t* frame_index,
Code& code = Code::Handle(zone);
GrowableArray<const Function*> inlined_functions;
GrowableArray<TokenPosition> inlined_token_positions;
TextBuffer buffer(1024);
ZoneTextBuffer buffer(zone, 1024);
// Iterate through the stack frames and create C string description
// for each frame.
@@ -22416,7 +22417,7 @@ const char* StackTrace::ToCStringInternal(intptr_t* frame_index,
}
}
return buffer.Steal();
return buffer.buffer();
}
+2
View File
@@ -555,5 +555,7 @@
'zone.cc',
'zone.h',
'zone_test.cc',
'zone_text_buffer.cc',
'zone_text_buffer.h',
],
}
+65
View File
@@ -0,0 +1,65 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/zone_text_buffer.h"
#include "platform/assert.h"
#include "platform/globals.h"
#include "platform/utils.h"
#include "vm/os.h"
#include "vm/zone.h"
namespace dart {
ZoneTextBuffer::ZoneTextBuffer(Zone* zone, intptr_t initial_capacity)
: zone_(zone), buffer_(NULL), length_(0), capacity_(0) {
ASSERT(initial_capacity > 0);
buffer_ = reinterpret_cast<char*>(zone->Alloc<char>(initial_capacity));
capacity_ = initial_capacity;
}
intptr_t ZoneTextBuffer::Printf(const char* format, ...) {
va_list args;
va_start(args, format);
intptr_t remaining = capacity_ - length_;
ASSERT(remaining >= 0);
intptr_t len = OS::VSNPrint(buffer_ + length_, remaining, format, args);
va_end(args);
if (len >= remaining) {
EnsureCapacity(len);
remaining = capacity_ - length_;
ASSERT(remaining > len);
va_list args2;
va_start(args2, format);
intptr_t len2 = OS::VSNPrint(buffer_ + length_, remaining, format, args2);
va_end(args2);
ASSERT(len == len2);
}
length_ += len;
buffer_[length_] = '\0';
return len;
}
void ZoneTextBuffer::AddString(const char* s) {
Printf("%s", s);
}
void ZoneTextBuffer::EnsureCapacity(intptr_t len) {
intptr_t remaining = capacity_ - length_;
if (remaining <= len) {
const int kBufferSpareCapacity = 64; // Somewhat arbitrary.
// TODO(turnidge): do we need to guard against overflow or other
// security issues here? Text buffers are used by the debugger
// to send user-controlled data (e.g. values of string variables) to
// the debugger front-end.
intptr_t new_capacity = capacity_ + len + kBufferSpareCapacity;
buffer_ = zone_->Realloc<char>(buffer_, capacity_, new_capacity);
capacity_ = new_capacity;
}
}
} // namespace dart
+38
View File
@@ -0,0 +1,38 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef RUNTIME_VM_ZONE_TEXT_BUFFER_H_
#define RUNTIME_VM_ZONE_TEXT_BUFFER_H_
#include "vm/allocation.h"
#include "vm/globals.h"
namespace dart {
class Zone;
// TextBuffer maintains a dynamic character buffer with a printf-style way to
// append text.
class ZoneTextBuffer : ValueObject {
public:
ZoneTextBuffer(Zone* zone, intptr_t initial_capacity);
~ZoneTextBuffer() {}
intptr_t Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
void AddString(const char* s);
char* buffer() { return buffer_; }
intptr_t length() { return length_; }
private:
void EnsureCapacity(intptr_t len);
Zone* zone_;
char* buffer_;
intptr_t length_;
intptr_t capacity_;
};
} // namespace dart
#endif // RUNTIME_VM_ZONE_TEXT_BUFFER_H_