00001
00012 #include "op_libiberty.h"
00013
00014 #include "opd_parse_proc.h"
00015 #include "opd_proc.h"
00016 #include "opd_mapping.h"
00017 #include "opd_image.h"
00018 #include "opd_printf.h"
00019
00020 #include "op_file.h"
00021 #include "op_fileio.h"
00022
00023 #include <dirent.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027
00042
00043 static int opd_add_ascii_map(struct opd_proc * proc, char const * line,
00044 char * const image_name)
00045 {
00046 unsigned long offset, start, end;
00047 struct opd_image * image;
00048 char const * cp = line;
00049
00050
00051 while (*cp && *cp != ' ')
00052 cp++;
00053
00054
00055 if (!*cp || (!*(++cp)) || (!*(++cp)) || (*(++cp) != 'x'))
00056 return 0;
00057
00058
00059 if (sscanf(line, "%lx-%lx", &start, &end) != 2)
00060 return 0;
00061
00062
00063 cp += 2;
00064
00065
00066 if (sscanf(cp, "%lx", &offset) != 1)
00067 return 0;
00068
00069 while (*cp && *cp != '/')
00070 cp++;
00071
00072 if (!*cp)
00073 return 0;
00074
00075 image = opd_get_image(cp, image_name, 0, proc->tid, proc->tgid);
00076 if (!image)
00077 return 0;
00078
00079 opd_add_mapping(proc, image, start, offset, end);
00080
00081 return 1;
00082 }
00083
00084
00092 static void opd_get_ascii_maps(struct opd_proc * proc)
00093 {
00094 FILE * fp;
00095 char mapsfile[20] = "/proc/";
00096 char * line;
00097 char exe_name[20];
00098 char * image_name;
00099 struct list_head * pos;
00100
00101 snprintf(mapsfile + 6, 6, "%hu", proc->tid);
00102
00103 strcpy(exe_name, mapsfile);
00104
00105 strcat(mapsfile, "/maps");
00106
00107 fp = op_try_open_file(mapsfile, "r");
00108 if (!fp)
00109 return;
00110
00111 strcat(exe_name, "/exe");
00112 image_name = xmalloc(PATH_MAX);
00113 if (!realpath(exe_name, image_name))
00114
00115 strcpy(image_name, exe_name);
00116
00117 verbprintf(vmisc, "image name %s for pid %u %u\n", image_name, proc->tid, proc->tgid);
00118
00119 while (1) {
00120 line = op_get_line(fp);
00121 if (!line)
00122 break;
00123
00124 opd_add_ascii_map(proc, line, image_name);
00125 free(line);
00126 }
00127
00128
00129
00130
00131
00132 list_for_each(pos, &proc->maps) {
00133 struct opd_map * map = list_entry(pos, struct opd_map, next);
00134 if (!strcmp(map->image->name, image_name)) {
00135 if (pos != proc->maps.next) {
00136 fprintf(stderr, "swap map for image %s from %s to %s\n", image_name, proc->name, map->image->name);
00137 free((char *)proc->name);
00138 proc->name = xstrdup(map->image->name);
00139 }
00140 break;
00141 }
00142 }
00143
00144 if (list_empty(&proc->maps)) {
00145
00146
00147
00148
00149
00150
00151
00152 struct opd_image * image = opd_get_image(image_name,
00153 image_name, 0, proc->tid, proc->tgid);
00154 if (image)
00155 opd_add_mapping(proc, image, 0, 0, 0);
00156 }
00157
00158 if (image_name)
00159 free(image_name);
00160
00161 op_close_file(fp);
00162 }
00163
00164
00165 static u32 read_tgid(u32 tid)
00166 {
00167 char status_file[30] = "/proc/";
00168 char * line;
00169 FILE * fp;
00170 u32 tgid;
00171
00172 snprintf(status_file + 6, 6, "%hu", tid);
00173
00174 strcat(status_file, "/status");
00175
00176 fp = op_try_open_file(status_file, "r");
00177 if (!fp)
00178 return 0;
00179
00180 while (1) {
00181 line = op_get_line(fp);
00182 if (!line)
00183 break;
00184
00185 if (sscanf(line, "Tgid: %u", &tgid) == 1) {
00186 free(line);
00187 op_close_file(fp);
00188 return tgid;
00189 }
00190 free(line);
00191 }
00192
00193 op_close_file(fp);
00194
00195 return 0;
00196 }
00197
00198
00199 void opd_get_ascii_procs(void)
00200 {
00201 DIR * dir;
00202 struct dirent * dirent;
00203 struct opd_proc * proc;
00204 u32 pid;
00205
00206 if (!(dir = opendir("/proc"))) {
00207 perror("oprofiled: /proc directory could not be opened. ");
00208 exit(EXIT_FAILURE);
00209 }
00210
00211 while ((dirent = readdir(dir))) {
00212 if (sscanf(dirent->d_name, "%u", &pid) == 1) {
00213 u32 tgid = read_tgid(pid);
00214 verbprintf(vmisc, "ASCII added %u %u\n", pid, tgid);
00215 proc = opd_get_proc(pid, tgid);
00216 if (!proc)
00217 proc = opd_new_proc(pid, tgid);
00218 opd_get_ascii_maps(proc);
00219 }
00220 }
00221
00222 closedir(dir);
00223 }