unwind: refactor stacktrace_walk

* unwind.c (stacktrace_walk): Move stack frame printing code
to separate function print_stack_frame.
diff --git a/unwind.c b/unwind.c
index da256c9..c4a262c 100644
--- a/unwind.c
+++ b/unwind.c
@@ -283,6 +283,82 @@
 		tcp->mmap_cache);
 }
 
+static void
+get_symbol_name(unw_cursor_t *cursor, char **name,
+		size_t *size, unw_word_t *offset)
+{
+	for (;;) {
+		int rc = unw_get_proc_name(cursor, *name, *size, offset);
+		if (rc == 0)
+			break;
+		if (rc != -UNW_ENOMEM) {
+			**name = '\0';
+			*offset = 0;
+			break;
+		}
+		*size *= 2;
+		*name = realloc(*name, *size);
+		if (!*name)
+			die_out_of_memory();
+	}
+}
+
+static int
+print_stack_frame(struct tcb *tcp,
+		  call_action_fn call_action,
+		  error_action_fn error_action,
+		  void *data,
+		  unw_cursor_t *cursor,
+		  char **symbol_name,
+		  size_t *symbol_name_size)
+{
+	unw_word_t ip;
+	int lower = 0;
+	int upper = (int) tcp->mmap_cache_size - 1;
+
+	if (unw_get_reg(cursor, UNW_REG_IP, &ip) < 0) {
+		perror_msg("Can't walk the stack of process %d", tcp->pid);
+		return -1;
+	}
+
+	while (lower <= upper) {
+		struct mmap_cache_t *cur_mmap_cache;
+		int mid = (upper + lower) / 2;
+
+		cur_mmap_cache = &tcp->mmap_cache[mid];
+
+		if (ip >= cur_mmap_cache->start_addr &&
+		    ip < cur_mmap_cache->end_addr) {
+			unsigned long true_offset;
+			unw_word_t function_offset;
+
+			get_symbol_name(cursor, symbol_name, symbol_name_size,
+					&function_offset);
+			true_offset = ip - cur_mmap_cache->start_addr +
+				cur_mmap_cache->mmap_offset;
+			call_action(data,
+				    cur_mmap_cache->binary_filename,
+				    *symbol_name,
+				    function_offset,
+				    true_offset);
+			return 0;
+		}
+		else if (ip < cur_mmap_cache->start_addr)
+			upper = mid - 1;
+		else
+			lower = mid + 1;
+	}
+
+	/*
+	 * there is a bug in libunwind >= 1.0
+	 * after a set_tid_address syscall
+	 * unw_get_reg returns IP == 0
+	 */
+	if(ip)
+		error_action(data, "unexpected_backtracing_error", ip);
+	return -1;
+}
+
 /*
  * walking the stack
  */
@@ -292,17 +368,10 @@
 		error_action_fn error_action,
 		void *data)
 {
-	unw_word_t ip;
-	unw_cursor_t cursor;
-	unw_word_t function_offset;
-	int stack_depth = 0, ret_val;
-	/* these are used for the binary search through the mmap_chace */
-	int lower, upper, mid;
+	char *symbol_name;
 	size_t symbol_name_size = 40;
-	char * symbol_name;
-	struct mmap_cache_t* cur_mmap_cache;
-	unsigned long true_offset;
-	bool berror_expected = false;
+	unw_cursor_t cursor;
+	int stack_depth;
 
 	if (!tcp->mmap_cache)
 		error_msg_and_die("bug: mmap_cache is NULL");
@@ -316,90 +385,16 @@
 	if (unw_init_remote(&cursor, libunwind_as, tcp->libunwind_ui) < 0)
 		perror_msg_and_die("Can't initiate libunwind");
 
-	do {
-		/* looping on the stack frame */
-		if (unw_get_reg(&cursor, UNW_REG_IP, &ip) < 0) {
-			perror_msg("Can't walk the stack of process %d", tcp->pid);
+	for (stack_depth = 0; stack_depth < 256; ++stack_depth) {
+		if (print_stack_frame(tcp, call_action, error_action, data,
+				&cursor, &symbol_name, &symbol_name_size) < 0)
 			break;
-		}
-
-		lower = 0;
-		upper = (int) tcp->mmap_cache_size - 1;
-
-		while (lower <= upper) {
-			/* find the mmap_cache and print the stack frame */
-			mid = (upper + lower) / 2;
-			cur_mmap_cache = &tcp->mmap_cache[mid];
-
-			if (ip >= cur_mmap_cache->start_addr &&
-			    ip < cur_mmap_cache->end_addr) {
-				for (;;) {
-					symbol_name[0] = '\0';
-					ret_val = unw_get_proc_name(&cursor, symbol_name,
-						symbol_name_size, &function_offset);
-					if (ret_val != -UNW_ENOMEM)
-						break;
-					symbol_name_size *= 2;
-					symbol_name = realloc(symbol_name, symbol_name_size);
-					if (!symbol_name)
-						die_out_of_memory();
-				}
-
-				if (cur_mmap_cache->deleted)
-					berror_expected = true;
-
-				true_offset = ip - cur_mmap_cache->start_addr +
-					cur_mmap_cache->mmap_offset;
-				if (symbol_name[0]) {
-					call_action(data,
-						    cur_mmap_cache->binary_filename,
-						    symbol_name,
-						    function_offset,
-						    true_offset);
-				} else {
-					call_action(data,
-						    cur_mmap_cache->binary_filename,
-						    symbol_name,
-						    0,
-						    true_offset);
-				}
-				break; /* stack frame printed */
-			}
-			else if (mid == 0) {
-				/*
-				 * there is a bug in libunwind >= 1.0
-				 * after a set_tid_address syscall
-				 * unw_get_reg returns IP == 0
-				 */
-				if(ip)
-					error_action(data,
-						     "backtracing_error", 0);
-				goto ret;
-			}
-			else if (ip < cur_mmap_cache->start_addr)
-				upper = mid - 1;
-			else
-				lower = mid + 1;
-
-		}
-		if (lower > upper) {
-			error_action(data,
-				     berror_expected
-				     ?"expected_backtracing_error"
-				     :"unexpected_backtracing_error",
-				     ip);
-			goto ret;
-		}
-
-		ret_val = unw_step(&cursor);
-
-		if (++stack_depth > 255) {
-			error_action(data,
-				     "too many stack frames", 0);
+		if (unw_step(&cursor) <= 0)
 			break;
-		}
-	} while (ret_val > 0);
-ret:
+	}
+	if (stack_depth >= 256)
+		error_action(data, "too many stack frames", 0);
+
 	free(symbol_name);
 }