From: George Dunlap <george.dunlap@eu.citrix.com>
To: Don Slutz <dslutz@verizon.com>, xen-devel@lists.xen.org
Cc: Don Slutz <Don@CloudSwitch.com>,
Ian Jackson <ian.jackson@eu.citrix.com>,
Ian Campbell <ian.campbell@citrix.com>,
Jan Beulich <jbeulich@suse.com>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: Re: [PATCH v4 10/15] xenctx: Add -M <maddr> option to dump memory at maddr.
Date: Wed, 19 Mar 2014 17:08:01 +0000 [thread overview]
Message-ID: <5329CEF1.9010603@eu.citrix.com> (raw)
In-Reply-To: <1395180940-23901-11-git-send-email-dslutz@verizon.com>
On 03/18/2014 10:15 PM, Don Slutz wrote:
> Currently not supported on ARM.
>
> New routine read_mem_word() will correctly read a word that crosses
> a page boundary. It will not fault if the 2nd page can not be
> mapped.
>
> Here is an example:
>
> Memory (address ffffffff803ddf90):
> ffffffff80048d19 0000000000200800 ffffffff803e7801 0000000000086800
> 0000000000000000 ffffffff80430720 ffffffff803e722f 80008e000010019c
> 00000000ffffffff 0000000000000000 0000000000000000 0000000000200000
> 0000000000000000 0000000000000000 0000000000000000 00cf9b000000ffff
> 00af9b000000ffff 00cf93000000ffff 00cffb000000ffff 00cff3000000ffff
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> ---
> v4 Changed from -m to -M
>
> tools/xentrace/xenctx.c | 168 ++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 150 insertions(+), 18 deletions(-)
>
> diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
> index e5c45df..e7d490e 100644
> --- a/tools/xentrace/xenctx.c
> +++ b/tools/xentrace/xenctx.c
> @@ -29,23 +29,6 @@
> #include <xen/foreign/x86_64.h>
> #include <xen/hvm/save.h>
>
> -static struct xenctx {
> - xc_interface *xc_handle;
> - int domid;
> - int frame_ptrs;
> - int stack_trace;
> - int disp_all;
> - int multiple_pages;
> - int bytes_per_line;
> - int lines;
> - int decode_as_ascii;
> - int tag_stack_dump;
> - int tag_call_trace;
> - int all_vcpus;
> - int self_paused;
> - xc_dominfo_t dominfo;
> -} xenctx;
> -
> #if defined (__i386__) || defined (__x86_64__)
> typedef unsigned long long guest_word_t;
> #define FMT_32B_WORD "%08llx"
> @@ -69,6 +52,27 @@ typedef uint64_t guest_word_t;
>
> #define MAX_BYTES_PER_LINE 128
>
> +static struct xenctx {
> + xc_interface *xc_handle;
> + int domid;
> + int frame_ptrs;
> + int stack_trace;
> + int disp_all;
> + int multiple_pages;
> + int bytes_per_line;
> + int lines;
> + int decode_as_ascii;
> + int tag_stack_dump;
> + int tag_call_trace;
> + int all_vcpus;
> +#ifndef NO_TRANSLATION
> + guest_word_t mem_addr;
> + int do_memory;
> +#endif
> + int self_paused;
> + xc_dominfo_t dominfo;
> +} xenctx;
> +
> struct symbol {
> guest_word_t address;
> char *name;
> @@ -630,6 +634,37 @@ static guest_word_t read_stack_word(guest_word_t *src, int width)
> return word;
> }
>
> +#ifndef NO_TRANSLATION
You seem to be nesting "#ifndef NO_TRANSLATION" here -- there's already
an #ifndef up above map_page.
> +static guest_word_t read_mem_word(vcpu_guest_context_any_t *ctx, int vcpu,
> + guest_word_t virt, int width)
> +{
> + if ( (virt & 7) == 0 )
> + {
> + guest_word_t *p = map_page(ctx, vcpu, virt);
> +
> + if ( p )
> + return read_stack_word(p, width);
> + else
> + return -1;
> + } else {
> + guest_word_t word = -1;
> + char *src, *dst;
> + int i;
> +
> + dst = (char*)&word;
> + for (i = 0; i < width; i++ )
> + {
> + src = map_page(ctx, vcpu, virt + i);
> + if ( src )
> + *dst++ = *src;
> + else
> + return word;
> + }
> + return word;
> + }
> +}
> +#endif
> +
> static void print_stack_word(guest_word_t word, int width)
> {
> if (width == 4)
> @@ -638,6 +673,67 @@ static void print_stack_word(guest_word_t word, int width)
> printf(FMT_64B_WORD, word);
> }
>
> +#ifndef NO_TRANSLATION
> +static void print_mem(vcpu_guest_context_any_t *ctx, int vcpu, int width, guest_word_t mem_addr)
> +{
> + guest_word_t instr;
> + guest_word_t instr_start;
> + guest_word_t word;
> + guest_word_t ascii[MAX_BYTES_PER_LINE/4];
> + int i;
> +
> + instr_start = mem_addr;
> + instr = mem_addr;
> + printf("Memory (address ");
> + print_stack_word(instr, width);
> + printf("):\n");
> + for (i = 1; i < xenctx.lines + 1; i++)
> + {
> + int j = 0;
> + int k;
> +
> + if ( xenctx.tag_stack_dump )
> + {
> + print_stack_word(instr, width);
> + printf(":");
> + }
> + while ( instr < instr_start + i * xenctx.bytes_per_line )
> + {
> + void *p = map_page(ctx, vcpu, instr);
> + if ( !p )
> + return;
> + word = read_mem_word(ctx, vcpu, instr, width);
> + if ( xenctx.decode_as_ascii )
> + ascii[j++] = word;
> + printf(" ");
> + print_stack_word(word, width);
> + instr += width;
> + }
> + printf(" ");
> + if ( xenctx.decode_as_ascii )
> + {
> + for (k = j; k < xenctx.bytes_per_line / width; k++)
> + printf(" %*s", width*2, "");
> + for (k = 0; k < j; k++)
> + {
> + int l;
> + unsigned char *bytep = (unsigned char*)&ascii[k];
> +
> + for (l = 0; l < width; l++)
> + {
> + if ( (*bytep < 127) && (*bytep >= 32) )
> + printf("%c", *bytep);
> + else
> + printf(".");
> + bytep++;
> + }
> + }
> + }
> + printf("\n");
This inner loop seems to be an exact copy of the code in print_stack --
wouldn't it make sense to make a generic "dump memory area" function,
and have both print_mem and print_stack call it?
> + }
> +}
> +#endif
> +
> static int print_code(vcpu_guest_context_any_t *ctx, int vcpu)
> {
> guest_word_t instr;
> @@ -874,6 +970,13 @@ static void dump_ctx(int vcpu)
> }
> #endif
>
> +#ifndef NO_TRANSLATION
> + if ( xenctx.do_memory )
> + {
> + print_mem(&ctx, vcpu, guest_word_size, xenctx.mem_addr);
> + return;
> + }
> +#endif
> print_ctx(&ctx);
> #ifndef NO_TRANSLATION
> if (print_code(&ctx, vcpu))
> @@ -928,13 +1031,21 @@ static void usage(void)
> printf(" add address on each line of Stack dump.\n");
> printf(" -T, --tag-call-trace\n");
> printf(" add address on each line of Call trace.\n");
> +#ifndef NO_TRANSLATION
> + printf(" -M maddr, --memory=maddr\n");
> + printf(" dump memory at maddr.\n");
> +#endif
> }
>
> int main(int argc, char **argv)
> {
> int ch;
> int ret;
> +#ifndef NO_TRANSLATION
> + static const char *sopts = "fs:hak:SCmb:l:DtTM:";
> +#else
> static const char *sopts = "fs:hak:SCmb:l:DtT";
> +#endif
> static const struct option lopts[] = {
> {"stack-trace", 0, NULL, 'S'},
> {"symbol-table", 1, NULL, 's'},
> @@ -944,6 +1055,9 @@ int main(int argc, char **argv)
> {"decode-as-ascii", 0, NULL, 'D'},
> {"tag-stack-dump", 0, NULL, 't'},
> {"tag-call-trace", 0, NULL, 'T'},
> +#ifndef NO_TRANSLATION
> + {"memory", 1, NULL, 'M'},
> +#endif
> {"bytes-per-line", 1, NULL, 'b'},
> {"lines", 1, NULL, 'l'},
> {"all", 0, NULL, 'a'},
> @@ -954,6 +1068,7 @@ int main(int argc, char **argv)
> const char *symbol_table = NULL;
>
> int vcpu = 0;
> + int do_default = 1;
>
> xenctx.bytes_per_line = 32;
> xenctx.lines = 5;
> @@ -1007,10 +1122,18 @@ int main(int argc, char **argv)
> break;
> case 'C':
> xenctx.all_vcpus = 1;
> + do_default = 0;
> break;
> case 'k':
> kernel_start = strtoull(optarg, NULL, 0);
> break;
> +#ifndef NO_TRANSLATION
> + case 'M':
> + xenctx.mem_addr = strtoull(optarg, NULL, 0);
> + xenctx.do_memory = 1;
> + do_default = 0;
> + break;
> +#endif
> case 'h':
> usage();
> exit(-1);
> @@ -1060,9 +1183,18 @@ int main(int argc, char **argv)
> xenctx.self_paused = 1;
> }
>
> +#ifndef NO_TRANSLATION
> + if ( xenctx.do_memory )
> + {
> + dump_ctx(vcpu);
> + if (xenctx.all_vcpus)
> + printf("\n");
> + }
> + xenctx.do_memory = 0;
> +#endif
> if (xenctx.all_vcpus)
> dump_all_vcpus();
> - else
> + if ( do_default )
> dump_ctx(vcpu);
So after this change, you can do "xenctx -M <addr>" and get memory,
"xenctx -C" and get vcpu info, or "xenctx -M <addr> -C" and get both;
but you can't get the ctx with both. Would it make sense to add an
option to explicitly request dump_ctx(), so that you could have any
combination? (And of course default to dump_ctx() if nothing is specified?)
-George
next prev parent reply other threads:[~2014-03-19 17:08 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-18 22:15 [PATCH v4 00/15] xenctx: Many changes Don Slutz
2014-03-18 22:15 ` [PATCH v4 01/15] xenctx: clean up usage output Don Slutz
2014-03-19 15:16 ` George Dunlap
2014-03-18 22:15 ` [PATCH v4 02/15] xenctx: Clean up stack trace when hypercall_page not in symbol table Don Slutz
2014-03-19 15:18 ` George Dunlap
2014-03-18 22:15 ` [PATCH v4 03/15] xenctx: Add -m (--multiple_pages) option to output larger stack Don Slutz
2014-03-19 15:34 ` George Dunlap
2014-03-20 1:19 ` Don Slutz
2014-03-20 10:52 ` George Dunlap
2014-03-18 22:15 ` [PATCH v4 04/15] xenctx: Add command line options -b and -l Don Slutz
2014-03-19 15:48 ` George Dunlap
2014-03-20 1:03 ` Don Slutz
2014-03-18 22:15 ` [PATCH v4 05/15] xenctx: Add command line option -D (--decode-as-ascii) Don Slutz
2014-03-19 16:09 ` George Dunlap
2014-03-20 0:57 ` Don Slutz
2014-03-18 22:15 ` [PATCH v4 06/15] xenctx: Add command line option -t (--tag-stack-dump) Don Slutz
2014-03-19 16:10 ` George Dunlap
2014-03-18 22:15 ` [PATCH v4 07/15] xenctx: Change print_symbol to do the space before Don Slutz
2014-03-19 16:12 ` George Dunlap
2014-03-18 22:15 ` [PATCH v4 08/15] xenctx: More info on failed to map page Don Slutz
2014-03-19 16:16 ` George Dunlap
2014-03-18 22:15 ` [PATCH v4 09/15] xenctx: Add command line option -T (--tag-call-trace) Don Slutz
2014-03-19 16:20 ` George Dunlap
2014-03-20 0:55 ` Don Slutz
2014-03-18 22:15 ` [PATCH v4 10/15] xenctx: Add -M <maddr> option to dump memory at maddr Don Slutz
2014-03-19 17:08 ` George Dunlap [this message]
2014-03-20 1:36 ` Don Slutz
2014-03-18 22:15 ` [PATCH v4 11/15] xenctx: Add -d <daddr> option to dump memory at daddr as a stack Don Slutz
2014-03-18 22:15 ` [PATCH v4 12/15] xenctx: change is_kernel_text() into kernel_addr() Don Slutz
2014-03-18 22:15 ` [PATCH v4 13/15] xenctx: Add convert of more registers to symbols Don Slutz
2014-03-19 8:30 ` Jan Beulich
2014-03-19 13:54 ` Don Slutz
2014-03-18 22:15 ` [PATCH v4 14/15] xenctx: Add output of vcpu value and state for --all-vcpus Don Slutz
2014-03-19 8:32 ` Jan Beulich
2014-03-19 13:36 ` Don Slutz
2014-03-18 22:15 ` [PATCH v4 15/15] xenctx: Fix handling of !guest_protected_mode Don Slutz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5329CEF1.9010603@eu.citrix.com \
--to=george.dunlap@eu.citrix.com \
--cc=Don@CloudSwitch.com \
--cc=dslutz@verizon.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).