This patch extends the "percpu" command so that it can be used on static variable directly (a bit like the "p" command). Signed-off-by: Petr Tesarik <ptesarik@xxxxxxx> --- help.c | 4 ++-- symbols.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 9 deletions(-)
Extend percpu to recognize static variables This patch extends the "percpu" command so that it can be used on static variable directly (a bit like the "p" command). Signed-off-by: Petr Tesarik <ptesarik@xxxxxxx> --- help.c | 4 ++-- symbols.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 9 deletions(-) --- a/help.c +++ b/help.c @@ -1150,7 +1150,7 @@ NULL char *help_percpu[] = { "percpu", "percpu variables", -"[-a] [-c cpu] [cpu]... [struct|union|*] struct_name [address|symbol]", +"[-a] [-c cpu] [cpu]... [struct|union|*] [struct_name] [address|symbol]", " This command displays a formatted display of the contents of a per-cpu", " variable for a given set of CPUs.", " ", @@ -1163,7 +1163,7 @@ char *help_percpu[] = { " currently selected task.", "\nEXAMPLES", " Show the value of a per-cpu variable on processor 2:\n", -" %s> percpu 2 list_head blk_cpu_iopoll", +" %s> percpu 2 blk_cpu_iopoll", " [2]: ffff88011e290100", " struct list_head {", " next = 0xffff88011e290100, ", --- a/symbols.c +++ b/symbols.c @@ -5987,6 +5987,27 @@ freebuf: } } +static char * +symbol_type_name(const char *name) +{ + char buf[BUFSIZE], *p; + + open_tmpfile(); + sprintf(buf, "whatis %s", name); + if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) { + close_tmpfile(); + return NULL; + } + + rewind(pc->tmpfile); + while (fgets(buf, BUFSIZE, pc->tmpfile) && !STRNEQ(buf, "type = ")) + ; + p = feof(pc->tmpfile) ? NULL : buf + strlen("type = "); + close_tmpfile(); + + return p ? strdup(clean_line(p)) : NULL; +} + /* * This command displays a data type after adjusting the address with * a per-cpu offset. @@ -6052,34 +6073,45 @@ cmd_percpu(void) flags = 0UL; structname = NULL; + sp = NULL; if (STREQ(args[optind], "struct")) { flags |= STRUCT_REQUEST; structname = args[++optind]; + ++optind; } else if (STREQ(args[optind], "union")) { flags |= UNION_REQUEST; structname = args[++optind]; + ++optind; } else if (args[optind][0] == '*') { structname = args[optind][1] ? args[optind] + 1 : args[++optind]; - } else { + ++optind; + } else if (! (sp = per_cpu_symbol_search(args[optind]))) { structname = args[optind]; + ++optind; } - ++optind; - if (argerrs || !structname || !args[optind] || args[optind+1]) { + if (argerrs || !args[optind] || args[optind+1] || + (!structname && !sp)) { FREEBUF(cpus); cmd_usage(pc->curcmd, SYNOPSIS); } - if (arg_to_datatype(structname, dm, + if (structname && arg_to_datatype(structname, dm, DATATYPE_QUERY|ANON_MEMBER_QUERY|RETURN_ON_ERROR) < 1) { FREEBUF(cpus); error(FATAL, "invalid data structure reference: %s\n", structname); } - if (dm->flags & TYPEDEF) { + if (sp) { + typename = symbol_type_name(sp->name); + if (arg_to_datatype(typename, dm, + DATATYPE_QUERY|RETURN_ON_ERROR) < 1) + dm->type = 0; + flags |= dm->type; + } else if (dm->flags & TYPEDEF) { flags |= dm->type; typename = strdup(dm->name); } else { @@ -6099,7 +6131,9 @@ cmd_percpu(void) goto freebuf; } - if (clean_arg() && IS_A_NUMBER(args[optind])) { + if (sp) { + addr = sp->value; + } else if (clean_arg() && IS_A_NUMBER(args[optind])) { addr = htol(args[optind], FAULT_ON_ERROR, NULL); } else if ((sp = per_cpu_symbol_search(args[optind]))) { addr = sp->value; @@ -6131,7 +6165,16 @@ cmd_percpu(void) continue; } - fprintf(fp, "%s ", typename); + /* If it is a struct or union, make output similar to that + * of cmd_datatype_common(), otherwise print a type cast. + * Note that gdb already prints a typecast for pointer types, + * so do not duplicate it here. + */ + if (dm->type & (STRUCT_REQUEST|UNION_REQUEST)) + fprintf(fp, "%s ", typename); + else if (! (dm->type & POINTER)) + fprintf(fp, "(%s) ", typename); + snprintf(buf, sizeof buf, "output *(%s*) 0x%lx", typename, cpuaddr); gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR);
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility