From: Philippe E. <ph...@us...> - 2007-12-02 17:01:16
|
Update of /cvsroot/oprofile/oprofile/opjitconv In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv25664/opjitconv Modified Files: Tag: JIT_SUPPORT opjitconv.c opjitconv.h parse_dump.c Log Message: dump the jit process name into the header of the dump file. Index: opjitconv.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/opjitconv/Attic/opjitconv.c,v retrieving revision 1.1.2.13 retrieving revision 1.1.2.14 diff -u -p -d -r1.1.2.13 -r1.1.2.14 --- opjitconv.c 27 Nov 2007 11:49:53 -0000 1.1.2.13 +++ opjitconv.c 2 Dec 2007 17:01:13 -0000 1.1.2.14 @@ -80,6 +80,8 @@ int max_entry_count; struct jitentry ** entries_symbols_ascending; /* array pointing to all jit entries sorted by address */ struct jitentry ** entries_address_ascending; +/* The application name */ +char const * dump_exe_filename; /* debug flag, print some information */ int debug; @@ -110,12 +112,46 @@ static void free_jit_debug_line(void) } +static int check_elf_file(char const * name, + struct op_jitdump_info const dmp_info) +{ + int jofd; + struct stat jo_file_stat; + time_t dumpfile_modtime; + + // Check if ELF file exists already + jofd = open(name, O_RDONLY); + if (jofd < 0) + return OP_JIT_CONV_OK; + if (fstat(jofd, &jo_file_stat) < 0) { + perror("opjitconv:fstat on .jo file"); + return OP_JIT_CONV_FAIL; + } + if (dmp_info.dmp_file_stat.st_mtime > + dmp_info.dmp_file_stat.st_ctime) + dumpfile_modtime = dmp_info.dmp_file_stat.st_mtime; + else + dumpfile_modtime = dmp_info.dmp_file_stat.st_ctime; + + /* ELF file already exists, so if dumpfile has not been + * modified since the ELF file's mod time, we don't + * need to do ELF creation again. + */ + if (!(jo_file_stat.st_ctime < dumpfile_modtime || + jo_file_stat.st_mtime < dumpfile_modtime)) { + return OP_JIT_CONV_ALREADY_DONE; + } + return OP_JIT_CONV_OK; +} + static int op_jit_convert(struct op_jitdump_info file_info, - char const * elffile, unsigned long long start_time, - unsigned long long end_time) + char const * session_dir, char const * proc_id, + unsigned long long start_time, unsigned long long end_time) { void const * jitdump = file_info.dmp_file; int rc = OP_JIT_CONV_OK; + char * elf_file = NULL; + size_t sz; entry_count = 0; max_entry_count = 0; @@ -129,6 +165,18 @@ static int op_jit_convert(struct op_jitd end_time)) == OP_JIT_CONV_FAIL) goto out; + sz = strlen(session_dir) + strlen("/samples/current/{root}") + + strlen(dump_exe_filename) + strlen("/{dep}/{anon:anon}/") + + strlen(proc_id) + 4; + elf_file = xmalloc(sz); + snprintf(elf_file, sz, "%s%s%s%s%s.jo", session_dir, + "/samples/current/{root}", dump_exe_filename, + "/{dep}/{anon:anon}/", proc_id); + verbprintf(debug, "converting to %s\n", elf_file); + + if ((rc = check_elf_file(elf_file, file_info)) != OP_JIT_CONV_OK) + goto out; + create_arrays(); if ((rc = resolve_overlaps(start_time)) == OP_JIT_CONV_FAIL) goto out; @@ -137,7 +185,7 @@ static int op_jit_convert(struct op_jitd if (!entry_count) return OP_JIT_CONV_NO_JIT_RECS_IN_DUMPFILE; - if ((cur_bfd = open_elf(elffile)) == NULL) { + if ((cur_bfd = open_elf(elf_file)) == NULL) { rc = OP_JIT_CONV_FAIL; goto out; } @@ -167,10 +215,9 @@ static int op_jit_convert(struct op_jitd /* * Front-end processing from this point to end of the source. * From main(), the general flow is as follows: - * 1. Find all anonymous samples directories * 2. Find all JIT dump files * 3. For each JIT dump file: - * 3.1 Find matching anon samples dir (from list retrieved in step 1) + * 3.1 Find matching anon samples dir from the jit dump header * 3.2 mmap the JIT dump file * 3.3 Call op_jit_convert to create ELF file if necessary */ @@ -186,6 +233,7 @@ static void get_pathname(char const * pa list_add(&pn->neighbor, names); } + static void delete_pathname(struct pathname * pname) { free(pname->name); @@ -194,17 +242,6 @@ static void delete_pathname(struct pathn } -static void delete_path_names_list(struct list_head * list) -{ - struct list_head * pos1, * pos2; - list_for_each_safe(pos1, pos2, list) { - struct pathname * pname = list_entry(pos1, struct pathname, - neighbor); - delete_pathname(pname); - } -} - - static int mmap_jitdump(char const * dumpfile, struct op_jitdump_info * file_info) { @@ -235,41 +272,16 @@ out: return rc; } -static char const * find_anon_dir_match(struct list_head * anon_dirs, - char const * proc_id) -{ - struct list_head * pos; - char match_filter [10]; - snprintf(match_filter, 10, "*/%s.*", proc_id); - list_for_each(pos, anon_dirs) { - struct pathname * anon_dir = - list_entry(pos, struct pathname, neighbor); - if (!fnmatch(match_filter, anon_dir->name, 0)) - return anon_dir->name; - } - return NULL; -} -/* Look for an anonymous samples directory that matches the process ID - * given by the passed JIT dmp_pathname. If none is found, it's an error - * since by agreement, all JIT dump files should be removed every time - * the user does --reset. If we do find the matching samples directory, - * we create an ELF file (<proc_id>.jo) and place it in that directory. - */ static int process_jit_dumpfile(char const * dmp_pathname, - struct list_head * anon_sample_dirs, + char const * session_dir, unsigned long long start_time, unsigned long long end_time) { - int result_dir_length, proc_id_length; + int proc_id_length; int rc = OP_JIT_CONV_OK; - int jofd; - struct stat jo_file_stat; - time_t dumpfile_modtime; struct op_jitdump_info dmp_info; - char * elf_file = NULL; char * proc_id = NULL; - char const * anon_dir; char const * dumpfilename = rindex(dmp_pathname, '/'); verbprintf(debug, "Processing dumpfile %s\n", dmp_pathname); if (dumpfilename) { @@ -290,67 +302,14 @@ chk_proc_id: rc = OP_JIT_CONV_FAIL; goto out; } - if (!(anon_dir = find_anon_dir_match(anon_sample_dirs, proc_id))) { - printf("Possible error: No matching anon samples for %s\n", - dmp_pathname); - rc = OP_JIT_CONV_NO_MATCHING_ANON_SAMPLES; - goto free_res1; - } if ((rc = mmap_jitdump(dmp_pathname, &dmp_info)) == OP_JIT_CONV_OK) { - char * anon_path_seg = rindex(anon_dir, '/'); - if (!anon_path_seg) { - printf("opjitconv: Bad path for anon sample: %s\n", - anon_dir); - rc = OP_JIT_CONV_FAIL; - goto free_res2; - } - result_dir_length = ++anon_path_seg - anon_dir; - elf_file = xmalloc(result_dir_length + - strlen(proc_id) + strlen(".jo") + 1); - strncpy(elf_file, anon_dir, result_dir_length); - elf_file[result_dir_length] = '\0'; - strcat(elf_file, proc_id); - strcat(elf_file, ".jo"); - - // Check if ELF file exists already - jofd = open(elf_file, O_RDONLY); - if (jofd < 0) - goto create_elf; - rc = fstat(jofd, &jo_file_stat); - if (rc < 0) { - perror("opjitconv:fstat on .jo file"); - rc = OP_JIT_CONV_FAIL; - goto free_res3; - } - if (dmp_info.dmp_file_stat.st_mtime > - dmp_info.dmp_file_stat.st_ctime) - dumpfile_modtime = dmp_info.dmp_file_stat.st_mtime; - else - dumpfile_modtime = dmp_info.dmp_file_stat.st_ctime; - - /* ELF file already exists, so if dumpfile has not been - * modified since the ELF file's mod time, we don't - * need to do ELF creation again. - */ - if (!(jo_file_stat.st_ctime < dumpfile_modtime || - jo_file_stat.st_mtime < dumpfile_modtime)) { - rc = OP_JIT_CONV_ALREADY_DONE; - goto free_res3; - } - - create_elf: - verbprintf(debug, "Converting %s to %s\n", dmp_pathname, - elf_file); - rc = op_jit_convert(dmp_info, elf_file, start_time, end_time); - free_res3: - free(elf_file); - free_res2: + rc = op_jit_convert(dmp_info, session_dir, proc_id, + start_time, end_time); munmap(dmp_info.dmp_file, dmp_info.dmp_file_stat.st_size); } - free_res1: free(proc_id); - out: +out: return rc; } @@ -362,26 +321,12 @@ static int op_process_jit_dumpfiles(char char jitdumpfile[PATH_MAX + 1]; char const * jitdump_dir = "/var/lib/oprofile/jitdump/"; LIST_HEAD(jd_fnames); - char const * anon_dir_filter = "*/{dep}/{anon:anon}/[0-9]*.*"; - LIST_HEAD(anon_dnames); - char const * samples_subdir = "/samples/current"; - int samples_dir_len = strlen(session_dir) + strlen(samples_subdir); - char samples_dir[samples_dir_len + 1]; if ((rc = get_matching_pathnames(&jd_fnames, get_pathname, jitdump_dir, "*.dump", NO_RECURSION)) < 0 || list_empty(&jd_fnames)) goto out; - sprintf(samples_dir, "%s%s", session_dir, samples_subdir); - if (get_matching_pathnames(&anon_dnames, get_pathname, - samples_dir, anon_dir_filter, - MATCH_DIR_ONLY_RECURSION) < 0 - || list_empty(&anon_dnames)) { - rc = OP_JIT_CONV_NO_ANON_SAMPLES; - goto out; - } - /* get_matching_pathnames returns only filename segment when * NO_RECURSION is passed, so below, we add back the JIT * dump directory path to the name. @@ -391,7 +336,7 @@ static int op_process_jit_dumpfiles(char list_entry(pos1, struct pathname, neighbor); strncpy(jitdumpfile, jitdump_dir, PATH_MAX); strncat(jitdumpfile, dmpfile->name, PATH_MAX); - rc = process_jit_dumpfile(jitdumpfile, &anon_dnames, + rc = process_jit_dumpfile(jitdumpfile, session_dir, start_time, end_time); if (rc == OP_JIT_CONV_FAIL) { verbprintf(debug, "JIT convert error %d\n", rc); @@ -399,7 +344,6 @@ static int op_process_jit_dumpfiles(char } delete_pathname(dmpfile); } - delete_path_names_list(&anon_dnames); out: return rc; } Index: opjitconv.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/opjitconv/Attic/opjitconv.h,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -p -d -r1.1.2.4 -r1.1.2.5 --- opjitconv.h 29 Nov 2007 17:49:15 -0000 1.1.2.4 +++ opjitconv.h 2 Dec 2007 17:01:13 -0000 1.1.2.5 @@ -107,6 +107,8 @@ extern struct jitentry ** entries_addres extern asymbol ** syms; /* the bfd handle of the ELF file we write */ extern bfd * cur_bfd; +/* The application name */ +extern char const * dump_exe_filename; /* debug flag, print some information */ extern int debug; Index: parse_dump.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/opjitconv/Attic/parse_dump.c,v retrieving revision 1.1.2.7 retrieving revision 1.1.2.8 diff -u -p -d -r1.1.2.7 -r1.1.2.8 --- parse_dump.c 29 Nov 2007 17:49:15 -0000 1.1.2.7 +++ parse_dump.c 2 Dec 2007 17:01:13 -0000 1.1.2.8 @@ -200,10 +200,13 @@ static int parse_header(char const ** pt dump_bfd_arch = header->bfd_arch; dump_bfd_mach = header->bfd_mach; dump_bfd_target_name = header->bfd_target; + dump_exe_filename = dump_bfd_target_name + + strlen(dump_bfd_target_name) + 1; include_code = header->dump_code; verbprintf(debug, "header: bfd-arch=%i, bfd-mach=%i, dump_code=%i" - " bfd_target_name=%s\n", dump_bfd_arch, dump_bfd_mach, - include_code, dump_bfd_target_name); + " bfd_target_name=%s dump_exe_filename=%s\n", + dump_bfd_arch, dump_bfd_mach, include_code, + dump_bfd_target_name, dump_exe_filename); *ptr = *ptr + header->totalsize; out: return rc; |