Fixing a bunch of memory leaks.

Courtesy of perftools. Most are not really relevant but cleanup  the
perftools output. There was a big one in the logging code as well
though.
This commit is contained in:
Robin Sommer 2011-09-29 22:23:51 -07:00
parent 221d1663be
commit 91ed9ffa8f
4 changed files with 95 additions and 30 deletions

27
CHANGES
View file

@ -1,4 +1,31 @@
1.6-dev-1333 | 2011-09-29 22:29:51 -0700
* Fixing a number of memory leaks. (Robin Sommer)
* Loaded_scripts.log is indented with spaces now and makes more
sense to look at. (Seth Hall)
* Teach HTTP parser to derive content length of multipart/byteranges
bodies. Addresses #488. (Jon Siwek)
* Change logging of HTTP 1xx responses to occur in their own
columns. Addresses #411. (Jon Siwek)
* Fix handling of HTTP 1xx response codes. Addresses #411).
* Taking advantage of yet another trick to get installed browser
plugins. (Seth Hall)
- With the software-browser-plugins script you can watch for Omniture
advertising servers to grab the list of installed plugins.
- I reorganized the plugin detection a bit too to abstract it better.
- Removed the WEB_ prefix from all of the Software::Type HTTP enums.
They were essentially redundant due to the full name already being
HTTP::SERVER (for example).
1.6-dev-1316 | 2011-09-28 16:50:05 -0700 1.6-dev-1316 | 2011-09-28 16:50:05 -0700
* Unit test cleanup. Updated README and collected coverage-related * Unit test cleanup. Updated README and collected coverage-related

View file

@ -1 +1 @@
1.6-dev-1316 1.6-dev-1333

View file

@ -966,6 +966,13 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns)
for ( int j = 0; j < filter->num_fields; ++j ) for ( int j = 0; j < filter->num_fields; ++j )
arg_fields[j] = new LogField(*filter->fields[j]); arg_fields[j] = new LogField(*filter->fields[j]);
if ( filter->remote )
remote_serializer->SendLogCreateWriter(stream->id,
filter->writer,
path,
filter->num_fields,
arg_fields);
if ( filter->local ) if ( filter->local )
{ {
writer = CreateWriter(stream->id, filter->writer, writer = CreateWriter(stream->id, filter->writer,
@ -979,17 +986,17 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns)
} }
} }
else else
{
// Insert a null pointer into the map to make // Insert a null pointer into the map to make
// sure we don't try creating it again. // sure we don't try creating it again.
stream->writers.insert(Stream::WriterMap::value_type( stream->writers.insert(Stream::WriterMap::value_type(
Stream::WriterPathPair(filter->writer->AsEnum(), path), 0)); Stream::WriterPathPair(filter->writer->AsEnum(), path), 0));
if ( filter->remote ) for( int i = 0; i < filter->num_fields; ++i)
remote_serializer->SendLogCreateWriter(stream->id, delete arg_fields[i];
filter->writer,
path, delete [] arg_fields;
filter->num_fields, }
arg_fields);
} }
// Alright, can do the write now. // Alright, can do the write now.

View file

