Hi Dave, On Tue, Nov 21, 2017 at 10:02:42AM -0500, Dave Anderson wrote: [...] > > Hello Leo, > > > > Everything looks fine on paper, except that long ago I stopped accepting > > and adding extension modules as part of the base crash package: Thanks a lot for reviewing. > > > --- > > > extensions/csdump.c | 547 > > > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > 1 file changed, 547 insertions(+) > > > create mode 100644 extensions/csdump.c > > > > Can you please create a simple standalone package that can be added to > > the extensions page here: > > > > http://people.redhat.com/anderson/extensions.html > > > > When your standalone pacakge is ready, I will add it to that page. And > > any future updates to the package can be posted there as a new revision > > whenever you like. > > BTW, by "standalone package", in your case, it can simply be a copy of csdump.c, > since it builds automatically when placed in the extensions subdirectory. > > Note that several of the packages on the extensions page simply consist of a > single file. However, you may want to add a version number, a link to a github > repo, restrict it to ARM64 only, have its own makefile, or whatever you want > to add. That's all up to you -- just let me know. Understand. When I started to write this code, I read the extensions page and referred intel-pt extension which listed on the page. This code is still in early phase and need mature it after I get feedback and suggestions from mailing list. When related kernel patches have been merged into mainline kernel [1], then this will be milestone for me and let you help to add it on the extension page. [1] https://lists.linaro.org/pipermail/coresight/2017-November/000964.html Thanks, Leo Yan > > > diff --git a/extensions/csdump.c b/extensions/csdump.c > > > new file mode 100644 > > > index 0000000..c657378 > > > --- /dev/null > > > +++ b/extensions/csdump.c > > > @@ -0,0 +1,547 @@ > > > +/* > > > + * Extension module to dump log buffer of ARM Coresight Trace > > > + * > > > + * Copyright (C) 2017 Linaro Ltd. > > > + * > > > + * This program is free software; you can redistribute it and/or modify > > > + * it under the terms of the GNU General Public License as published by > > > + * the Free Software Foundation; either version 2 of the License, or > > > + * (at your option) any later version. > > > + * > > > + * This program is distributed in the hope that it will be useful, > > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > > + * GNU General Public License for more details. > > > + */ > > > + > > > +#define _GNU_SOURCE > > > +#include <sys/file.h> > > > + > > > +#include "defs.h" > > > + > > > +static unsigned int perf_header[] = { > > > + 0x46524550, 0x32454c49, /* Magic: PERFILE2 */ > > > + 0x00000068, 0x00000000, /* header size */ > > > + 0x00000080, 0x00000000, /* attr size */ > > > + 0x00000078, 0x00000000, /* attrs offset */ > > > + 0x00000100, 0x00000000, /* attrs size */ > > > + 0x00000178, 0x00000000, /* data offset */ > > > + 0x00002568, 0x00000000, /* data size */ > > > + 0x00000000, 0x00000000, /* event offset */ > > > + 0x00000000, 0x00000000, /* event size */ > > > + 0x00040004, 0x00000000, /* feature bitmap */ > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000 > > > +}; > > > + > > > +static unsigned int perf_event_id[] = { > > > + 0x00000015, 0x00000000, > > > + 0x00000016, 0x00000000, > > > +}; > > > + > > > +static unsigned int perf_event_cs_etm[] = { > > > + 0x00000006, 0x00000070, /* event type: 6, size: 0x70 */ > > > + 0x00000000, 0x00000000, /* config: 0 */ > > > + 0x00000001, 0x00000000, /* sample_period: 1 */ > > > + 0x00010003, 0x00000000, /* sample_type: PERF_SAMPLE_IP | PERF_SAMPLE_TID > > > | > > > + PERF_SAMPLE_PERIOD */ > > > + 0x00000004, 0x00000000, /* read_format: PERF_FORMAT_ID */ > > > + 0x00141001, 0x00000000, /* disabled: 1, enable_on_exec: 1, > > > + sample_id_all: 1, exclude_guest: 1 */ > > > + 0x00000000, 0x00000000, /* wakeup_events: 0, bp_type: 0 */ > > > + 0x00000000, 0x00000000, /* config1 : 0 */ > > > + 0x00000000, 0x00000000, /* config1 : 0 */ > > > + 0x00000000, 0x00000000, /* branch_sample_type: 0 */ > > > + 0x00000000, 0x00000000, /* sample_regs_user: 0 */ > > > + 0x00000000, 0x00000000, /* sample_stack_user: 0, clockid: 0 */ > > > + 0x00000000, 0x00000000, /* sample_regs_intr: 0 */ > > > + 0x00000000, 0x00000000, /* aux_watermark: 0, sample_max_stack: 0 */ > > > + 0x00000068, 0x00000000, /* ids.offset: 0x68 */ > > > + 0x00000008, 0x00000000, /* ids.size: 0x8 */ > > > +}; > > > + > > > +static unsigned int perf_event_dummy[] = { > > > + 0x00000001, 0x00000070, /* event type: 1, size: 0x70 */ > > > + 0x00000009, 0x00000000, /* config: 9 */ > > > + 0x00000001, 0x00000000, /* sample_period: 1 */ > > > + 0x00010003, 0x00000000, /* sample_type: PERF_SAMPLE_IP | PERF_SAMPLE_TID > > > | > > > + PERF_SAMPLE_PERIOD */ > > > + 0x00000004, 0x00000000, /* read_format: PERF_FORMAT_ID */ > > > + 0x01843361, 0x00000000, /* disabled: 1, exclude_kernel: 1 > > > + exclude_hv: 1, mmap: 1, > > > + comm: 1, enable_on_exec: 1, > > > + task: 1, sample_id_all: 1, > > > + mmap2: 1, comm_exec: 1 */ > > > + 0x00000000, 0x00000000, /* wakeup_events: 0, bp_type: 0 */ > > > + 0x00000000, 0x00000000, /* config1 : 0 */ > > > + 0x00000000, 0x00000000, /* config1 : 0 */ > > > + 0x00000000, 0x00000000, /* branch_sample_type: 0 */ > > > + 0x00000000, 0x00000000, /* sample_regs_user: 0 */ > > > + 0x00000000, 0x00000000, /* sample_stack_user: 0, clockid: 0 */ > > > + 0x00000000, 0x00000000, /* sample_regs_intr: 0 */ > > > + 0x00000000, 0x00000000, /* aux_watermark: 0, sample_max_stack: 0 */ > > > + 0x00000070, 0x00000000, /* ids.offset: 0x70 */ > > > + 0x00000008, 0x00000000, /* ids.size: 0x8 */ > > > +}; > > > + > > > +static unsigned int perf_auxtrace_info[] = { > > > + 0x00000046, 0x02680000, /* type: PERF_RECORD_AUXTRACE_INFO, size: 0x268 > > > */ > > > + 0x00000003, 0x00000000, /* info->type: PERF_AUXTRACE_CS_ETM */ > > > + 0x00000000, 0x00000000, /* version: 0 */ > > > + 0x00000008, 0x00000006, /* cpus: 8, type: 6 */ > > > + 0x00000000, 0x00000000 /* snapshot_mode: 0 */ > > > +}; > > > + > > > +static unsigned int perf_kernel_mmap[] = { > > > + 0x00000001, 0x00500001, /* type: PERF_RECORD_MMAP, size: 0x50, > > > + misc: PERF_RECORD_MISC_KERNEL */ > > > + 0xffffffff, 0x00000000, /* pid: 0xffffffff, tid: 0x0 */ > > > + 0x08080000, 0xffff0000, /* start: 0xffff000008080000 */ > > > + 0xf7f7ffff, 0x0000ffff, /* len: 0x0000fffff7f7ffff */ > > > + 0x08080000, 0xffff0000, /* pgoff: 0xffff000008080000 */ > > > + 0x72656b5b, 0x2e6c656e, /* filename: [kernel.kallsyms]_text */ > > > + 0x6c6c616b, 0x736d7973, > > > + 0x65745f5d, 0x00007478, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > +}; > > > + > > > +static unsigned int perf_threads[] = { > > > + 0x00000003, 0x00280000, /* type: PERF_RECORD_COMM, size: 0x28 */ > > > + 0x0000090c, 0x0000090c, /* pid: 0x90c, tid: 0x90c */ > > > + 0x66726570, 0x00000000, /* comm: perf */ > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + > > > + 0x00000003, 0x00282000, /* type: PERF_RECORD_COMM, size: 0x28 */ > > > + 0x0000090c, 0x0000090c, /* pid: 0x90c, tid: 0x90c */ > > > + 0x696e6170, 0x00000063, /* comm: panic */ > > > + 0x0000090c, 0x0000090c, > > > + 0x00000016, 0x00000000, > > > + > > > + 0x0000000a, 0x00680002, /* type: PERF_RECORD_MMAP2, size: 0x68 */ > > > + 0x0000090c, 0x0000090c, /* pid: 0x90c, tid: 0x90c */ > > > + 0x00400000, 0x00000000, /* addr: 0x00400000 */ > > > + 0x00006000, 0x00000000, /* len: 0x00006000 */ > > > + 0x00000000, 0x00000000, /* pgoff: 0x0 */ > > > + 0x000000b3, 0x00000009, /* maj: 0xb3, min: 0x9 */ > > > + 0x00000085, 0x00000000, /* ino: 0x85 */ > > > + 0x00000000, 0x00000000, /* ino_generation: 0x0 */ > > > + 0x00000005, 0x00001802, /* prot: PROT_READ | PROT_EXEC, flag: 0x1802 */ > > > + 0x6e69622f, 0x616e752f, /* comm: /bin/uname */ > > > + 0x0000656d, 0x00000000, > > > + 0x0000090c, 0x0000090c, > > > + 0x00000016, 0x00000000, > > > + > > > + 0x0000000a, 0x00800002, > > > + 0x0000090c, 0x0000090c, > > > + 0xb77c2000, 0x0000ffff, > > > + 0x0002e000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x000000b3, 0x00000009, > > > + 0x00000752, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000005, 0x00001802, > > > + 0x62696c2f, 0x7261612f, /* ld-2.19.so */ > > > + 0x34366863, 0x6e696c2d, > > > + 0x672d7875, 0x6c2f756e, > > > + 0x2e322d64, 0x732e3931, > > > + 0x0000006f, 0x00000000, > > > + 0x0000090c, 0x0000090c, > > > + 0x00000016, 0x00000000, > > > + > > > + 0x0000000a, 0x00600002, > > > + 0x0000090c, 0x0000090c, > > > + 0xb77ec000, 0x0000ffff, > > > + 0x00001000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000005, 0x00001002, > > > + 0x7364765b, 0x00005d6f, /* [vdso] */ > > > + 0x0000090c, 0x0000090c, > > > + 0x00000016, 0x00000000, > > > + > > > + 0x0000000a, 0x00800002, > > > + 0x0000090c, 0x0000090c, > > > + 0xb7675000, 0x0000ffff, > > > + 0x0014d000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x000000b3, 0x00000009, > > > + 0x0000076a, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000005, 0x00001002, > > > + 0x62696c2f, 0x7261612f, /* /lib/aarch64-linux-gnu/libc-2.19.so */ > > > + 0x34366863, 0x6e696c2d, > > > + 0x672d7875, 0x6c2f756e, > > > + 0x2d636269, 0x39312e32, > > > + 0x006f732e, 0x00000000, > > > + 0x0000090c, 0x0000090c, > > > + 0x00000016, 0x00000000, > > > + > > > + 0x0000000b, 0x00300000, /* type: PERF_RECORD_AUX, size: 0x30 */ > > > + 0x00000000, 0x00000000, /* aux_offset: 0x0 */ > > > + 0x00002000, 0x00000000, /* aux_size: 0x2000 */ > > > + 0x00000001, 0x00000000, /* flag: 0x1 */ > > > + 0x0000090c, 0x0000090c, > > > + 0x00000015, 0x00000000, > > > + > > > + 0x00000004, 0x00300000, /* type: PERF_RECORD_EXIT, size: 0x30 */ > > > + 0x0000090c, 0x0000090c, /* pid, ppid: 0x90c */ > > > + 0x0000090c, 0x0000090c, /* tid, ptid: 0x90c */ > > > + 0xf89cbddc, 0x00000571, > > > + 0x0000090c, 0x0000090c, > > > + 0x00000016, 0x00000000, > > > +}; > > > + > > > +static unsigned int perf_auxtrace_snapshot[] = { > > > + 0x00000047, 0x00300000, /* type: PERF_RECORD_AUXTRACE, size: 0x30 */ > > > + 0x00002000, 0x00000000, /* auxsize: 0x2000 */ > > > + 0x00000000, 0x00000000, /* auxoffset: 0x0 */ > > > + 0x74bc6ab4, 0x5a1c47b3, /* reference: rand() */ > > > + 0x00000000, 0x0000090c, /* idx: 0x0, pid: 0x90c */ > > > + 0xffffffff, 0x00000000, /* cpu: -1 */ > > > +}; > > > + > > > +static unsigned int perf_record_finish[] = { > > > + 0x00000044, 0x00080000, > > > +}; > > > + > > > +static unsigned int perf_sections[] = { > > > + 0x00002760, 0x00000000, /* buildid section: start addr */ > > > + 0x00000064, 0x00000000, /* buildid section: len */ > > > + 0x000027c4, 0x00000000, /* auxtrace section: start addr */ > > > + 0x00000018, 0x00000000, /* auxtrace section: len */ > > > + 0x000027dc, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > +}; > > > + > > > +static unsigned int perf_sections_feat[] = { > > > + 0x00000000, 0x00640001, > > > + 0xffffffff, 0xc9b5ee32, > > > + 0xa6009dc9, 0xcb21093d, > > > + 0x23c315d8, 0x1067c385, > > > + 0x00000000, 0x72656b5b, > > > + 0x2e6c656e, 0x6c6c616b, > > > + 0x736d7973, 0x0000005d, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, 0x00000000, > > > + 0x00000000, > > > + > > > + 0x00000001, 0x00000000, > > > + 0x000006a8, 0x00000000, > > > + 0x00000030, 0x00000000, > > > +}; > > > + > > > +#define koffset(struct, member) struct##_##member##_offset > > > + > > > +/* at = ((struct *)ptr)->member */ > > > +#define read_value(at, ptr, struct, member) \ > > > + do { \ > > > + readmem(ptr + koffset(struct, member), KVADDR, \ > > > + &at, sizeof(at), #struct "'s " #member, \ > > > + RETURN_ON_ERROR); \ > > > + } while (0) > > > + > > > + > > > +#define init_offset(struct, member) do { \ > > > + koffset(struct, member) = MEMBER_OFFSET(#struct, #member);\ > > > + if (koffset(struct, member) < 0) { \ > > > + fprintf(fp, "failed to init the offset, struct:"\ > > > + #struct ", member:" #member); \ > > > + fprintf(fp, "\n"); \ > > > + return -1; \ > > > + } \ > > > + } while (0) > > > + > > > +static int koffset(coresight_dump_node, cpu); > > > +static int koffset(coresight_dump_node, list); > > > +static int koffset(coresight_dump_node, buf); > > > +static int koffset(coresight_dump_node, buf_size); > > > +static int koffset(coresight_dump_node, name); > > > +static int koffset(coresight_dump_node, csdev); > > > + > > > +static int koffset(coresight_device, dev); > > > +static int koffset(device, kobj); > > > +static int koffset(kobject, name); > > > + > > > +static struct list_data list_data; > > > +static int instance_count; > > > +static int csdump_metadata_len = 0; > > > + > > > +static int csdump_write_buf(FILE *out_fp, char *component, int cpu_idx) > > > +{ > > > + ulong instance_ptr; > > > + ulong field; > > > + ulong buf_addr; > > > + ulong csdev_addr; > > > + ulong dev_addr; > > > + ulong kobj_addr; > > > + ulong name_addr; > > > + int cpu, buf_sz, i, ret; > > > + char name[64]; > > > + char *buf; > > > + > > > + /* We start i at 1 to skip over the list_head and continue to the last > > > + * instance, which lies at index instance_count */ > > > + for (i = 1; i <= instance_count; i++) { > > > + instance_ptr = list_data.list_ptr[i]; > > > + > > > + field = instance_ptr - koffset(coresight_dump_node, list); > > > + > > > + read_value(cpu, field, coresight_dump_node, cpu); > > > + read_value(buf_addr, field, coresight_dump_node, buf); > > > + read_value(buf_sz, field, coresight_dump_node, buf_size); > > > + > > > + read_value(csdev_addr, field, coresight_dump_node, csdev); > > > + dev_addr = csdev_addr + koffset(coresight_device, dev); > > > + kobj_addr = dev_addr + koffset(device, kobj); > > > + > > > + read_value(name_addr, kobj_addr, kobject, name); > > > + read_string(name_addr, name, 64); > > > + > > > + if (!buf_sz) > > > + continue; > > > + > > > + if (strstr(name, component) && (cpu == cpu_idx)) > > > + break; > > > + } > > > + > > > + if (i > instance_count) > > > + return -1; > > > + > > > + buf = malloc(buf_sz); > > > + readmem(buf_addr, KVADDR, buf, buf_sz, "read dump log buf", > > > + FAULT_ON_ERROR); > > > + > > > + ret = fwrite(buf, buf_sz, 1, out_fp); > > > + if (!ret) { > > > + fprintf(fp, "[%d] Cannot write file\n", cpu); > > > + free(buf); > > > + return -1; > > > + } > > > + > > > + free(buf); > > > + > > > + return buf_sz; > > > +} > > > + > > > +static int csdump_metadata(void) > > > +{ > > > + FILE *out_fp; > > > + int online_cpus, i; > > > + > > > + if ((out_fp = fopen("./metadata.bin", "w")) == NULL) { > > > + fprintf(fp, "Cannot open file\n"); > > > + return -1; > > > + } > > > + > > > + online_cpus = get_cpus_online(); > > > + for (i = 0; i < online_cpus; i++) { > > > + fprintf(fp, "cpu = %d\n", i); > > > + csdump_metadata_len += csdump_write_buf(out_fp, "etm", i); > > > + } > > > + > > > + fclose(out_fp); > > > + > > > + return 0; > > > +} > > > + > > > +static int csdump_tracedata(void) > > > +{ > > > + FILE *out_fp; > > > + > > > + if ((out_fp = fopen("./cstrace.bin", "w")) == NULL) { > > > + fprintf(fp, "Cannot open file\n"); > > > + return -1; > > > + } > > > + > > > + csdump_write_buf(out_fp, "etf", 0); > > > + > > > + fclose(out_fp); > > > + > > > + return 0; > > > +} > > > + > > > +static int csdump_perfdata(void) > > > +{ > > > + FILE *out_fp; > > > + int online_cpus, i; > > > + int trace_len = 0; > > > + int pos, diff; > > > + > > > + if ((out_fp = fopen("./perf.data", "w")) == NULL) { > > > + fprintf(fp, "Cannot open file\n"); > > > + return -1; > > > + } > > > + > > > + fwrite(perf_header, sizeof(perf_header), 1, out_fp); > > > + fwrite(perf_event_id, sizeof(perf_event_id), 1, out_fp); > > > + fwrite(perf_event_cs_etm, sizeof(perf_event_cs_etm), 1, out_fp); > > > + fwrite(perf_event_dummy, sizeof(perf_event_dummy), 1, out_fp); > > > + > > > + online_cpus = get_cpus_online(); > > > + > > > + /* Adjust auxtrace_info size */ > > > + perf_auxtrace_info[1] = (perf_auxtrace_info[1] & 0xffff) | > > > + ((sizeof(perf_auxtrace_info) + csdump_metadata_len) << 16); > > > + /* Adjust CPU num */ > > > + perf_auxtrace_info[6] = online_cpus; > > > + > > > + fwrite(perf_auxtrace_info, sizeof(perf_auxtrace_info), 1, out_fp); > > > + trace_len += sizeof(perf_auxtrace_info); > > > + > > > + for (i = 0; i < online_cpus; i++) { > > > + fprintf(fp, "cpu = %d\n", i); > > > + trace_len += csdump_write_buf(out_fp, "etm", i); > > > + } > > > + > > > + fwrite(perf_kernel_mmap, sizeof(perf_kernel_mmap), 1, out_fp); > > > + trace_len += sizeof(perf_kernel_mmap); > > > + > > > + fwrite(perf_threads, sizeof(perf_threads), 1, out_fp); > > > + trace_len += sizeof(perf_threads); > > > + > > > + fwrite(perf_auxtrace_snapshot, sizeof(perf_auxtrace_snapshot), 1, > > > out_fp); > > > + trace_len += sizeof(perf_auxtrace_snapshot); > > > + > > > + trace_len += csdump_write_buf(out_fp, "etf", 0); > > > + > > > + fwrite(perf_record_finish, sizeof(perf_record_finish), 1, out_fp); > > > + trace_len += sizeof(perf_record_finish); > > > + > > > + pos = ftell(out_fp); > > > + pos += sizeof(perf_sections); > > > + > > > + diff = perf_sections[0] - pos; > > > + > > > + for (i = 0; i < sizeof(perf_sections) / 4; i += 4) { > > > + if (!perf_sections[i]) > > > + continue; > > > + > > > + perf_sections[i] = perf_sections[i] - diff; > > > + } > > > + > > > + fwrite(perf_sections, sizeof(perf_sections), 1, out_fp); > > > + fwrite(perf_sections_feat, sizeof(perf_sections_feat), 1, out_fp); > > > + > > > + fseek(out_fp, 48L, SEEK_SET); > > > + fwrite(&trace_len, sizeof(trace_len), 1, out_fp); > > > + > > > + fclose(out_fp); > > > + > > > + return 0; > > > +} > > > + > > > +static int csdump_prepare(void) > > > +{ > > > + struct syment *sym_dump_list; > > > + struct kernel_list_head *cs_dump_list_head; > > > + > > > + init_offset(coresight_dump_node, cpu); > > > + init_offset(coresight_dump_node, list); > > > + init_offset(coresight_dump_node, buf); > > > + init_offset(coresight_dump_node, buf_size); > > > + init_offset(coresight_dump_node, name); > > > + init_offset(coresight_dump_node, csdev); > > > + > > > + init_offset(coresight_device, dev); > > > + init_offset(device, kobj); > > > + init_offset(kobject, name); > > > + > > > + /* Get pointer to dump list */ > > > + sym_dump_list = symbol_search("coresight_dump_list"); > > > + if (!sym_dump_list) { > > > + fprintf(fp, "symbol coresight_dump_list is not found\n"); > > > + return -1; > > > + } > > > + > > > + cs_dump_list_head = (void *)sym_dump_list->value; > > > + fprintf(fp, "cs_dump_list_head = 0x%p\n", cs_dump_list_head); > > > + > > > + BZERO(&list_data, sizeof(struct list_data)); > > > + list_data.start = (ulong)cs_dump_list_head; > > > + list_data.end = (ulong)cs_dump_list_head; > > > + list_data.flags = LIST_ALLOCATE; > > > + instance_count = do_list(&list_data); > > > + > > > + /* > > > + * The do_list count includes the list_head, which is not > > > + * a proper instance so minus 1. > > > + */ > > > + instance_count--; > > > + if (instance_count <= 0) > > > + return -1; > > > + > > > + return 0; > > > +} > > > + > > > +static void csdump_unprepare(void) > > > +{ > > > + FREEBUF(list_data.list_ptr); > > > +} > > > + > > > +void cmd_csdump(void) > > > +{ > > > + char* outdir; > > > + mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | > > > + S_IRGRP | S_IXGRP | > > > + S_IROTH | S_IXOTH; /* 0755 */ > > > + int ret; > > > + > > > + if (argcnt != 2) > > > + cmd_usage(pc->curcmd, SYNOPSIS); > > > + > > > + outdir = args[1]; > > > + if ((ret = mkdir(outdir, mode))) { > > > + fprintf(fp, "Cannot create directory %s: %d\n", outdir, ret); > > > + return; > > > + } > > > + > > > + if ((ret = chdir(outdir))) { > > > + fprintf(fp, "Cannot chdir %s: %d\n", outdir, ret); > > > + return; > > > + } > > > + > > > + if (csdump_prepare()) > > > + goto out; > > > + > > > + csdump_metadata(); > > > + csdump_tracedata(); > > > + csdump_perfdata(); > > > + > > > +out: > > > + csdump_unprepare(); > > > + chdir(".."); > > > + return; > > > +} > > > + > > > +char *help_csdump[] = { > > > + "csdump", > > > + "Dump log buffer of Coresight Trace", > > > + "<output-dir>", > > > + "This command extracts coresight log buffer to the directory", > > > + "specified by <output-dir>", > > > + NULL > > > +}; > > > + > > > +static struct command_table_entry command_table[] = { > > > + { "csdump", cmd_csdump, help_csdump, 0}, > > > + { NULL }, > > > +}; > > > + > > > +void __attribute__((constructor)) > > > +csdump_init(void) > > > +{ > > > + register_extension(command_table); > > > +} > > > + > > > +void __attribute__((destructor)) > > > +csdump_fini(void) { } > > > -- > > > 2.7.4 > > > > > > -- > > > Crash-utility mailing list > > > Crash-utility@xxxxxxxxxx > > > https://www.redhat.com/mailman/listinfo/crash-utility > > > > > > > -- > > Crash-utility mailing list > > Crash-utility@xxxxxxxxxx > > https://www.redhat.com/mailman/listinfo/crash-utility > > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility