All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.