Index: libfdproto/sessions.c
===================================================================
--- libfdproto/sessions.c	(revision 1027)
+++ libfdproto/sessions.c	(revision 1085)
@@ -70,4 +70,5 @@
 	int		  id;	/* A unique integer to identify this handler */
 	void 		(*cleanup)(session_state *, os0_t, void *); /* The cleanup function to be called for cleaning a state */
+	session_state_dump *state_dump; /* dumper function */
 	void             *opaque; /* a value that is passed as is to the cleanup callback */
 };
@@ -273,5 +274,5 @@
 
 /* Create a new handler */
-int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state *, os0_t, void *), void * opaque )
+int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state *, os0_t, void *), session_state_dump dumper, void * opaque )
 {
 	struct session_handler *new;
@@ -290,4 +291,5 @@
 	new->eyec = SH_EYEC;
 	new->cleanup = cleanup;
+	new->state_dump = dumper;
 	new->opaque = opaque;
 	
@@ -873,47 +875,61 @@
 
 /* Dump functions */
-void fd_sess_dump(int level, struct session * session)
-{
-	struct fd_list * li;
-	char buf[30];
-	struct tm tm;
-	
-	if (!TRACE_BOOL(level))
-		return;
-	
-	fd_log_debug("\t  %*s -- Session @%p --", level, "", session);
+DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump, struct session * session, int with_states)
+{
+	size_t o = 0;
+	if (!offset)
+		offset = &o;
+	
+	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{session}(@%p): ", session), return NULL);
+	
 	if (!VALIDATE_SI(session)) {
-		fd_log_debug("\t  %*s  Invalid session object", level, "");
+		CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL);
 	} else {
-		
-		fd_log_debug("\t  %*s  sid '%s'(%zd), hash %x, msg %d, destroyed %d", level, "", session->sid, session->sidlen, session->hash, session->msg_cnt, session->is_destroyed);
-
-		strftime(buf, sizeof(buf), "%D,%T", localtime_r( &session->timeout.tv_sec , &tm ));
-		fd_log_debug("\t  %*s  timeout %s.%09ld", level, "", buf, session->timeout.tv_nsec);
-
-		CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ );
-		pthread_cleanup_push( fd_cleanup_mutex, &session->stlock );
-		for (li = session->states.next; li != &session->states; li = li->next) {
-			struct state * st = (struct state *)(li->o);
-			fd_log_debug("\t  %*s    handler %d registered data %p", level, "", st->hdl->id, st->state);
+		char timebuf[30];
+		struct tm tm;
+
+		strftime(timebuf, sizeof(timebuf), "%D,%T", localtime_r( &session->timeout.tv_sec , &tm ));
+		CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%zd) h:%x m:%d d:%d to:%s.%06ld\n",
+							session->sid, session->sidlen, session->hash, session->msg_cnt, session->is_destroyed,
+							timebuf, session->timeout.tv_nsec/1000), 
+				 return NULL);
+		
+		if (with_states) {
+			struct fd_list * li;
+			CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ );
+			pthread_cleanup_push( fd_cleanup_mutex, &session->stlock );
+			
+			for (li = session->states.next; li != &session->states; li = li->next) {
+				struct state * st = (struct state *)(li->o);
+				CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "  {state i:%d}(@%p): \n", st->hdl->id, st), return NULL);
+				if (st->hdl->state_dump) {
+					CHECK_MALLOC_DO( (*st->hdl->state_dump)( FD_DUMP_STD_PARAMS, st->state), 
+							fd_dump_extend( FD_DUMP_STD_PARAMS, "[dumper error]\n"));
+				} else {
+					CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<%p>\n", st->state), return NULL);
+				}
+			}
+			
+			pthread_cleanup_pop(0);
+			CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ );
 		}
-		pthread_cleanup_pop(0);
-		CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ );
-	}
-	fd_log_debug("\t  %*s -- end of session @%p --", level, "", session);
-}
-
-void fd_sess_dump_hdl(int level, struct session_handler * handler)
-{
-	if (!TRACE_BOOL(level))
-		return;
-	
-	fd_log_debug("\t  %*s -- Handler @%p --", level, "", handler);
+	}
+	return *buf;
+}
+
+DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump_hdl, struct session_handler * handler)
+{
+	size_t o = 0;
+	if (!offset)
+		offset = &o;
+	
+	CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{sesshdl}(@%p): ", handler), return NULL);
+	
 	if (!VALIDATE_SH(handler)) {
-		fd_log_debug("\t  %*s  Invalid session handler object", level, "");
+		CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL);
 	} else {
-		fd_log_debug("\t  %*s  id %d, cleanup %p, opaque %p", level, "", handler->id, handler->cleanup, handler->opaque);
-	}
-	fd_log_debug("\t  %*s -- end of handler @%p --", level, "", handler);
+		CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "i:%d cl:%p d:%p o:%p\n", handler->id, handler->cleanup, handler->state_dump, handler->opaque), return NULL);
+	}
+	return *buf;
 }	
 
