From 1d219b3a253f44d73aa68cd42238d6fa451bb80e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Axel=20D=C3=B6rfler?= <axeld@pinc-software.de>
Date: Mon, 15 Nov 2010 21:25:03 +0000
Subject: [PATCH] * Added AS_DUMP_ALLOCATOR command that dumps an applications
 memory allocator to   the syslog/serial output. * Added app_server_debug
 command that currently just sends this command to the   specified teams.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39441 a95241bf-73f2-0310-859d-f6bbb57e9c96
---
 headers/private/app/ServerProtocol.h       |  7 ++-
 src/servers/app/ClientMemoryAllocator.cpp  | 26 ++++++++++
 src/servers/app/ClientMemoryAllocator.h    |  2 +
 src/servers/app/Desktop.cpp                | 13 ++---
 src/servers/app/ServerApp.cpp              |  6 ++-
 src/tests/servers/app/Jamfile              |  8 +++-
 src/tests/servers/app/app_server_debug.cpp | 55 ++++++++++++++++++++++
 7 files changed, 107 insertions(+), 10 deletions(-)
 create mode 100644 src/tests/servers/app/app_server_debug.cpp

diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h
index d8c2b733f4..39b912c49f 100644
--- a/headers/private/app/ServerProtocol.h
+++ b/headers/private/app/ServerProtocol.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2009, Haiku.
+ * Copyright 2001-2010, Haiku.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -81,7 +81,7 @@ enum {
 
 	AS_BEGIN_RECT_TRACKING,
 	AS_END_RECT_TRACKING,
-	
+
 	AS_GET_CURSOR_POSITION,
 	AS_GET_CURSOR_BITMAP,
 
@@ -336,6 +336,9 @@ enum {
 	// desktop listener communications
 	AS_TALK_TO_DESKTOP_LISTENER,
 
+	// debugging helper
+	AS_DUMP_ALLOCATOR,
+
 	AS_LAST_CODE
 };
 
diff --git a/src/servers/app/ClientMemoryAllocator.cpp b/src/servers/app/ClientMemoryAllocator.cpp
index 3cd9ad6f49..594cfcf44f 100644
--- a/src/servers/app/ClientMemoryAllocator.cpp
+++ b/src/servers/app/ClientMemoryAllocator.cpp
@@ -211,6 +211,32 @@ ClientMemoryAllocator::Unlock()
 }
 
 
