SourceForge has been redesigned. Learn more.
Close

Diff of /dae/opd_proc.c [de0c3c] .. [fb7fe6]  Maximize  Restore

Switch to unified view

a/dae/opd_proc.c b/dae/opd_proc.c
1
/* $Id: opd_proc.c,v 1.113 2002/05/02 02:19:08 movement Exp $ */
1
/* $Id: opd_proc.c,v 1.114 2002/05/06 18:00:29 movement Exp $ */
2
/* COPYRIGHT (C) 2000 THE VICTORIA UNIVERSITY OF MANCHESTER and John Levon
2
/* COPYRIGHT (C) 2000 THE VICTORIA UNIVERSITY OF MANCHESTER and John Levon
3
 * This program is free software; you can redistribute it and/or modify it
3
 * This program is free software; you can redistribute it and/or modify it
4
 * under the terms of the GNU General Public License as published by the Free
4
 * under the terms of the GNU General Public License as published by the Free
5
 * Software Foundation; either version 2 of the License, or (at your option)
5
 * Software Foundation; either version 2 of the License, or (at your option)
6
 * any later version.
6
 * any later version.
...
...
15
 * Place - Suite 330, Boston, MA 02111-1307, USA.
15
 * Place - Suite 330, Boston, MA 02111-1307, USA.
16
 */
16
 */
17
17
18
#include "opd_proc.h"
18
#include "opd_proc.h"
19
19
20
#include "op_get_time.h"
21
#include "op_file.h"
22
#include "op_fileio.h"
23
#include "op_mangle.h"
24
#include "op_sample_file.h"
25
 
20
/* per-process */
26
/* per-process */
21
#define OPD_DEFAULT_MAPS 16
27
#define OPD_DEFAULT_MAPS 16
22
#define OPD_MAP_INC 8
28
#define OPD_MAP_INC 8
23
29
30
/* here to avoid warning */
31
extern op_cpu cpu_type;
32
 
24
/* hash of process lists */
33
/* hash of process lists */
25
static struct opd_proc *opd_procs[OPD_MAX_PROC_HASH];
34
static struct opd_proc *opd_procs[OPD_MAX_PROC_HASH];
26
35
27
/* hash map device mmap */
36
/* hash map device mmap */
28
struct op_hash_index *hashmap;
37
struct op_hash_index *hashmap;
...
...
58
            ++j;
67
            ++j;
59
            proc = proc->next;
68
            proc = proc->next;
60
        }
69
        }
61
    }
70
    }
62
 
71
 
63
    printf("%s\n", opd_get_time());
72
    printf("%s\n", op_get_time());
64
    printf("Nr. proc struct: %d\n", j);
73
    printf("Nr. proc struct: %d\n", j);
65
    printf("Nr. image struct: %d\n", nr_images);
74
    printf("Nr. image struct: %d\n", nr_images);
66
    printf("Nr. kernel samples: %lu\n", opd_stats[OPD_KERNEL]);
75
    printf("Nr. kernel samples: %lu\n", opd_stats[OPD_KERNEL]);
67
    printf("Nr. modules samples: %lu\n", opd_stats[OPD_MODULE]);
76
    printf("Nr. modules samples: %lu\n", opd_stats[OPD_MODULE]);
