struct btp_distances * btp_threads_compare(struct btp_thread **threads, int m, int n, btp_dist_thread_type dist_func) { struct btp_distances *distances; struct btp_thread *thread1, *thread2; int i, j, ok, all; distances = btp_distances_new(m, n); for (i = 0; i < m; i++) for (j = i + 1; j < n; j++) { ok = all = 0; btp_thread_quality_counts(threads[i], &ok, &all); btp_thread_quality_counts(threads[j], &ok, &all); if (ok == all) { thread1 = threads[i]; thread2 = threads[j]; } else { /* There are some unknown function names, try to pair them, but * the threads need to be copied first. */ thread1 = btp_thread_dup(threads[i], false); thread2 = btp_thread_dup(threads[j], false); btp_normalize_paired_unknown_function_names(thread1, thread2); } distances->distances[get_distance_position(distances, i, j)] = dist_func(thread1, thread2); if (ok != all) { btp_thread_free(thread1); btp_thread_free(thread2); } } return distances; }
void btp_backtrace_remove_threads_except_one(struct btp_backtrace *backtrace, struct btp_thread *thread) { while (backtrace->threads) { struct btp_thread *delete_thread = backtrace->threads; backtrace->threads = delete_thread->next; if (delete_thread != thread) btp_thread_free(delete_thread); } thread->next = NULL; backtrace->threads = thread; }
struct btp_thread * btp_thread_parse(char **input, struct btp_location *location) { char *local_input = *input; /* Read the Thread keyword, which is mandatory. */ int chars = btp_skip_string(&local_input, "Thread"); location->column += chars; if (0 == chars) { location->message = "\"Thread\" header expected"; return NULL; } /* Skip spaces, at least one space is mandatory. */ int spaces = btp_skip_char_sequence(&local_input, ' '); location->column += spaces; if (0 == spaces) { location->message = "Space expected after the \"Thread\" keyword."; return NULL; } /* Read thread number. */ struct btp_thread *imthread = btp_thread_new(); int digits = btp_parse_unsigned_integer(&local_input, &imthread->number); location->column += digits; if (0 == digits) { location->message = "Thread number expected."; btp_thread_free(imthread); return NULL; } /* Skip spaces after the thread number and before parentheses. */ spaces = btp_skip_char_sequence(&local_input, ' '); location->column += spaces; if (0 == spaces) { location->message = "Space expected after the thread number."; btp_thread_free(imthread); return NULL; } /* Read the LWP section in parentheses, optional. */ location->column += btp_thread_skip_lwp(&local_input); /* Read the Thread keyword in parentheses, optional. */ chars = btp_skip_string(&local_input, "(Thread "); location->column += chars; if (0 != chars) { /* Read the thread identification number. It can be either in * decimal or hexadecimal form. * Examples: * "Thread 10 (Thread 2476):" * "Thread 8 (Thread 0xb07fdb70 (LWP 6357)):" */ digits = btp_skip_hexadecimal_number(&local_input); if (0 == digits) digits = btp_skip_unsigned_integer(&local_input); location->column += digits; if (0 == digits) { location->message = "The thread identification number expected."; btp_thread_free(imthread); return NULL; } /* Handle the optional " (LWP [0-9]+)" section. */ location->column += btp_skip_char_sequence(&local_input, ' '); location->column += btp_thread_skip_lwp(&local_input); /* Read the end of the parenthesis. */ if (!btp_skip_char(&local_input, ')')) { location->message = "Closing parenthesis for Thread expected."; btp_thread_free(imthread); return NULL; } } /* Read the end of the header line. */ chars = btp_skip_string(&local_input, ":\n"); if (0 == chars) { location->message = "Expected a colon followed by a newline ':\\n'."; btp_thread_free(imthread); return NULL; } /* Add the newline from the last btp_skip_string. */ btp_location_add(location, 2, 0); /* Read the frames. */ struct btp_frame *frame, *prevframe = NULL; struct btp_location frame_location; btp_location_init(&frame_location); while ((frame = btp_frame_parse(&local_input, &frame_location))) { if (prevframe) { btp_frame_add_sibling(prevframe, frame); prevframe = frame; } else imthread->frames = prevframe = frame; btp_location_add(location, frame_location.line, frame_location.column); } if (!imthread->frames) { location->message = frame_location.message; btp_thread_free(imthread); return NULL; } *input = local_input; return imthread; }