opd_mangling.c

Go to the documentation of this file.
00001 
00012 #include <sys/types.h>
00013  
00014 #include "opd_mangling.h"
00015 #include "opd_kernel.h"
00016 #include "opd_cookie.h"
00017 #include "opd_sfile.h"
00018 #include "opd_anon.h"
00019 #include "opd_printf.h"
00020 #include "opd_events.h"
00021 #include "oprofiled.h"
00022 
00023 #include "op_file.h"
00024 #include "op_sample_file.h"
00025 #include "op_config.h"
00026 #include "op_mangle.h"
00027 #include "op_events.h"
00028 #include "op_libiberty.h"
00029 
00030 #include <limits.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <errno.h>
00035 
00036 
00037 static char const * get_dep_name(struct sfile const * sf)
00038 {
00039     if (sf->anon)
00040         return find_cookie(sf->app_cookie);
00041 
00042     /* avoid to call find_cookie(), caller can recover using image_name */
00043     if (sf->cookie == sf->app_cookie)
00044         return NULL;
00045 
00046     if (!separate_kernel && !(separate_lib && !sf->kernel))
00047         return NULL;
00048 
00049     /* this will fail if e.g. kernel thread */
00050     if (sf->app_cookie == 0)
00051         return NULL;
00052 
00053     return find_cookie(sf->app_cookie);
00054 }
00055 
00056 
00057 static char * mangle_anon(struct anon_mapping const * anon)
00058 {
00059     char * name = xmalloc(PATH_MAX);
00060 
00061     snprintf(name, 1024, "%u.0x%llx.0x%llx", (unsigned int)anon->tgid,
00062            anon->start, anon->end);
00063 
00064     return name;
00065 }
00066 
00067 
00068 static char *
00069 mangle_filename(struct sfile * last, struct sfile const * sf, int counter, int cg)
00070 {
00071     char * mangled;
00072     struct mangle_values values;
00073     struct opd_event * event = find_counter_event(counter);
00074 
00075     values.flags = 0;
00076 
00077     if (sf->kernel) {
00078         values.image_name = sf->kernel->name;
00079         values.flags |= MANGLE_KERNEL;
00080     } else if (sf->anon) {
00081         values.flags |= MANGLE_ANON;
00082         values.image_name = mangle_anon(sf->anon);
00083         values.anon_name = sf->anon->name;
00084     } else {
00085         values.image_name = find_cookie(sf->cookie);
00086     }
00087 
00088     values.dep_name = get_dep_name(sf);
00089     if (!values.dep_name)
00090         values.dep_name = values.image_name;
00091  
00092     /* FIXME: log */
00093     if (!values.image_name || !values.dep_name)
00094         return NULL;
00095 
00096     if (separate_thread) {
00097         values.flags |= MANGLE_TGID | MANGLE_TID;
00098         values.tid = sf->tid;
00099         values.tgid = sf->tgid;
00100     }
00101  
00102     if (separate_cpu) {
00103         values.flags |= MANGLE_CPU;
00104         values.cpu = sf->cpu;
00105     }
00106 
00107     if (cg) {
00108         values.flags |= MANGLE_CALLGRAPH;
00109         if (last->kernel) {
00110             values.cg_image_name = last->kernel->name;
00111         } else if (last->anon) {
00112             values.flags |= MANGLE_CG_ANON;
00113             values.cg_image_name = mangle_anon(last->anon);
00114             values.anon_name = last->anon->name;
00115         } else {
00116             values.cg_image_name = find_cookie(last->cookie);
00117         }
00118 
00119         /* FIXME: log */
00120         if (!values.cg_image_name) {
00121             if (values.flags & MANGLE_ANON)
00122                 free((char *)values.image_name);
00123             return NULL;
00124         }
00125     }
00126 
00127     values.event_name = event->name;
00128     values.count = event->count;
00129     values.unit_mask = event->um;
00130 
00131     mangled = op_mangle_filename(&values);
00132 
00133     if (values.flags & MANGLE_ANON)
00134         free((char *)values.image_name);
00135     if (values.flags & MANGLE_CG_ANON)
00136         free((char *)values.cg_image_name);
00137     return mangled;
00138 }
00139 
00140 
00141 int opd_open_sample_file(odb_t *file, struct sfile *last,
00142                          struct sfile * sf, int counter, int cg)
00143 {
00144     char * mangled;
00145     char const * binary;
00146     int spu_profile = 0;
00147     vma_t last_start = 0;
00148     int err;
00149 
00150     mangled = mangle_filename(last, sf, counter, cg);
00151 
00152     if (!mangled)
00153         return EINVAL;
00154 
00155     verbprintf(vsfile, "Opening \"%s\"\n", mangled);
00156 
00157     create_path(mangled);
00158 
00159     /* locking sf will lock associated cg files too */
00160     sfile_get(sf);
00161     if (sf != last)
00162         sfile_get(last);
00163 
00164 retry:
00165     err = odb_open(file, mangled, ODB_RDWR, sizeof(struct opd_header));
00166 
00167     /* This can naturally happen when racing against opcontrol --reset. */
00168     if (err) {
00169         if (err == EMFILE) {
00170             if (sfile_lru_clear()) {
00171                 printf("LRU cleared but odb_open() fails for %s.\n", mangled);
00172                 abort();
00173             }
00174             goto retry;
00175         }
00176 
00177         fprintf(stderr, "oprofiled: open of %s failed: %s\n",
00178                 mangled, strerror(err));
00179         goto out;
00180     }
00181 
00182     if (!sf->kernel)
00183         binary = find_cookie(sf->cookie);
00184     else
00185         binary = sf->kernel->name;
00186 
00187     if (last && last->anon)
00188         last_start = last->anon->start;
00189 
00190     if (sf->embedded_offset != UNUSED_EMBEDDED_OFFSET)
00191         spu_profile = 1;
00192 
00193     fill_header(odb_get_data(file), counter,
00194             sf->anon ? sf->anon->start : 0, last_start,
00195             !!sf->kernel, last ? !!last->kernel : 0,
00196             spu_profile, sf->embedded_offset,
00197             binary ? op_get_mtime(binary) : 0);
00198 
00199 out:
00200     sfile_put(sf);
00201     if (sf != last)
00202         sfile_put(last);
00203     free(mangled);
00204     return err;
00205 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1