68
    printf("Nr. modules samples lost: %lu\n", 
77
    printf("Nr. modules samples lost: %lu\n", 
...
...
198
    uint i;
207
    uint i;
199
    char *mangled;
208
    char *mangled;
200
    uint len;
209
    uint len;
201
    const char * app_name = separate_samples ? image->app_name : NULL;
210
    const char * app_name = separate_samples ? image->app_name : NULL;
202
211
203
    mangled = opd_mangle_filename(image->name, app_name);
212
    mangled = op_mangle_filename(image->name, app_name);
204
213
205
    len = strlen(mangled);
214
    len = strlen(mangled);
206
 
215
 
207
    for (i = 0 ; i < op_nr_counters ; ++i) {
216
    for (i = 0 ; i < op_nr_counters ; ++i) {
208
        sprintf(mangled + len, "#%d", i);
217
        sprintf(mangled + len, "#%d", i);
...
...
264
    for (i = 0 ; i < op_nr_counters ; ++i) {
273
    for (i = 0 ; i < op_nr_counters ; ++i) {
265
        memset(&image->sample_files[i], '\0',
274
        memset(&image->sample_files[i], '\0',
266
               sizeof(struct opd_sample_file));
275
               sizeof(struct opd_sample_file));
267
    }
276
    }
268
277
269
    image->mtime = opd_get_mtime(image->name);
278
    image->mtime = op_get_mtime(image->name);
270
 
279
 
271
    opd_handle_old_sample_files(image);
280
    opd_handle_old_sample_files(image);
272
281
273
    /* samples files are lazily openeded */
282
    /* samples files are lazily openeded */
274
}
283
}
...
...
313
    const char * app_name;
322
    const char * app_name;
314
323
315
    sample_file = &image->sample_files[counter];
324
    sample_file = &image->sample_files[counter];
316
325
317
    app_name = separate_samples ? image->app_name : NULL;
326
    app_name = separate_samples ? image->app_name : NULL;
318
    mangled = opd_mangle_filename(image->name, app_name);
327
    mangled = op_mangle_filename(image->name, app_name);
319
328
320
    sprintf(mangled + strlen(mangled), "#%d", counter);
329
    sprintf(mangled + strlen(mangled), "#%d", counter);
321
330
322
    verbprintf("Opening \"%s\"\n", mangled);
331
    verbprintf("Opening \"%s\"\n", mangled);
323
332
...
...
381
static void opd_check_image_mtime(struct opd_image * image)
390
static void opd_check_image_mtime(struct opd_image * image)
382
{
391
{
383
    uint i;
392
    uint i;
384
    char *mangled;
393
    char *mangled;
385
    uint len;
394
    uint len;
386
    time_t newmtime = opd_get_mtime(image->name);
395
    time_t newmtime = op_get_mtime(image->name);
387
    const char * app_name;
396
    const char * app_name;
388
 
397
 
389
    if (image->mtime == newmtime)
398
    if (image->mtime == newmtime)
390
        return;
399
        return;
391
400
392
    verbprintf("Current mtime %lu differs from stored "
401
    verbprintf("Current mtime %lu differs from stored "
393
        "mtime %lu for %s\n", newmtime, image->mtime, image->name);
402
        "mtime %lu for %s\n", newmtime, image->mtime, image->name);
394
403
395
    app_name = separate_samples ? image->app_name : NULL;
404
    app_name = separate_samples ? image->app_name : NULL;
396
    mangled = opd_mangle_filename(image->name, app_name);
405
    mangled = op_mangle_filename(image->name, app_name);
397
406
398
    len = strlen(mangled);
407
    len = strlen(mangled);
399
408
400
    for (i=0; i < op_nr_counters; i++) {
409
    for (i=0; i < op_nr_counters; i++) {
401
        struct opd_sample_file * file = &image->sample_files[i]; 
410
        struct opd_sample_file * file = &image->sample_files[i]; 
...
...
817
/**
826
/**
818
 * opd_is_in_map - check whether an EIP is within a mapping
827
 * opd_is_in_map - check whether an EIP is within a mapping
819
 * @map: map to check
828
 * @map: map to check
820
 * @eip: EIP value
829
 * @eip: EIP value
821
 *
830
 *
822
 * Return %TRUE if the EIP value @eip is within the boundaries
831
 * Return %1 if the EIP value @eip is within the boundaries
823
 * of the map @map, %FALSE otherwise.
832
 * of the map @map, %0 otherwise.
824
 */
833
 */
825
inline static int opd_is_in_map(struct opd_map *map, u32 eip)
834
inline static int opd_is_in_map(struct opd_map *map, u32 eip)
826
{
835
{
827
    return (eip >= map->start && eip < map->end);
836
    return (eip >= map->start && eip < map->end);
828
}
837
}
...
...
856
865
857
/**
866
/**
858
 * opd_eip_is_kernel - is the sample from kernel/module space
867
 * opd_eip_is_kernel - is the sample from kernel/module space
859
 * @eip: EIP value
868
 * @eip: EIP value
860
 *
869
 *
861
 * Returns %TRUE if @eip is in the address space starting at
870
 * Returns %1 if @eip is in the address space starting at
862
 * kernel_start, %FALSE otherwise.
871
 * kernel_start, %0 otherwise.
863
 */
872
 */
864
inline static int opd_eip_is_kernel(u32 eip)
873
inline static int opd_eip_is_kernel(u32 eip)
865
{
874
{
866
    extern u32 kernel_start;
875
    extern u32 kernel_start;
867
    return (eip >= kernel_start);
876
    return (eip >= kernel_start);
...
...
1167
 * opd_add_ascii_map - parse an ASCII map string for a process
1176
 * opd_add_ascii_map - parse an ASCII map string for a process
1168
 * @proc: process to add map to
1177
 * @proc: process to add map to
1169
 * @line: 0-terminated ASCII string
1178
 * @line: 0-terminated ASCII string
1170
 *
1179
 *
1171
 * Attempt to parse the string @line for map information
1180
 * Attempt to parse the string @line for map information
1172
 * and add the info to the process @proc. Returns %TRUE
1181
 * and add the info to the process @proc. Returns %1
1173
 * on success, %FALSE otherwise.
1182
 * on success, %0 otherwise.
1174
 *
1183
 *
1175
 * The parsing is based on Linux 2.4 format, which looks like this :
1184
 * The parsing is based on Linux 2.4 format, which looks like this :
1176
 *
1185
 *
1177
 * 4001e000-400fc000 r-xp 00000000 03:04 31011      /lib/libc-2.1.2.so
1186
 * 4001e000-400fc000 r-xp 00000000 03:04 31011      /lib/libc-2.1.2.so
1178
 */
1187
 */
...
...
1186
    while (*cp && *cp != ' ')
1195
    while (*cp && *cp != ' ')
1187
        cp++;
1196
        cp++;
1188
1197
1189
    /* handle rwx */
1198
    /* handle rwx */
1190
    if (!*cp || (!*(++cp)) || (!*(++cp)) || (*(++cp) != 'x'))
1199
    if (!*cp || (!*(++cp)) || (!*(++cp)) || (*(++cp) != 'x'))
1191
        return FALSE;
1200
        return 0;
1192
1201
1193
    /* get start and end from "40000000-4001f000" */
1202
    /* get start and end from "40000000-4001f000" */
1194
    if (sscanf(line,"%x-%x", &map->start, &map->end) != 2)
1203
    if (sscanf(line,"%x-%x", &map->start, &map->end) != 2)
1195
        return FALSE;
1204
        return 0;
1196
1205
1197
    /* "p " */
1206
    /* "p " */
1198
    cp += 2;
1207
    cp += 2;
1199
1208
1200
    /* read offset */
1209
    /* read offset */
1201
    if (sscanf(cp,"%x", &map->offset) != 1)
1210
    if (sscanf(cp,"%x", &map->offset) != 1)
1202
        return FALSE;
1211
        return 0;
1203
1212
1204
    while (*cp && *cp != '/')
1213
    while (*cp && *cp != '/')
1205
        cp++;
1214
        cp++;
1206
1215
1207
    if (!*cp)
1216
    if (!*cp)
1208
        return FALSE;
1217
        return 0;
1209
1218
1210
    /* FIXME: we should verify this is indeed the primary
1219
    /* FIXME: we should verify this is indeed the primary
1211
     * app image by readlinking /proc/pid/exe */
1220
     * app image by readlinking /proc/pid/exe */
1212
    map->image = opd_get_image(cp, -1, opd_app_name(proc), 0);
1221
    map->image = opd_get_image(cp, -1, opd_app_name(proc), 0);
1213
1222
1214
    if (!map->image)
1223
    if (!map->image)
1215
        return FALSE;
1224
        return 0;
1216
1225
1217
    if (++proc->nr_maps == proc->max_nr_maps)
1226
    if (++proc->nr_maps == proc->max_nr_maps)
1218
        opd_grow_maps(proc);
1227
        opd_grow_maps(proc);
1219
1228
1220
    return TRUE;
1229
    return 1;
1221
}
1230
}
1222
1231
1223
/**
1232
/**
1224
 * opd_get_ascii_maps - read all maps for a process
1233
 * opd_get_ascii_maps - read all maps for a process
1225
 * @proc: process to work on
1234
 * @proc: process to work on
...
...
1234
    char *line;
1243
    char *line;
1235
1244
1236
    snprintf(mapsfile + 6, 6, "%hu", proc->pid);
1245
    snprintf(mapsfile + 6, 6, "%hu", proc->pid);
1237
    strcat(mapsfile,"/maps");
1246
    strcat(mapsfile,"/maps");
1238
1247
1239
    fp = opd_try_open_file(mapsfile, "r");
1248
    fp = op_try_open_file(mapsfile, "r");
1240
    if (!fp)
1249
    if (!fp)
1241
        return;
1250
        return;
1242
1251
1243
    while (1) {
1252
    while (1) {
1244
        line = opd_get_line(fp);
1253
        line = op_get_line(fp);
1245
        if (streq(line, "") && feof(fp)) {
1254
        if (streq(line, "") && feof(fp)) {
1246
            free(line);
1255
            free(line);
1247
            break;
1256
            break;
1248
        } else {
1257
        } else {
1249
            opd_add_ascii_map(proc, line);
1258
            opd_add_ascii_map(proc, line);
1250
            free(line);
1259
            free(line);
1251
        }
1260
        }
1252
    }
1261
    }
1253
1262
1254
    opd_close_file(fp);
1263
    op_close_file(fp);
1255
}
1264
}
1256
1265
1257
/**
1266
/**
1258
 * opd_get_ascii_procs - read process and mapping information from /proc
1267
 * opd_get_ascii_procs - read process and mapping information from /proc
1259
 *
1268
 *