+void
+ClientMemoryAllocator::Dump()
+{
+	AutoReadLocker locker(fLock);
+
+	debug_printf("Application %ld, %s: chunks:\n", fApplication->ClientTeam(),
+		fApplication->Signature());
+
+	chunk_list::Iterator iterator = fChunks.GetIterator();
+	int32 i = 0;
+	while (struct chunk* chunk = iterator.Next()) {
+		debug_printf("  [%4ld] %p, area %ld, base %p, size %lu\n", i++, chunk,
+			chunk->area, chunk->base, chunk->size);
+	}
+
+	debug_printf("free blocks:\n");
+
+	block_list::Iterator blockIterator = fFreeBlocks.GetIterator();
+	i = 0;
+	while (struct block* block = blockIterator.Next()) {
+		debug_printf("  [%6ld] %p, chunk %p, base %p, size %lu\n", i++, block,
+			block->chunk, block->base, block->size);
+	}
+}
+
+
 struct block *
 ClientMemoryAllocator::_AllocateChunk(size_t size, bool& newArea)
 {
diff --git a/src/servers/app/ClientMemoryAllocator.h b/src/servers/app/ClientMemoryAllocator.h
index fb0c633133..726ecd7d65 100644
--- a/src/servers/app/ClientMemoryAllocator.h
+++ b/src/servers/app/ClientMemoryAllocator.h
@@ -51,6 +51,8 @@ public:
 			bool				Lock();
 			void				Unlock();
 
+			void				Dump();
+
 private:
 			struct block*		_AllocateChunk(size_t size, bool& newArea);
 
diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp
index 626dd694cf..059d5e27d7 100644
--- a/src/servers/app/Desktop.cpp
+++ b/src/servers/app/Desktop.cpp
@@ -2265,7 +2265,7 @@ Desktop::_PrepareQuit()
 
 
 void
-Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
+Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
 {
 	switch (code) {
 		case AS_CREATE_APP:
@@ -2285,7 +2285,7 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
 			port_id	clientLooperPort = -1;
 			port_id clientReplyPort = -1;
 			int32 htoken = B_NULL_TOKEN;
-			char *appSignature = NULL;
+			char* appSignature = NULL;
 
 			link.Read<port_id>(&clientReplyPort);
 			link.Read<port_id>(&clientLooperPort);
@@ -2294,7 +2294,7 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
 			if (link.ReadString(&appSignature) != B_OK)
 				break;
 
-			ServerApp *app = new ServerApp(this, clientReplyPort,
+			ServerApp* app = new ServerApp(this, clientReplyPort,
 				clientLooperPort, clientTeamID, htoken, appSignature);
 			if (app->InitCheck() == B_OK
 				&& app->Run()) {
@@ -2334,10 +2334,10 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
 			// Run through the list of apps and nuke the proper one
 
 			int32 count = fApplications.CountItems();
-			ServerApp *removeApp = NULL;
+			ServerApp* removeApp = NULL;
 
 			for (int32 i = 0; i < count; i++) {
-				ServerApp *app = fApplications.ItemAt(i);
+				ServerApp* app = fApplications.ItemAt(i);
 
 				if (app->Thread() == thread) {
 					fApplications.RemoveItemAt(i);
@@ -2387,6 +2387,7 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
 		}
 
 		case AS_APP_CRASHED:
+		case AS_DUMP_ALLOCATOR:
 		{
 			BAutolock locker(fApplicationsLock);
 
@@ -2398,7 +2399,7 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
 				ServerApp* app = fApplications.ItemAt(i);
 
 				if (app->ClientTeam() == team)
-					app->PostMessage(AS_APP_CRASHED);
+					app->PostMessage(code);
 			}
 			break;
 		}
diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp
index dfc4c2b152..0738517782 100644
--- a/src/servers/app/ServerApp.cpp
+++ b/src/servers/app/ServerApp.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2009, Haiku.
+ * Copyright 2001-2010, Haiku.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -545,6 +545,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
 			}
 			break;
 
+		case AS_DUMP_ALLOCATOR:
+			fMemoryAllocator.Dump();
+			break;
+
 		case AS_CREATE_WINDOW:
 		case AS_CREATE_OFFSCREEN_WINDOW:
 		{
diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile
index cadb857ca5..df8c05b7fe 100644
--- a/src/tests/servers/app/Jamfile
+++ b/src/tests/servers/app/Jamfile
@@ -1,12 +1,18 @@
 SubDir HAIKU_TOP src tests servers app ;
 
+UsePrivateHeaders app graphics input interface shared storage ;
+
+SimpleTest app_server_debug :
+	app_server_debug.cpp
+	: be
+;
+
 SetSubDirSupportedPlatforms libbe_test ;
 
 # No need to define any of those targets, when not building for libbe_test
 if $(TARGET_PLATFORM) = libbe_test {
 
 UseLibraryHeaders agg png zlib ;
-UsePrivateHeaders app graphics input interface shared storage ;
 UsePrivateHeaders [ FDirName graphics common ] ;
 
 # headers/build/private/kernel is needed for safemode.h and syscalls.h.
diff --git a/src/tests/servers/app/app_server_debug.cpp b/src/tests/servers/app/app_server_debug.cpp
new file mode 100644
index 0000000000..184e62adac
--- /dev/null
+++ b/src/tests/servers/app/app_server_debug.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010, Axel Dörfler, axeld@pinc-software.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <DesktopLink.h>
+#include <ServerProtocol.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+extern const char* __progname;
+
+
+status_t
+send_debug_message(team_id team, int32 code)
+{
+	BPrivate::DesktopLink link;
+
+	status_t status = link.InitCheck();
+	if (status != B_OK)
+		return status;
+
+	// prepare the message
+	status = link.StartMessage(code);
+	if (status != B_OK)
+		return status;
+
+	status = link.Attach(team);
+	if (status != B_OK)
+		return status;
+
+	// send it
+	return link.Flush();
+}
+
+
+int
+main(int argc, char** argv)
+{
+	if (argc == 1) {
+		fprintf(stderr, "usage: %s <team-id> [...]\n", __progname);
+		return 1;
+	}
+
+	for (int32 i = 1; i < argc; i++) {
+		team_id team = atoi(argv[i]);
+		if (team > 0)
+			send_debug_message(team, AS_DUMP_ALLOCATOR);
+	}
+
+	return 0;
+}