Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169575
b: refs/heads/master
c: 8d06367
h: refs/heads/master
i:
  169573: 4f0a009
  169571: f95e945
  169567: ba5637a
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Nov 8, 2009
1 parent f22c870 commit 147b0b3
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2643ce11457a99a85c5bed8dd631e35968e6ca5a
refs/heads/master: 8d06367fa79c053a4a56a2ce0bb9e840f5da1236
49 changes: 46 additions & 3 deletions trunk/tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "util/header.h"
#include "util/event.h"
#include "util/debug.h"
#include "util/symbol.h"

#include <unistd.h>
#include <sched.h>
Expand Down Expand Up @@ -109,9 +110,21 @@ static void write_output(void *buf, size_t size)
}
}

static void write_event(event_t *buf, size_t size)
{
/*
* Add it to the list of DSOs, so that when we finish this
* record session we can pick the available build-ids.
*/
if (buf->header.type == PERF_RECORD_MMAP)
dsos__findnew(buf->mmap.filename);

write_output(buf, size);
}

static int process_synthesized_event(event_t *event)
{
write_output(event, event->header.size);
write_event(event, event->header.size);
return 0;
}

Expand Down Expand Up @@ -163,14 +176,14 @@ static void mmap_read(struct mmap_data *md)
size = md->mask + 1 - (old & md->mask);
old += size;

write_output(buf, size);
write_event(buf, size);
}

buf = &data[old & md->mask];
size = head - old;
old += size;

write_output(buf, size);
write_event(buf, size);

md->prev = old;
mmap_write_tail(md, old);
Expand Down Expand Up @@ -365,10 +378,38 @@ static void open_counters(int cpu, pid_t pid)
nr_cpu++;
}

static bool write_buildid_table(void)
{
struct dso *pos;
bool have_buildid = false;

list_for_each_entry(pos, &dsos, node) {
struct build_id_event b;
size_t len;

if (filename__read_build_id(pos->long_name,
&b.build_id,
sizeof(b.build_id)) < 0)
continue;
have_buildid = true;
memset(&b.header, 0, sizeof(b.header));
len = strlen(pos->long_name) + 1;
len = ALIGN(len, 64);
b.header.size = sizeof(b) + len;
write_output(&b, sizeof(b));
write_output(pos->long_name, len);
}

return have_buildid;
}

static void atexit_header(void)
{
header->data_size += bytes_written;

if (write_buildid_table())
perf_header__set_feat(header, HEADER_BUILD_ID);

perf_header__write(header, output);
}

Expand Down Expand Up @@ -572,6 +613,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
{
int counter;

symbol__init(0);

argc = parse_options(argc, argv, options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (!argc && target_pid == -1 && !system_wide)
Expand Down
37 changes: 37 additions & 0 deletions trunk/tools/perf/util/data_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,39 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
}
}

static int perf_header__read_build_ids(const struct perf_header *self,
int input, off_t file_size)
{
off_t offset = self->data_offset + self->data_size;
struct build_id_event bev;
char filename[PATH_MAX];
int err = -1;

if (lseek(input, offset, SEEK_SET) < 0)
return -1;

while (offset < file_size) {
struct dso *dso;
ssize_t len;

if (read(input, &bev, sizeof(bev)) != sizeof(bev))
goto out;

len = bev.header.size - sizeof(bev);
if (read(input, filename, len) != len)
goto out;

dso = dsos__findnew(filename);
if (dso != NULL)
dso__set_build_id(dso, &bev.build_id);

offset += bev.header.size;
}
err = 0;
out:
return err;
}

int mmap_dispatch_perf_file(struct perf_header **pheader,
const char *input_name,
int force,
Expand Down Expand Up @@ -130,6 +163,10 @@ int mmap_dispatch_perf_file(struct perf_header **pheader,
if (curr_handler->sample_type_check(sample_type) < 0)
exit(-1);

if (perf_header__has_feat(header, HEADER_BUILD_ID) &&
perf_header__read_build_ids(header, input, input_stat.st_size))
pr_debug("failed to read buildids, continuing...\n");

if (load_kernel(NULL) < 0) {
perror("failed to load kernel symbols");
return EXIT_FAILURE;
Expand Down
7 changes: 7 additions & 0 deletions trunk/tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ struct sample_event{
u64 array[];
};

#define BUILD_ID_SIZE 20

struct build_id_event {
struct perf_event_header header;
u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
char filename[];
};

typedef union event_union {
struct perf_event_header header;
Expand Down
10 changes: 10 additions & 0 deletions trunk/tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ void perf_header__feat_trace_info(struct perf_header *header)
set_bit(HEADER_TRACE_INFO, header->adds_features);
}

void perf_header__set_feat(struct perf_header *self, int feat)
{
set_bit(feat, self->adds_features);
}

bool perf_header__has_feat(const struct perf_header *self, int feat)
{
return test_bit(feat, self->adds_features);
}

static void do_write(int fd, void *buf, size_t size)
{
while (size) {
Expand Down
4 changes: 4 additions & 0 deletions trunk/tools/perf/util/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "../../../include/linux/perf_event.h"
#include <sys/types.h>
#include <stdbool.h>
#include "types.h"

#include <linux/bitmap.h>
Expand All @@ -15,6 +16,7 @@ struct perf_header_attr {
};

#define HEADER_TRACE_INFO 1
#define HEADER_BUILD_ID 2

#define HEADER_FEAT_BITS 256

Expand Down Expand Up @@ -48,6 +50,8 @@ u64 perf_header__sample_type(struct perf_header *header);
struct perf_event_attr *
perf_header__find_attr(u64 id, struct perf_header *header);
void perf_header__feat_trace_info(struct perf_header *header);
void perf_header__set_feat(struct perf_header *self, int feat);
bool perf_header__has_feat(const struct perf_header *self, int feat);

struct perf_header *perf_header__new(void);

Expand Down
14 changes: 12 additions & 2 deletions trunk/tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,18 @@ map__find_symbol(struct map *self, u64 ip, symbol_filter_t filter)
int nr = dso__load(self->dso, self, filter);

if (nr < 0) {
pr_warning("Failed to open %s, continuing without symbols\n",
self->dso->long_name);
if (self->dso->has_build_id) {
char sbuild_id[BUILD_ID_SIZE * 2 + 1];

build_id__sprintf(self->dso->build_id,
sizeof(self->dso->build_id),
sbuild_id);
pr_warning("%s with build id %s not found",
self->dso->long_name, sbuild_id);
} else
pr_warning("Failed to open %s",
self->dso->long_name);
pr_warning(", continuing without symbols\n");
return NULL;
} else if (nr == 0) {
const char *name = self->dso->long_name;
Expand Down
Loading

0 comments on commit 147b0b3

Please sign in to comment.