Added some paranoia debug code. We track only the buffer size ATM, and

check that is remains the sum of its data node used sizes.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25195 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-04-26 20:31:51 +00:00
parent 0efc7a1ed7
commit 0d5ea6e6cf
1 changed files with 114 additions and 1 deletions

View File

@ -24,6 +24,8 @@
#include <string.h> #include <string.h>
#include <sys/uio.h> #include <sys/uio.h>
#include "paranoia_config.h"
//#define TRACE_BUFFER //#define TRACE_BUFFER
#ifdef TRACE_BUFFER #ifdef TRACE_BUFFER
@ -36,6 +38,11 @@
// maximum implementation derived buffer size is 65536 // maximum implementation derived buffer size is 65536
//#define ENABLE_DEBUGGER_COMMANDS 1 //#define ENABLE_DEBUGGER_COMMANDS 1
#define PARANOID_BUFFER_CHECK NET_BUFFER_PARANOIA
#define ENABLE_PARANOIA_CHECK_COMPONENT NET_BUFFER_PARANOIA
#include <debug_paranoia.h>
struct data_node { struct data_node {
struct list_link link; struct list_link link;
@ -145,6 +152,34 @@ dump_net_buffer_stats(int argc, char** argv)
#endif // ENABLE_DEBUGGER_COMMANDS #endif // ENABLE_DEBUGGER_COMMANDS
#if PARANOID_BUFFER_CHECK
static void
check_buffer(net_buffer *_buffer)
{
net_buffer_private *buffer = (net_buffer_private*)_buffer;
// sum up the size of all nodes
size_t size = 0;
data_node *node = (data_node *)list_get_first_item(&buffer->buffers);
while (node != NULL) {
size += node->used;
node = (data_node *)list_get_next_item(&buffer->buffers, node);
}
if (size != buffer->size) {
panic("net_buffer %p size != sum of its data node sizes (%lu vs. %lu)",
buffer, buffer->size, size);
}
}
# define CHECK_BUFFER(buffer) check_buffer(buffer)
#else
# define CHECK_BUFFER(buffer) do {} while (false)
#endif // !PARANOID_BUFFER_CHECK
static inline data_header * static inline data_header *
allocate_data_header() allocate_data_header()
{ {
@ -430,6 +465,10 @@ create_buffer(size_t headerSpace)
buffer->type = -1; buffer->type = -1;
CHECK_BUFFER(buffer);
CREATE_PARANOIA_CHECK_SET(buffer, "net_buffer");
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
return buffer; return buffer;
} }
@ -441,6 +480,9 @@ free_buffer(net_buffer *_buffer)
TRACE(("%ld: free buffer %p\n", find_thread(NULL), buffer)); TRACE(("%ld: free buffer %p\n", find_thread(NULL), buffer));
CHECK_BUFFER(buffer);
DELETE_PARANOIA_CHECK_SET(buffer);
data_node *node; data_node *node;
while ((node = (data_node *)list_remove_head_item(&buffer->buffers)) != NULL) { while ((node = (data_node *)list_remove_head_item(&buffer->buffers)) != NULL) {
remove_data_node(node); remove_data_node(node);
@ -464,6 +506,8 @@ duplicate_buffer(net_buffer *_buffer)
{ {
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
ParanoiaChecker _(buffer);
TRACE(("%ld: duplicate_buffer(buffer %p)\n", find_thread(NULL), buffer)); TRACE(("%ld: duplicate_buffer(buffer %p)\n", find_thread(NULL), buffer));
net_buffer *duplicate = create_buffer(buffer->first_node.header_space); net_buffer *duplicate = create_buffer(buffer->first_node.header_space);
@ -478,6 +522,7 @@ duplicate_buffer(net_buffer *_buffer)
while (true) { while (true) {
if (append_data(duplicate, node->start, node->used) < B_OK) { if (append_data(duplicate, node->start, node->used) < B_OK) {
free_buffer(duplicate); free_buffer(duplicate);
CHECK_BUFFER(buffer);
return NULL; return NULL;
} }
@ -488,6 +533,10 @@ duplicate_buffer(net_buffer *_buffer)
copy_metadata(duplicate, buffer); copy_metadata(duplicate, buffer);
CHECK_BUFFER(buffer);
CHECK_BUFFER(duplicate);
RUN_PARANOIA_CHECKS(duplicate);
return duplicate; return duplicate;
} }
@ -505,6 +554,8 @@ clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
{ {
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
ParanoiaChecker _(buffer);
TRACE(("%ld: clone_buffer(buffer %p)\n", find_thread(NULL), buffer)); TRACE(("%ld: clone_buffer(buffer %p)\n", find_thread(NULL), buffer));
net_buffer_private *clone = allocate_net_buffer(); net_buffer_private *clone = allocate_net_buffer();
@ -566,6 +617,11 @@ clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
copy_metadata(clone, buffer); copy_metadata(clone, buffer);
CREATE_PARANOIA_CHECK_SET(clone, "net_buffer");
SET_PARANOIA_CHECK(clone, &clone->size, sizeof(clone->size));
CHECK_BUFFER(buffer);
CHECK_BUFFER(clone);
return clone; return clone;
} }
@ -582,15 +638,22 @@ split_buffer(net_buffer *from, uint32 offset)
if (buffer == NULL) if (buffer == NULL)
return NULL; return NULL;
ParanoiaChecker _(from);
ParanoiaChecker _2(buffer);
TRACE(("%ld: split_buffer(buffer %p -> %p, offset %ld)\n", TRACE(("%ld: split_buffer(buffer %p -> %p, offset %ld)\n",
find_thread(NULL), from, buffer, offset)); find_thread(NULL), from, buffer, offset));
if (trim_data(buffer, offset) == B_OK) { if (trim_data(buffer, offset) == B_OK) {
if (remove_header(from, offset) == B_OK) if (remove_header(from, offset) == B_OK) {
CHECK_BUFFER(from);
CHECK_BUFFER(buffer);
return buffer; return buffer;
}
} }
free_buffer(buffer); free_buffer(buffer);
CHECK_BUFFER(from);
return NULL; return NULL;
} }
@ -615,6 +678,10 @@ merge_buffer(net_buffer *_buffer, net_buffer *_with, bool after)
//dprintf("with:\n"); //dprintf("with:\n");
//dump_buffer(with); //dump_buffer(with);
ParanoiaChecker _(buffer);
CHECK_BUFFER(buffer);
CHECK_BUFFER(with);
// TODO: this is currently very simplistic, I really need to finish the // TODO: this is currently very simplistic, I really need to finish the
// harder part of this implementation (data_node management per header) // harder part of this implementation (data_node management per header)
@ -672,11 +739,15 @@ merge_buffer(net_buffer *_buffer, net_buffer *_with, bool after)
buffer->size += node->used; buffer->size += node->used;
} }
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
// the data has been merged completely at this point // the data has been merged completely at this point
free_buffer(with); free_buffer(with);
//dprintf(" merge result:\n"); //dprintf(" merge result:\n");
//dump_buffer(buffer); //dump_buffer(buffer);
CHECK_BUFFER(buffer);
return B_OK; return B_OK;
} }
@ -690,6 +761,8 @@ write_data(net_buffer *_buffer, size_t offset, const void *data, size_t size)
{ {
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
ParanoiaChecker _(buffer);
if (offset + size > buffer->size) if (offset + size > buffer->size)
return B_BAD_VALUE; return B_BAD_VALUE;
if (size == 0) if (size == 0)
@ -718,6 +791,8 @@ write_data(net_buffer *_buffer, size_t offset, const void *data, size_t size)
return B_BAD_VALUE; return B_BAD_VALUE;
} }
CHECK_BUFFER(buffer);
return B_OK; return B_OK;
} }
@ -727,6 +802,8 @@ read_data(net_buffer *_buffer, size_t offset, void *data, size_t size)
{ {
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
ParanoiaChecker _(buffer);
if (offset + size > buffer->size) if (offset + size > buffer->size)
return B_BAD_VALUE; return B_BAD_VALUE;
if (size == 0) if (size == 0)
@ -755,6 +832,8 @@ read_data(net_buffer *_buffer, size_t offset, void *data, size_t size)
return B_BAD_VALUE; return B_BAD_VALUE;
} }
CHECK_BUFFER(buffer);
return B_OK; return B_OK;
} }
@ -765,6 +844,8 @@ prepend_size(net_buffer *_buffer, size_t size, void **_contiguousBuffer)
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
data_node *node = (data_node *)list_get_first_item(&buffer->buffers); data_node *node = (data_node *)list_get_first_item(&buffer->buffers);
ParanoiaChecker _(buffer);
TRACE(("%ld: prepend_size(buffer %p, size %ld) [has %u]\n", TRACE(("%ld: prepend_size(buffer %p, size %ld) [has %u]\n",
find_thread(NULL), buffer, size, node->header_space)); find_thread(NULL), buffer, size, node->header_space));
//dump_buffer(buffer); //dump_buffer(buffer);
@ -833,6 +914,9 @@ prepend_size(net_buffer *_buffer, size_t size, void **_contiguousBuffer)
//dprintf(" prepend_size result:\n"); //dprintf(" prepend_size result:\n");
//dump_buffer(buffer); //dump_buffer(buffer);
CHECK_BUFFER(buffer);
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
return B_OK; return B_OK;
} }
@ -863,6 +947,8 @@ append_size(net_buffer *_buffer, size_t size, void **_contiguousBuffer)
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
data_node *node = (data_node *)list_get_last_item(&buffer->buffers); data_node *node = (data_node *)list_get_last_item(&buffer->buffers);
ParanoiaChecker _(buffer);
TRACE(("%ld: append_size(buffer %p, size %ld)\n", find_thread(NULL), TRACE(("%ld: append_size(buffer %p, size %ld)\n", find_thread(NULL),
buffer, size)); buffer, size));
//dump_buffer(buffer); //dump_buffer(buffer);
@ -885,6 +971,7 @@ append_size(net_buffer *_buffer, size_t size, void **_contiguousBuffer)
node->tail_space = 0; node->tail_space = 0;
node->used += previousTailSpace; node->used += previousTailSpace;
buffer->size += previousTailSpace; buffer->size += previousTailSpace;
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
// allocate all buffers // allocate all buffers
@ -911,6 +998,7 @@ append_size(net_buffer *_buffer, size_t size, void **_contiguousBuffer)
buffer->size += sizeUsed; buffer->size += sizeUsed;
sizeAdded += sizeUsed; sizeAdded += sizeUsed;
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
list_add_item(&buffer->buffers, node); list_add_item(&buffer->buffers, node);
@ -924,6 +1012,8 @@ append_size(net_buffer *_buffer, size_t size, void **_contiguousBuffer)
//dprintf(" append result 1:\n"); //dprintf(" append result 1:\n");
//dump_buffer(buffer); //dump_buffer(buffer);
CHECK_BUFFER(buffer);
return B_OK; return B_OK;
} }
@ -935,9 +1025,12 @@ append_size(net_buffer *_buffer, size_t size, void **_contiguousBuffer)
node->used += size; node->used += size;
buffer->size += size; buffer->size += size;
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
//dprintf(" append result 2:\n"); //dprintf(" append result 2:\n");
//dump_buffer(buffer); //dump_buffer(buffer);
CHECK_BUFFER(buffer);
return B_OK; return B_OK;
} }
@ -969,6 +1062,8 @@ remove_header(net_buffer *_buffer, size_t bytes)
{ {
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
ParanoiaChecker _(buffer);
if (bytes > buffer->size) if (bytes > buffer->size)
return B_BAD_VALUE; return B_BAD_VALUE;
@ -984,6 +1079,7 @@ remove_header(net_buffer *_buffer, size_t bytes)
if (node == NULL) { if (node == NULL) {
if (left == 0) if (left == 0)
break; break;
CHECK_BUFFER(buffer);
return B_ERROR; return B_ERROR;
} }
@ -1016,9 +1112,12 @@ remove_header(net_buffer *_buffer, size_t bytes)
} }
buffer->size -= bytes; buffer->size -= bytes;
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
//dprintf(" remove result:\n"); //dprintf(" remove result:\n");
//dump_buffer(buffer); //dump_buffer(buffer);
CHECK_BUFFER(buffer);
return B_OK; return B_OK;
} }
@ -1045,6 +1144,8 @@ trim_data(net_buffer *_buffer, size_t newSize)
find_thread(NULL), buffer, newSize, buffer->size)); find_thread(NULL), buffer, newSize, buffer->size));
//dump_buffer(buffer); //dump_buffer(buffer);
ParanoiaChecker _(buffer);
if (newSize > buffer->size) if (newSize > buffer->size)
return B_BAD_VALUE; return B_BAD_VALUE;
if (newSize == buffer->size) if (newSize == buffer->size)
@ -1072,9 +1173,12 @@ trim_data(net_buffer *_buffer, size_t newSize)
} }
buffer->size = newSize; buffer->size = newSize;
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
//dprintf(" trim result:\n"); //dprintf(" trim result:\n");
//dump_buffer(buffer); //dump_buffer(buffer);
CHECK_BUFFER(buffer);
return B_OK; return B_OK;
} }
@ -1095,6 +1199,9 @@ append_cloned_data(net_buffer *_buffer, net_buffer *_source, uint32 offset,
TRACE(("%ld: append_cloned_data(buffer %p, source %p, offset = %ld, " TRACE(("%ld: append_cloned_data(buffer %p, source %p, offset = %ld, "
"bytes = %ld)\n", find_thread(NULL), buffer, source, offset, bytes)); "bytes = %ld)\n", find_thread(NULL), buffer, source, offset, bytes));
ParanoiaChecker _(buffer);
ParanoiaChecker _2(source);
if (source->size < offset + bytes || source->size < offset) if (source->size < offset + bytes || source->size < offset)
return B_BAD_VALUE; return B_BAD_VALUE;
@ -1141,6 +1248,10 @@ append_cloned_data(net_buffer *_buffer, net_buffer *_source, uint32 offset,
//dprintf(" append cloned result:\n"); //dprintf(" append cloned result:\n");
//dump_buffer(buffer); //dump_buffer(buffer);
CHECK_BUFFER(source);
CHECK_BUFFER(buffer);
SET_PARANOIA_CHECK(buffer, &buffer->size, sizeof(buffer->size));
return B_OK; return B_OK;
} }
@ -1313,6 +1424,8 @@ direct_access(net_buffer *_buffer, uint32 offset, size_t size,
{ {
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
ParanoiaChecker _(buffer);
//TRACE(("direct_access(buffer %p, offset %ld, size %ld)\n", buffer, offset, size)); //TRACE(("direct_access(buffer %p, offset %ld, size %ld)\n", buffer, offset, size));
if (offset + size > buffer->size) if (offset + size > buffer->size)