ret = (*jvmti)->GetLineNumberTable(jvmti, m, &nr_lines, &loc_tab); if (ret == JVMTI_ERROR_ABSENT_INFORMATION || ret == JVMTI_ERROR_NATIVE_METHOD) { /* No debug information for this method */ return ret;
} elseif (ret != JVMTI_ERROR_NONE) {
print_error(jvmti, "GetLineNumberTable", ret); return ret;
}
for (i = 0; i < nr_lines && loc_tab[i].start_location <= bci; i++) {
src_line = i;
}
if (src_line != -1) {
tab->pc = (unsignedlong)pc;
tab->line_number = loc_tab[src_line].line_number;
tab->discrim = 0; /* not yet used */
tab->methodID = m;
ret = JVMTI_ERROR_NONE;
} else {
ret = JVMTI_ERROR_ABSENT_INFORMATION;
}
staticvoid
copy_class_filename(constchar * class_sign, constchar * file_name, char * result, size_t max_length)
{ /* * Assume path name is class hierarchy, this is a common practice with Java programs
*/ if (*class_sign == 'L') {
size_t j, i = 0; char *p = strrchr(class_sign, '/'); if (p) { /* drop the 'L' prefix and copy up to the final '/' */ for (i = 0; i < (size_t)(p - class_sign); i++)
result[i] = class_sign[i+1];
} /* * append file name, we use loops and not string ops to avoid modifying * class_sign which is used later for the symbol name
*/ for (j = 0; i < (max_length - 1) && file_name && j < strlen(file_name); j++, i++)
result[i] = file_name[j];
ret = (*jvmti)->GetMethodDeclaringClass(jvmti, method,
&decl_class); if (ret != JVMTI_ERROR_NONE) {
print_error(jvmti, "GetMethodDeclaringClass", ret); return;
}
if (has_line_numbers && map && map_length) {
ret = get_line_numbers(jvmti, compile_info, &line_tab, &nr_lines); if (ret != JVMTI_ERROR_NONE) { if (ret != JVMTI_ERROR_NOT_FOUND) {
warnx("jvmti: cannot get line table for method");
}
nr_lines = 0;
} elseif (nr_lines > 0) {
line_file_names = malloc(sizeof(char*) * nr_lines); if (!line_file_names) {
warnx("jvmti: cannot allocate space for line table method names");
} else {
memset(line_file_names, 0, sizeof(char*) * nr_lines);
ret = fill_source_filenames(jvmti, nr_lines, line_tab, line_file_names); if (ret != JVMTI_ERROR_NONE) {
warnx("jvmti: fill_source_filenames failed");
} else {
output_debug_info = 1;
}
}
}
}
ret = (*jvmti)->GetClassSignature(jvmti, decl_class,
&class_sign, NULL); if (ret != JVMTI_ERROR_NONE) {
print_error(jvmti, "GetClassSignature", ret); goto error;
}
ret = (*jvmti)->GetMethodName(jvmti, method, &func_name,
&func_sign, NULL); if (ret != JVMTI_ERROR_NONE) {
print_error(jvmti, "GetMethodName", ret); goto error;
}
/* * write source line info record if we have it
*/ if (output_debug_info) if (jvmti_write_debug_info(jvmti_agent, addr, nr_lines, line_tab, (constchar * const *) line_file_names))
warnx("jvmti: write_debug_info() failed");
/* * Request a JVMTI interface version 1 environment
*/
ret = (*jvm)->GetEnv(jvm, (void *)&jvmti, JVMTI_VERSION_1); if (ret != JNI_OK) {
warnx("jvmti: jvmti version 1 not supported"); return -1;
}
/* * acquire method_load capability, we require it * request line numbers (optional)
*/
memset(&caps1, 0, sizeof(caps1));
caps1.can_generate_compiled_method_load_events = 1;
ret = (*jvmti)->AddCapabilities(jvmti, &caps1); if (ret != JVMTI_ERROR_NONE) {
print_error(jvmti, "AddCapabilities", ret); return -1;
}
ret = (*jvmti)->GetJLocationFormat(jvmti, &format); if (ret == JVMTI_ERROR_NONE && format == JVMTI_JLOCATION_JVMBCI) {
memset(&caps1, 0, sizeof(caps1));
caps1.can_get_line_numbers = 1;
caps1.can_get_source_file_name = 1;
ret = (*jvmti)->AddCapabilities(jvmti, &caps1); if (ret == JVMTI_ERROR_NONE)
has_line_numbers = 1;
} elseif (ret != JVMTI_ERROR_NONE)
print_error(jvmti, "GetJLocationFormat", ret);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.