@ -1460,7 +1460,9 @@ void RemoteSerializer::Finish()
while ( io->CanWrite() ); while ( io->CanWrite() );
loop_over_list(peers, i) loop_over_list(peers, i)
{
CloseConnection(peers[i]); CloseConnection(peers[i]);
}
} }
bool RemoteSerializer::Poll(bool may_block) bool RemoteSerializer::Poll(bool may_block)
@ -1812,7 +1814,7 @@ RemoteSerializer::Peer* RemoteSerializer::AddPeer(uint32 ip, uint16 port,
peer->sync_point = 0; peer->sync_point = 0;
peer->print_buffer = 0; peer->print_buffer = 0;
peer->print_buffer_used = 0; peer->print_buffer_used = 0;
peer->log_buffer = 0; peer->log_buffer = new char[LOG_BUFFER_SIZE];
peer->log_buffer_used = 0; peer->log_buffer_used = 0;
peers.append(peer); peers.append(peer);
@ -2048,8 +2050,6 @@ bool RemoteSerializer::ProcessRequestLogs()
Log(LogInfo, "peer requested logs", current_peer); Log(LogInfo, "peer requested logs", current_peer);
current_peer->logs_requested = true; current_peer->logs_requested = true;
current_peer->log_buffer = new char[LOG_BUFFER_SIZE];
current_peer->log_buffer_used = 0;
return true; return true;
} }
@ -2512,18 +2512,25 @@ bool RemoteSerializer::SendLogCreateWriter(PeerID peer_id, EnumVal* id, EnumVal*
goto error; goto error;
} }
c = new ChunkedIO::Chunk;
c->len = fmt.EndWrite(&c->data);
if ( ! SendToChild(MSG_LOG_CREATE_WRITER, peer, 0) ) if ( ! SendToChild(MSG_LOG_CREATE_WRITER, peer, 0) )
goto error; goto error;
c = new ChunkedIO::Chunk;
c->data = 0;
c->len = fmt.EndWrite(&c->data);
if ( ! SendToChild(c) ) if ( ! SendToChild(c) )
goto error; goto error;
return true; return true;
error: error:
if ( c )
{
delete c;
delete [] c->data;
}
FatalError(io->Error()); FatalError(io->Error());
return false; return false;
} }
@ -2592,6 +2599,8 @@ bool RemoteSerializer::SendLogWrite(Peer* peer, EnumVal* id, EnumVal* writer, st
peer->log_buffer_used += len; peer->log_buffer_used += len;
assert(peer->log_buffer_used <= LOG_BUFFER_SIZE); assert(peer->log_buffer_used <= LOG_BUFFER_SIZE);
delete [] data;
return true; return true;
error: error:
@ -2607,9 +2616,10 @@ bool RemoteSerializer::FlushLogBuffer(Peer* p)
if ( ! (p->log_buffer && p->log_buffer_used) ) if ( ! (p->log_buffer && p->log_buffer_used) )
return true; return true;
SendToChild(MSG_LOG_WRITE, p, p->log_buffer, p->log_buffer_used); char* data = new char[p->log_buffer_used];
memcpy(data, p->log_buffer, p->log_buffer_used);
SendToChild(MSG_LOG_WRITE, p, data, p->log_buffer_used);
p->log_buffer = new char[LOG_BUFFER_SIZE];
p->log_buffer_used = 0; p->log_buffer_used = 0;
return true; return true;
} }
@ -2826,6 +2836,11 @@ void RemoteSerializer::GotID(ID* id, Val* val)
(desc && *desc) ? desc : "not set"), (desc && *desc) ? desc : "not set"),
current_peer); current_peer);
#ifdef USE_PERFTOOLS
// May still be cached, but we don't care.
heap_checker->IgnoreObject(id);
#endif
Unref(id); Unref(id);
return; return;
} }
@ -2997,12 +3012,14 @@ bool RemoteSerializer::SendToChild(char type, Peer* peer, char* str, int len)
{ {
DEBUG_COMM(fmt("parent: (->child) %s (#%" PRI_SOURCE_ID ", %s)", msgToStr(type), peer ? peer->id : PEER_NONE, str)); DEBUG_COMM(fmt("parent: (->child) %s (#%" PRI_SOURCE_ID ", %s)", msgToStr(type), peer ? peer->id : PEER_NONE, str));
if ( child_pid && sendToIO(io, type, peer ? peer->id : PEER_NONE, str, len) )
return true;
delete [] str;
if ( ! child_pid ) if ( ! child_pid )
return false; return false;
if ( sendToIO(io, type, peer ? peer->id : PEER_NONE, str, len) )
return true;
if ( io->Eof() ) if ( io->Eof() )
ChildDied(); ChildDied();
@ -3014,9 +3031,6 @@ bool RemoteSerializer::SendToChild(char type, Peer* peer, int nargs, ...)
{ {
va_list ap; va_list ap;
if ( ! child_pid )
return false;
#ifdef DEBUG #ifdef DEBUG
va_start(ap, nargs); va_start(ap, nargs);
DEBUG_COMM(fmt("parent: (->child) %s (#%" PRI_SOURCE_ID ",%s)", DEBUG_COMM(fmt("parent: (->child) %s (#%" PRI_SOURCE_ID ",%s)",
@ -3024,12 +3038,18 @@ bool RemoteSerializer::SendToChild(char type, Peer* peer, int nargs, ...)
va_end(ap); va_end(ap);
#endif #endif
va_start(ap, nargs); if ( child_pid )
bool ret = sendToIO(io, type, peer ? peer->id : PEER_NONE, nargs, ap); {
va_end(ap); va_start(ap, nargs);
bool ret = sendToIO(io, type, peer ? peer->id : PEER_NONE, nargs, ap);
va_end(ap);
if ( ret ) if ( ret )
return true; return true;
}
if ( ! child_pid )
return false;
if ( io->Eof() ) if ( io->Eof() )
ChildDied(); ChildDied();
@ -3042,12 +3062,14 @@ bool RemoteSerializer::SendToChild(ChunkedIO::Chunk* c)
{ {
DEBUG_COMM(fmt("parent: (->child) chunk of size %d", c->len)); DEBUG_COMM(fmt("parent: (->child) chunk of size %d", c->len));
if ( child_pid && sendToIO(io, c) )
return true;
delete [] c->data;
if ( ! child_pid ) if ( ! child_pid )
return false; return false;
if ( sendToIO(io, c) )
return true;
if ( io->Eof() ) if ( io->Eof() )
ChildDied(); ChildDied();
@ -3066,6 +3088,15 @@ void RemoteSerializer::FatalError(const char* msg)
child_pid = 0; child_pid = 0;
using_communication = false; using_communication = false;
io->Clear(); io->Clear();
loop_over_list(peers, i)
{
// Make perftools happy.
Peer* p = peers[i];
delete [] p->log_buffer;
delete [] p->print_buffer;
p->log_buffer = p->print_buffer = 0;
}
} }
bool RemoteSerializer::IsActive() bool RemoteSerializer::IsActive()