* [PATCH v8 01/20] xenctx: clean up usage output
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-03-27 19:05 ` [PATCH v8 02/20] xenctx: Clean up stack trace when hypercall_page not in symbol table Don Slutz
` (18 subsequent siblings)
19 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
Fix usage formatting to be all the same.
Fix usage display of default --kernel-start for 64 bit.
Signed-off-by: Don Slutz <dslutz@verizon.com>
Reviewed-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/xentrace/xenctx.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 7275a00..97c6197 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -823,15 +823,16 @@ static void usage(void)
printf("options:\n");
printf(" -f, --frame-pointers\n");
- printf(" assume the kernel was compiled with\n");
- printf(" frame pointers.\n");
+ printf(" assume the kernel was compiled with\n");
+ printf(" frame pointers.\n");
printf(" -s SYMTAB, --symbol-table=SYMTAB\n");
- printf(" read symbol table from SYMTAB.\n");
- printf(" -S --stack-trace print a complete stack trace.\n");
- printf(" -k, --kernel-start\n");
- printf(" set user/kernel split. (default 0xc0000000)\n");
- printf(" -a --all display more registers\n");
- printf(" -C --all-vcpus print info for all vcpus\n");
+ printf(" read symbol table from SYMTAB.\n");
+ printf(" -S, --stack-trace print a complete stack trace.\n");
+ printf(" -k KADDR, --kernel-start=KADDR\n");
+ printf(" set user/kernel split. (default 0x"FMT_32B_WORD")\n",
+ kernel_start);
+ printf(" -a, --all display more registers\n");
+ printf(" -C, --all-vcpus print info for all vcpus\n");
}
int main(int argc, char **argv)
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 02/20] xenctx: Clean up stack trace when hypercall_page not in symbol table
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
2014-03-27 19:05 ` [PATCH v8 01/20] xenctx: clean up usage output Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-03-27 19:05 ` [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack Don Slutz
` (17 subsequent siblings)
19 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Jan Beulich
From: Don Slutz <Don@CloudSwitch.com>
Before:
Call Trace:
[<ffffffff8006b2b0>] default_idle+0x29 <--
[<ffffffff80048d19>] cpu_idle+0x95
[<ffffffff803e7801>] start_kernel+0x220
[<0000000000000000>] startup_64+0x80000000
[<ffffffff803e722f>] x86_64_start_kernel+0x22f
[<0000000000000000>] startup_64+0x80000000
[<0000000000000000>] startup_64+0x80000000
[<0000000000000000>] startup_64+0x80000000
[<0000000000000000>] startup_64+0x80000000
After:
Call Trace:
[<ffffffff8006b2b0>] default_idle+0x29 <--
[<ffffffff80048d19>] cpu_idle+0x95
[<ffffffff803e7801>] start_kernel+0x220
[<ffffffff803e722f>] x86_64_start_kernel+0x22f
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
tools/xentrace/xenctx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 97c6197..42a47f3 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -85,8 +85,9 @@ static int is_kernel_text(guest_word_t addr)
if (addr >= kernel_stext &&
addr <= kernel_etext)
return 1;
- if (addr >= kernel_hypercallpage &&
- addr <= kernel_hypercallpage + 4096)
+ if ( kernel_hypercallpage &&
+ (addr >= kernel_hypercallpage &&
+ addr <= kernel_hypercallpage + 4096) )
return 1;
if (addr >= kernel_sinittext &&
addr <= kernel_einittext)
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
2014-03-27 19:05 ` [PATCH v8 01/20] xenctx: clean up usage output Don Slutz
2014-03-27 19:05 ` [PATCH v8 02/20] xenctx: Clean up stack trace when hypercall_page not in symbol table Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 13:19 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 04/20] xenctx: Add command line options -b (--bytes-per-line) and -l (--lines) Don Slutz
` (16 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Don Slutz, Jan Beulich
Important: This is the stack size (also known as stack limit) to
display not the configured stack size.
Note: use with caution (easy to get garbage).
Below is a pictures of a configured 3 page stack, and where
the SP currently is. Each box is a page.
-n 1 -n 2 -n 3
+------------------+
| |
| |
| |
| |
SP --> | | * * *
+------------------+ | |
| | | |
| | | |
| | | |
| | | |
| | * |
+------------------+ |
| | |
| | |
| | |
| | |
| | *
+------------------+
Display using "-n 3" since the used stack pages is 3.
At a different time, the SP may be in the 1st page and so "-n 3"
will display garbage.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
v8:
Reworked comment.
multiple_pages => nr_stack_pages
Changed usage output.
Added range checking of option.
tools/xentrace/xenctx.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 42a47f3..dd84013 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -35,11 +35,14 @@ static struct xenctx {
int frame_ptrs;
int stack_trace;
int disp_all;
+ int nr_stack_pages;
int all_vcpus;
int self_paused;
xc_dominfo_t dominfo;
} xenctx;
+#define DEFAULT_NR_STACK_PAGES 1
+
#if defined (__i386__) || defined (__x86_64__)
typedef unsigned long long guest_word_t;
#define FMT_32B_WORD "%08llx"
@@ -664,6 +667,8 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
& ~((guest_word_t) XC_PAGE_SIZE - 1));
+ if ( xenctx.nr_stack_pages > 1 )
+ stack_limit += (xenctx.nr_stack_pages - 1) * XC_PAGE_SIZE;
printf("\n");
printf("Stack:\n");
for (i=1; i<5 && stack < stack_limit; i++) {
@@ -834,18 +839,24 @@ static void usage(void)
kernel_start);
printf(" -a, --all display more registers\n");
printf(" -C, --all-vcpus print info for all vcpus\n");
+ printf(" -n PAGES, --display-stack-pages=PAGES\n");
+ printf(" Display N pages from the stack pointer. (default %d)\n",
+ DEFAULT_NR_STACK_PAGES);
+ printf(" Changes stack limit. Note: use with caution (easy\n");
+ printf(" to get garbage).\n");
}
int main(int argc, char **argv)
{
int ch;
int ret;
- static const char *sopts = "fs:hak:SC";
+ static const char *sopts = "fs:hak:SCn:";
static const struct option lopts[] = {
{"stack-trace", 0, NULL, 'S'},
{"symbol-table", 1, NULL, 's'},
{"frame-pointers", 0, NULL, 'f'},
{"kernel-start", 1, NULL, 'k'},
+ {"display-stack-pages", 0, NULL, 'n'},
{"all", 0, NULL, 'a'},
{"all-vcpus", 0, NULL, 'C'},
{"help", 0, NULL, 'h'},
@@ -855,6 +866,8 @@ int main(int argc, char **argv)
int vcpu = 0;
+ xenctx.nr_stack_pages = DEFAULT_NR_STACK_PAGES;
+
while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
switch(ch) {
case 'f':
@@ -869,6 +882,16 @@ int main(int argc, char **argv)
case 'a':
xenctx.disp_all = 1;
break;
+ case 'n':
+ xenctx.nr_stack_pages = strtol(optarg, NULL, 0);
+ if ( xenctx.nr_stack_pages < 1)
+ {
+ fprintf(stderr,
+ "%s: Unsupported value(%d) for --display-stack-pages '%s'. Needs to be >= 1\n",
+ argv[0], xenctx.nr_stack_pages, optarg);
+ exit(-1);
+ }
+ break;
case 'C':
xenctx.all_vcpus = 1;
break;
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack
2014-03-27 19:05 ` [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack Don Slutz
@ 2014-04-01 13:19 ` Ian Campbell
2014-04-01 13:25 ` George Dunlap
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 13:19 UTC (permalink / raw)
To: Don Slutz
Cc: Stefano Stabellini, George Dunlap, Don Slutz, Ian Jackson,
xen-devel, Jan Beulich
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> Important: This is the stack size (also known as stack limit) to
> display not the configured stack size.
>
> Note: use with caution (easy to get garbage).
>
> Below is a pictures of a configured 3 page stack, and where
> the SP currently is. Each box is a page.
>
> -n 1 -n 2 -n 3
>
> +------------------+
> | |
> | |
> | |
> | |
> SP --> | | * * *
> +------------------+ | |
> | | | |
> | | | |
> | | | |
> | | | |
> | | * |
> +------------------+ |
> | | |
> | | |
> | | |
> | | |
> | | *
> +------------------+
>
> Display using "-n 3" since the used stack pages is 3.
Stacks grow downwards on all of the architectures we support. Perhaps
that is why the rest of us find your diagrams so confusing?
I drew my example to you the way I did for a reason.
Also, should the other end of the *---* line from SP (the bottom in your
diagram above) not be aligned to a page boundary, after all -n works in
pages.
> @@ -664,6 +667,8 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
>
> stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
> & ~((guest_word_t) XC_PAGE_SIZE - 1));
> + if ( xenctx.nr_stack_pages > 1 )
> + stack_limit += (xenctx.nr_stack_pages - 1) * XC_PAGE_SIZE;
The if here is still redundant.
> printf("\n");
> printf("Stack:\n");
> for (i=1; i<5 && stack < stack_limit; i++) {
> @@ -834,18 +839,24 @@ static void usage(void)
> kernel_start);
> printf(" -a, --all display more registers\n");
> printf(" -C, --all-vcpus print info for all vcpus\n");
> + printf(" -n PAGES, --display-stack-pages=PAGES\n");
> + printf(" Display N pages from the stack pointer. (default %d)\n",
> + DEFAULT_NR_STACK_PAGES);
> + printf(" Changes stack limit. Note: use with caution (easy\n");
> + printf(" to get garbage).\n");
Doesn't it go without saying that if you go off the bottom of the stack
you will get garbage?
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack
2014-04-01 13:19 ` Ian Campbell
@ 2014-04-01 13:25 ` George Dunlap
2014-04-01 20:28 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: George Dunlap @ 2014-04-01 13:25 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: Don Slutz, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/01/2014 02:19 PM, Ian Campbell wrote:
> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
>> Important: This is the stack size (also known as stack limit) to
>> display not the configured stack size.
>>
>> Note: use with caution (easy to get garbage).
>>
>> Below is a pictures of a configured 3 page stack, and where
>> the SP currently is. Each box is a page.
>>
>> -n 1 -n 2 -n 3
>>
>> +------------------+
>> | |
>> | |
>> | |
>> | |
>> SP --> | | * * *
>> +------------------+ | |
>> | | | |
>> | | | |
>> | | | |
>> | | | |
>> | | * |
>> +------------------+ |
>> | | |
>> | | |
>> | | |
>> | | |
>> | | *
>> +------------------+
>>
>> Display using "-n 3" since the used stack pages is 3.
>
> Stacks grow downwards on all of the architectures we support. Perhaps
> that is why the rest of us find your diagrams so confusing?
>
> I drew my example to you the way I did for a reason.
>
> Also, should the other end of the *---* line from SP (the bottom in your
> diagram above) not be aligned to a page boundary, after all -n works in
> pages.
>
>
>> @@ -664,6 +667,8 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
>>
>> stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
>> & ~((guest_word_t) XC_PAGE_SIZE - 1));
>> + if ( xenctx.nr_stack_pages > 1 )
>> + stack_limit += (xenctx.nr_stack_pages - 1) * XC_PAGE_SIZE;
>
> The if here is still redundant.
>
>> printf("\n");
>> printf("Stack:\n");
>> for (i=1; i<5 && stack < stack_limit; i++) {
>> @@ -834,18 +839,24 @@ static void usage(void)
>> kernel_start);
>> printf(" -a, --all display more registers\n");
>> printf(" -C, --all-vcpus print info for all vcpus\n");
>> + printf(" -n PAGES, --display-stack-pages=PAGES\n");
>> + printf(" Display N pages from the stack pointer. (default %d)\n",
>> + DEFAULT_NR_STACK_PAGES);
>> + printf(" Changes stack limit. Note: use with caution (easy\n");
>> + printf(" to get garbage).\n");
>
> Doesn't it go without saying that if you go off the bottom of the stack
> you will get garbage?
Only if you know that the tool doesn't know where the end of the stack
is. (Although hopefully the wording, "Display N pages" should give you
a hint.)
But what is "changes stack limit" supposed to mean?
-George
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack
2014-04-01 13:25 ` George Dunlap
@ 2014-04-01 20:28 ` Don Slutz
2014-04-02 10:39 ` Ian Campbell
0 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-04-01 20:28 UTC (permalink / raw)
To: George Dunlap, Ian Campbell, Don Slutz
Cc: Don Slutz, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/01/14 09:25, George Dunlap wrote:
> On 04/01/2014 02:19 PM, Ian Campbell wrote:
>> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
>>> Important: This is the stack size (also known as stack limit) to
>>> display not the configured stack size.
>>>
>>> Note: use with caution (easy to get garbage).
>>>
>>> Below is a pictures of a configured 3 page stack, and where
>>> the SP currently is. Each box is a page.
>>>
>>> -n 1 -n 2 -n 3
>>>
>>> +------------------+
>>> | |
>>> | |
>>> | |
>>> | |
>>> SP --> | | * * *
>>> +------------------+ | |
>>> | | | |
>>> | | | |
>>> | | | |
>>> | | | |
>>> | | * |
>>> +------------------+ |
>>> | | |
>>> | | |
>>> | | |
>>> | | |
>>> | | *
>>> +------------------+
>>>
>>> Display using "-n 3" since the used stack pages is 3.
>>
>> Stacks grow downwards on all of the architectures we support. Perhaps
>> that is why the rest of us find your diagrams so confusing?
>>
I expect so. I can flip the picture (and add relative address) to help. I was basing
the layout to match the stack output:
Call Trace:
[<ffffffff81346898>] io_serial_out+0x18 <--
ffff880032bb1310: [<ffffffff81346f51>] serial8250_console_putchar+0x31
ffff880032bb1330: [<ffffffff813428de>] uart_console_write+0x3e
ffff880032bb1338: [<ffffffff8100bc0e>] apic_timer_interrupt+0xe
ffff880032bb1370: [<ffffffff813472ad>] serial8250_console_write+0xbd
ffff880032bb13c0: [<ffffffff8106b8f5>] __call_console_drivers+0x75
ffff880032bb13f0: [<ffffffff8106b95a>] _call_console_drivers+0x4a
ffff880032bb1410: [<ffffffff8106be6e>] release_console_sem+0x4e
ffff880032bb1450: [<ffffffff8106c628>] vprintk+0x248
ffff880032bb14f0: [<ffffffff814fd363>] printk+0x41
ffff880032bb3f20: [<ffffffff8100204c>] do_one_initcall+0x3c
ffff880032bb3f50: [<ffffffff810b0eb1>] sys_init_module+0xe1
ffff880032bb3f80: [<ffffffff8100b0f2>] system_call_fastpath+0x16
Adding (my) boxes (note not fully to scale):
+------------------------------------------------------------------------------+
| |
| |
| |
| |
| |
| |
| [<ffffffff81346898>] io_serial_out+0x18 <-- |
SP->| ffff880032bb1310: [<ffffffff81346f51>] serial8250_console_putchar+0x31 |
| ffff880032bb1330: [<ffffffff813428de>] uart_console_write+0x3e |
| ffff880032bb1338: [<ffffffff8100bc0e>] apic_timer_interrupt+0xe |
| ffff880032bb1370: [<ffffffff813472ad>] serial8250_console_write+0xbd |
| ffff880032bb13c0: [<ffffffff8106b8f5>] __call_console_drivers+0x75 |
| ffff880032bb13f0: [<ffffffff8106b95a>] _call_console_drivers+0x4a |
| ffff880032bb1410: [<ffffffff8106be6e>] release_console_sem+0x4e |
| ffff880032bb1450: [<ffffffff8106c628>] vprintk+0x248 |
| ffff880032bb14f0: [<ffffffff814fd363>] printk+0x41 |
| |
| |
| |
+------------------------------------------------------------------------------+
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+------------------------------------------------------------------------------+
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ffff880032bb3f20: [<ffffffff8100204c>] do_one_initcall+0x3c |
| ffff880032bb3f50: [<ffffffff810b0eb1>] sys_init_module+0xe1 |
| ffff880032bb3f80: [<ffffffff8100b0f2>] system_call_fastpath+0x16 |
| |
+------------------------------------------------------------------------------+
>> I drew my example to you the way I did for a reason.
>>
Sorry, I did not notice that.
>> Also, should the other end of the *---* line from SP (the bottom in your
>> diagram above) not be aligned to a page boundary, after all -n works in
>> pages.
>>
I am happy to do it either way. I think of the page breaks to not be part of memory.
>>
>>> @@ -664,6 +667,8 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
>>>
>>> stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
>>> & ~((guest_word_t) XC_PAGE_SIZE - 1));
>>> + if ( xenctx.nr_stack_pages > 1 )
>>> + stack_limit += (xenctx.nr_stack_pages - 1) * XC_PAGE_SIZE;
>>
>> The if here is still redundant.
>>
Will drop.
>>> printf("\n");
>>> printf("Stack:\n");
>>> for (i=1; i<5 && stack < stack_limit; i++) {
>>> @@ -834,18 +839,24 @@ static void usage(void)
>>> kernel_start);
>>> printf(" -a, --all display more registers\n");
>>> printf(" -C, --all-vcpus print info for all vcpus\n");
>>> + printf(" -n PAGES, --display-stack-pages=PAGES\n");
>>> + printf(" Display N pages from the stack pointer. (default %d)\n",
>>> + DEFAULT_NR_STACK_PAGES);
>>> + printf(" Changes stack limit. Note: use with caution (easy\n");
>>> + printf(" to get garbage).\n");
>>
>> Doesn't it go without saying that if you go off the bottom of the stack
>> you will get garbage?
>
> Only if you know that the tool doesn't know where the end of the stack is. (Although hopefully the wording, "Display N pages" should give you a hint.)
>
> But what is "changes stack limit" supposed to mean?
>
Partly it is used in the next patch's usage output:
-l <lines>, --lines <lines>
change the number of lines output for Stack. (default 5)
Can be specified as MAX. Note: Fewer lines will be output
if stack limit reached.
And it was the best term I know of to say in a few words:
The output of stack starts at the current SP and stops when the
end of N page(s) is/are reached.
-Don Slutz
> -George
>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack
2014-04-01 20:28 ` Don Slutz
@ 2014-04-02 10:39 ` Ian Campbell
0 siblings, 0 replies; 50+ messages in thread
From: Ian Campbell @ 2014-04-02 10:39 UTC (permalink / raw)
To: Don Slutz
Cc: Stefano Stabellini, George Dunlap, Don Slutz, Ian Jackson,
xen-devel, Jan Beulich
On Tue, 2014-04-01 at 16:28 -0400, Don Slutz wrote:
> On 04/01/14 09:25, George Dunlap wrote:
> > On 04/01/2014 02:19 PM, Ian Campbell wrote:
> >> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> >>> Important: This is the stack size (also known as stack limit) to
> >>> display not the configured stack size.
> >>>
> >>> Note: use with caution (easy to get garbage).
> >>>
> >>> Below is a pictures of a configured 3 page stack, and where
> >>> the SP currently is. Each box is a page.
> >>>
> >>> -n 1 -n 2 -n 3
> >>>
> >>> +------------------+
> >>> | |
> >>> | |
> >>> | |
> >>> | |
> >>> SP --> | | * * *
> >>> +------------------+ | |
> >>> | | | |
> >>> | | | |
> >>> | | | |
> >>> | | | |
> >>> | | * |
> >>> +------------------+ |
> >>> | | |
> >>> | | |
> >>> | | |
> >>> | | |
> >>> | | *
> >>> +------------------+
> >>>
> >>> Display using "-n 3" since the used stack pages is 3.
> >>
> >> Stacks grow downwards on all of the architectures we support. Perhaps
> >> that is why the rest of us find your diagrams so confusing?
> >>
>
> I expect so. I can flip the picture (and add relative address) to help. I was basing
> the layout to match the stack output:
The reality is that the layout does not match the stack output, but you
are using terms like "stack pages" which lead people to expect things in
terms of the layout in memory pages.
>
> Call Trace:
> [<ffffffff81346898>] io_serial_out+0x18 <--
> ffff880032bb1310: [<ffffffff81346f51>] serial8250_console_putchar+0x31
> ffff880032bb1330: [<ffffffff813428de>] uart_console_write+0x3e
> ffff880032bb1338: [<ffffffff8100bc0e>] apic_timer_interrupt+0xe
> ffff880032bb1370: [<ffffffff813472ad>] serial8250_console_write+0xbd
> ffff880032bb13c0: [<ffffffff8106b8f5>] __call_console_drivers+0x75
> ffff880032bb13f0: [<ffffffff8106b95a>] _call_console_drivers+0x4a
> ffff880032bb1410: [<ffffffff8106be6e>] release_console_sem+0x4e
> ffff880032bb1450: [<ffffffff8106c628>] vprintk+0x248
> ffff880032bb14f0: [<ffffffff814fd363>] printk+0x41
> ffff880032bb3f20: [<ffffffff8100204c>] do_one_initcall+0x3c
> ffff880032bb3f50: [<ffffffff810b0eb1>] sys_init_module+0xe1
> ffff880032bb3f80: [<ffffffff8100b0f2>] system_call_fastpath+0x16
>
> Adding (my) boxes (note not fully to scale):
Oh come on, how do you think that is useful?
>
> >> Also, should the other end of the *---* line from SP (the bottom in your
> >> diagram above) not be aligned to a page boundary, after all -n works in
> >> pages.
> >>
>
> I am happy to do it either way. I think of the page breaks to not be part of memory.
Oh I see, the ending * is just before the boundary.
I think you should move the SP into the middle of the page, otherwise
under your way of displaying it it seems like the 1-page case has no
contents.
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 04/20] xenctx: Add command line options -b (--bytes-per-line) and -l (--lines)
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (2 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 03/20] xenctx: Add -n (--display-stack-pages) option to output larger stack Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:30 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 05/20] xenctx: Add command line option -D (--decode-as-ascii) Don Slutz
` (15 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
-b <bytes>, --bytes-per-line <bytes>
change the number of bytes per line output for Stack.
(default 32) Note: rounded to native size (4 or 8 bytes).
This option allows you to change the width of the output line. When
used with the -D option and/or -t, the output can be adjusted with
this to less then 80 columns.
-l <lines>, --lines <lines>
change the number of lines output for Stack. (default 5)
Can be specified as MAX. Note: Fewer lines will be output
if stack limit reached.
The default value show a reasonable amount of the raw stack. The -S
option will output all of it one line at a time. This can be used
to select something in the middle.
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v8:
Commit message adjusted.
More CODING_STYLE changes.
INT_MAX was too big.
tools/xentrace/xenctx.c | 79 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 67 insertions(+), 12 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index dd84013..ebd28c6 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
+#include <limits.h>
#include "xenctrl.h"
#include <xen/foreign/x86_32.h>
@@ -36,12 +37,16 @@ static struct xenctx {
int stack_trace;
int disp_all;
int nr_stack_pages;
+ int bytes_per_line;
+ int lines;
int all_vcpus;
int self_paused;
xc_dominfo_t dominfo;
} xenctx;
#define DEFAULT_NR_STACK_PAGES 1
+#define DEFAULT_BYTES_PER_LINE 32
+#define DEFAULT_LINES 5
#if defined (__i386__) || defined (__x86_64__)
typedef unsigned long long guest_word_t;
@@ -64,6 +69,8 @@ typedef uint64_t guest_word_t;
#define FMT_64B_WORD "%016lx"
#endif
+#define MAX_BYTES_PER_LINE 128
+
struct symbol {
guest_word_t address;
char *name;
@@ -665,25 +672,34 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
guest_word_t *p;
int i;
+ if ( width )
+ xenctx.bytes_per_line =
+ ((xenctx.bytes_per_line + width - 1) / width) * width;
stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
& ~((guest_word_t) XC_PAGE_SIZE - 1));
if ( xenctx.nr_stack_pages > 1 )
stack_limit += (xenctx.nr_stack_pages - 1) * XC_PAGE_SIZE;
printf("\n");
- printf("Stack:\n");
- for (i=1; i<5 && stack < stack_limit; i++) {
- while(stack < stack_limit && stack < stack_pointer(ctx) + i*32) {
- p = map_page(ctx, vcpu, stack);
- if (!p)
- return -1;
- word = read_stack_word(p, width);
- printf(" ");
- print_stack_word(word, width);
- stack += width;
+ if ( xenctx.lines )
+ {
+ printf("Stack:\n");
+ for (i = 1; i < xenctx.lines + 1 && stack < stack_limit; i++)
+ {
+ while ( stack < stack_limit &&
+ stack < stack_pointer(ctx) + i * xenctx.bytes_per_line )
+ {
+ p = map_page(ctx, vcpu, stack);
+ if ( !p )
+ return -1;
+ word = read_stack_word(p, width);
+ printf(" ");
+ print_stack_word(word, width);
+ stack += width;
+ }
+ printf("\n");
}
printf("\n");
}
- printf("\n");
if(xenctx.stack_trace)
printf("Stack Trace:\n");
@@ -844,19 +860,30 @@ static void usage(void)
DEFAULT_NR_STACK_PAGES);
printf(" Changes stack limit. Note: use with caution (easy\n");
printf(" to get garbage).\n");
+ printf(" -b <bytes>, --bytes-per-line <bytes>\n");
+ printf(" change the number of bytes per line output for Stack.\n");
+ printf(" (default %d) Note: rounded to native size (4 or 8 bytes).\n",
+ DEFAULT_BYTES_PER_LINE);
+ printf(" -l <lines>, --lines <lines>\n");
+ printf(" change the number of lines output for Stack. (default %d)\n",
+ DEFAULT_LINES);
+ printf(" Can be specified as MAX. Note: Fewer lines will be output\n");
+ printf(" if stack limit reached.\n");
}
int main(int argc, char **argv)
{
int ch;
int ret;
- static const char *sopts = "fs:hak:SCn:";
+ static const char *sopts = "fs:hak:SCn:b:l:";
static const struct option lopts[] = {
{"stack-trace", 0, NULL, 'S'},
{"symbol-table", 1, NULL, 's'},
{"frame-pointers", 0, NULL, 'f'},
{"kernel-start", 1, NULL, 'k'},
{"display-stack-pages", 0, NULL, 'n'},
+ {"bytes-per-line", 1, NULL, 'b'},
+ {"lines", 1, NULL, 'l'},
{"all", 0, NULL, 'a'},
{"all-vcpus", 0, NULL, 'C'},
{"help", 0, NULL, 'h'},
@@ -866,6 +893,8 @@ int main(int argc, char **argv)
int vcpu = 0;
+ xenctx.bytes_per_line = DEFAULT_BYTES_PER_LINE;
+ xenctx.lines = DEFAULT_LINES;
xenctx.nr_stack_pages = DEFAULT_NR_STACK_PAGES;
while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
@@ -892,6 +921,32 @@ int main(int argc, char **argv)
exit(-1);
}
break;
+ case 'b':
+ xenctx.bytes_per_line = strtol(optarg, NULL, 0);
+ if ( xenctx.bytes_per_line < 4 ||
+ xenctx.bytes_per_line > MAX_BYTES_PER_LINE )
+ {
+ fprintf(stderr,
+ "%s: Unsupported value for --bytes-per-line '%s'. Needs to be 4 <= %d <= %d\n",
+ argv[0], optarg, xenctx.bytes_per_line,
+ MAX_BYTES_PER_LINE);
+ exit(-1);
+ }
+ break;
+ case 'l':
+ if ( !strcmp(optarg, "all") || !strcmp(optarg, "ALL") ||
+ !strcmp(optarg, "max") || !strcmp(optarg, "MAX") )
+ xenctx.lines = INT_MAX - 1;
+ else
+ xenctx.lines = strtol(optarg, NULL, 0);
+ if ( xenctx.lines < 0 || xenctx.lines == INT_MAX)
+ {
+ fprintf(stderr,
+ "%s: Unsupported value(%d) for --lines '%s'. Needs to be >= 0, < %d\n",
+ argv[0], xenctx.lines, optarg, INT_MAX);
+ exit(-1);
+ }
+ break;
case 'C':
xenctx.all_vcpus = 1;
break;
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 04/20] xenctx: Add command line options -b (--bytes-per-line) and -l (--lines)
2014-03-27 19:05 ` [PATCH v8 04/20] xenctx: Add command line options -b (--bytes-per-line) and -l (--lines) Don Slutz
@ 2014-04-01 14:30 ` Ian Campbell
0 siblings, 0 replies; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 14:30 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> -b <bytes>, --bytes-per-line <bytes>
> change the number of bytes per line output for Stack.
> (default 32) Note: rounded to native size (4 or 8 bytes).
>
> This option allows you to change the width of the output line. When
> used with the -D option and/or -t, the output can be adjusted with
> this to less then 80 columns.
>
> -l <lines>, --lines <lines>
> change the number of lines output for Stack. (default 5)
> Can be specified as MAX. Note: Fewer lines will be output
> if stack limit reached.
>
> The default value show a reasonable amount of the raw stack. The -S
> option will output all of it one line at a time. This can be used
> to select something in the middle.
>
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 05/20] xenctx: Add command line option -D (--decode-as-ascii)
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (3 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 04/20] xenctx: Add command line options -b (--bytes-per-line) and -l (--lines) Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 13:27 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 06/20] xenctx: Add command line option -t (--tag-stack-dump) Don Slutz
` (14 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Don Slutz, Jan Beulich
If specified, output ascii version of stack also.
This is not the default because the result exceeds 80 characters per line.
Here is an example:
Stack:
ffffffff80048d19 0000000000200800 ffffffff803e7801 0000000000086800 .......... ......x>......h......
0000000000000000 ffffffff80430720 ffffffff803e722f 80008e000010019c ........ .C...../r>.............
00000000ffffffff 0000000000000000 0000000000000000 0000000000200000 .......................... .....
0000000000000000 0000000000000000 ................
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
v8: Add "...exceeds 80 characters..." to commit message
tools/xentrace/xenctx.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index ebd28c6..2649f2f 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -39,6 +39,7 @@ static struct xenctx {
int nr_stack_pages;
int bytes_per_line;
int lines;
+ int decode_as_ascii;
int all_vcpus;
int self_paused;
xc_dominfo_t dominfo;
@@ -670,6 +671,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
guest_word_t frame;
guest_word_t word;
guest_word_t *p;
+ guest_word_t ascii[MAX_BYTES_PER_LINE/4];
int i;
if ( width )
@@ -685,6 +687,9 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
printf("Stack:\n");
for (i = 1; i < xenctx.lines + 1 && stack < stack_limit; i++)
{
+ int j = 0;
+ int k;
+
while ( stack < stack_limit &&
stack < stack_pointer(ctx) + i * xenctx.bytes_per_line )
{
@@ -692,10 +697,36 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
if ( !p )
return -1;
word = read_stack_word(p, width);
+ if ( xenctx.decode_as_ascii )
+ ascii[j++] = word;
printf(" ");
print_stack_word(word, width);
stack += width;
}
+ if ( xenctx.decode_as_ascii )
+ {
+ /*
+ * Line up ascii output if less than bytes_per_line
+ * were printed.
+ */
+ for (k = j; k < xenctx.bytes_per_line / width; k++)
+ printf(" %*s", width * 2, "");
+ printf(" ");
+ for (k = 0; k < j; k++)
+ {
+ int l;
+ unsigned char *bytep = (unsigned char *)&ascii[k];
+
+ for (l = 0; l < width; l++)
+ {
+ if (isprint(*bytep))
+ printf("%c", *bytep);
+ else
+ printf(".");
+ bytep++;
+ }
+ }
+ }
printf("\n");
}
printf("\n");
@@ -869,19 +900,22 @@ static void usage(void)
DEFAULT_LINES);
printf(" Can be specified as MAX. Note: Fewer lines will be output\n");
printf(" if stack limit reached.\n");
+ printf(" -D, --decode-as-ascii\n");
+ printf(" add a decode of Stack dump as ascii.\n");
}
int main(int argc, char **argv)
{
int ch;
int ret;
- static const char *sopts = "fs:hak:SCn:b:l:";
+ static const char *sopts = "fs:hak:SCn:b:l:D";
static const struct option lopts[] = {
{"stack-trace", 0, NULL, 'S'},
{"symbol-table", 1, NULL, 's'},
{"frame-pointers", 0, NULL, 'f'},
{"kernel-start", 1, NULL, 'k'},
{"display-stack-pages", 0, NULL, 'n'},
+ {"decode-as-ascii", 0, NULL, 'D'},
{"bytes-per-line", 1, NULL, 'b'},
{"lines", 1, NULL, 'l'},
{"all", 0, NULL, 'a'},
@@ -921,6 +955,9 @@ int main(int argc, char **argv)
exit(-1);
}
break;
+ case 'D':
+ xenctx.decode_as_ascii = 1;
+ break;
case 'b':
xenctx.bytes_per_line = strtol(optarg, NULL, 0);
if ( xenctx.bytes_per_line < 4 ||
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 05/20] xenctx: Add command line option -D (--decode-as-ascii)
2014-03-27 19:05 ` [PATCH v8 05/20] xenctx: Add command line option -D (--decode-as-ascii) Don Slutz
@ 2014-04-01 13:27 ` Ian Campbell
0 siblings, 0 replies; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 13:27 UTC (permalink / raw)
To: Don Slutz
Cc: Stefano Stabellini, George Dunlap, Don Slutz, Ian Jackson,
xen-devel, Jan Beulich
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> If specified, output ascii version of stack also.
>
> This is not the default because the result exceeds 80 characters per line.
>
> Here is an example:
>
> Stack:
> ffffffff80048d19 0000000000200800 ffffffff803e7801 0000000000086800 .......... ......x>......h......
> 0000000000000000 ffffffff80430720 ffffffff803e722f 80008e000010019c ........ .C...../r>.............
> 00000000ffffffff 0000000000000000 0000000000000000 0000000000200000 .......................... .....
> 0000000000000000 0000000000000000 ................
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 06/20] xenctx: Add command line option -t (--tag-stack-dump)
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (4 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 05/20] xenctx: Add command line option -D (--decode-as-ascii) Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-03-27 19:05 ` [PATCH v8 07/20] xenctx: Change print_symbol to do the space before Don Slutz
` (13 subsequent siblings)
19 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Don Slutz, Jan Beulich
If specified, add stack address to dump.
This is not the default because the result exceeds 80 characters per line.
Here is an example:
Stack:
ffffffff803ddf90: ffffffff80048d19 0000000000200800 ffffffff803e7801 0000000000086800
ffffffff803ddfb0: 0000000000000000 ffffffff80430720 ffffffff803e722f 80008e000010019c
ffffffff803ddfd0: 00000000ffffffff 0000000000000000 0000000000000000 0000000000200000
ffffffff803ddff0: 0000000000000000 0000000000000000
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Reviewed-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
v8: Add "...exceeds 80 characters..." to commit message
tools/xentrace/xenctx.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 2649f2f..ec3b653 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -40,6 +40,7 @@ static struct xenctx {
int bytes_per_line;
int lines;
int decode_as_ascii;
+ int tag_stack_dump;
int all_vcpus;
int self_paused;
xc_dominfo_t dominfo;
@@ -690,6 +691,11 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
int j = 0;
int k;
+ if ( xenctx.tag_stack_dump )
+ {
+ print_stack_word(stack, width);
+ printf(":");
+ }
while ( stack < stack_limit &&
stack < stack_pointer(ctx) + i * xenctx.bytes_per_line )
{
@@ -902,13 +908,15 @@ static void usage(void)
printf(" if stack limit reached.\n");
printf(" -D, --decode-as-ascii\n");
printf(" add a decode of Stack dump as ascii.\n");
+ printf(" -t, --tag-stack-dump\n");
+ printf(" add address on each line of Stack dump.\n");
}
int main(int argc, char **argv)
{
int ch;
int ret;
- static const char *sopts = "fs:hak:SCn:b:l:D";
+ static const char *sopts = "fs:hak:SCn:b:l:Dt";
static const struct option lopts[] = {
{"stack-trace", 0, NULL, 'S'},
{"symbol-table", 1, NULL, 's'},
@@ -916,6 +924,7 @@ int main(int argc, char **argv)
{"kernel-start", 1, NULL, 'k'},
{"display-stack-pages", 0, NULL, 'n'},
{"decode-as-ascii", 0, NULL, 'D'},
+ {"tag-stack-dump", 0, NULL, 't'},
{"bytes-per-line", 1, NULL, 'b'},
{"lines", 1, NULL, 'l'},
{"all", 0, NULL, 'a'},
@@ -958,6 +967,9 @@ int main(int argc, char **argv)
case 'D':
xenctx.decode_as_ascii = 1;
break;
+ case 't':
+ xenctx.tag_stack_dump = 1;
+ break;
case 'b':
xenctx.bytes_per_line = strtol(optarg, NULL, 0);
if ( xenctx.bytes_per_line < 4 ||
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 07/20] xenctx: Change print_symbol to do the space before.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (5 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 06/20] xenctx: Add command line option -t (--tag-stack-dump) Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-03-27 19:05 ` [PATCH v8 08/20] xenctx: More info on failed to map page Don Slutz
` (12 subsequent siblings)
19 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Jan Beulich
From: Don Slutz <Don@CloudSwitch.com>
This stops the output of an extra space at the end of the line.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
tools/xentrace/xenctx.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index ec3b653..30f8f2c 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -171,9 +171,9 @@ static void print_symbol(guest_word_t addr)
return;
if (addr==s->address)
- printf("%s ", s->name);
+ printf(" %s", s->name);
else
- printf("%s+%#x ", s->name, (unsigned int)(addr - s->address));
+ printf(" %s+%#x", s->name, (unsigned int)(addr - s->address));
}
static void read_symbol_table(const char *symtab)
@@ -312,7 +312,7 @@ static void print_ctx_32(vcpu_guest_context_x86_32_t *ctx)
{
struct cpu_user_regs_x86_32 *regs = &ctx->user_regs;
- printf("cs:eip: %04x:%08x ", regs->cs, regs->eip);
+ printf("cs:eip: %04x:%08x", regs->cs, regs->eip);
print_symbol(regs->eip);
print_flags(regs->eflags);
printf("ss:esp: %04x:%08x\n", regs->ss, regs->esp);
@@ -341,7 +341,7 @@ static void print_ctx_32on64(vcpu_guest_context_x86_64_t *ctx)
{
struct cpu_user_regs_x86_64 *regs = &ctx->user_regs;
- printf("cs:eip: %04x:%08x ", regs->cs, (uint32_t)regs->eip);
+ printf("cs:eip: %04x:%08x", regs->cs, (uint32_t)regs->eip);
print_symbol((uint32_t)regs->eip);
print_flags((uint32_t)regs->eflags);
printf("ss:esp: %04x:%08x\n", regs->ss, (uint32_t)regs->esp);
@@ -370,7 +370,7 @@ static void print_ctx_64(vcpu_guest_context_x86_64_t *ctx)
{
struct cpu_user_regs_x86_64 *regs = &ctx->user_regs;
- printf("rip: %016"PRIx64" ", regs->rip);
+ printf("rip: %016"PRIx64, regs->rip);
print_symbol(regs->rip);
print_flags(regs->rflags);
printf("rsp: %016"PRIx64"\n", regs->rsp);
@@ -468,7 +468,7 @@ static void print_ctx_32(vcpu_guest_context_t *ctx)
{
vcpu_guest_core_regs_t *regs = &ctx->user_regs;
- printf("PC: %08"PRIx32" ", regs->pc32);
+ printf("PC: %08"PRIx32, regs->pc32);
print_symbol(regs->pc32);
printf("\n");
printf("CPSR: %08"PRIx32"\n", regs->cpsr);
@@ -520,7 +520,7 @@ static void print_ctx_64(vcpu_guest_context_t *ctx)
{
vcpu_guest_core_regs_t *regs = &ctx->user_regs;
- printf("PC: %016"PRIx64" ", regs->pc64);
+ printf("PC: %016"PRIx64, regs->pc64);
print_symbol(regs->pc64);
printf("\n");
@@ -744,7 +744,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
printf("Call Trace:\n");
printf("%c [<", xenctx.stack_trace ? '*' : ' ');
print_stack_word(instr_pointer(ctx), width);
- printf(">] ");
+ printf(">]");
print_symbol(instr_pointer(ctx));
printf(" <--\n");
@@ -784,7 +784,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
word = read_stack_word(p, width);
printf("%c [<", xenctx.stack_trace ? '|' : ' ');
print_stack_word(word, width);
- printf(">] ");
+ printf(">]");
print_symbol(word);
printf("\n");
stack += width;
@@ -800,7 +800,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
if (is_kernel_text(word)) {
printf(" [<");
print_stack_word(word, width);
- printf(">] ");
+ printf(">]");
print_symbol(word);
printf("\n");
} else if (xenctx.stack_trace) {
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 08/20] xenctx: More info on failed to map page.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (6 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 07/20] xenctx: Change print_symbol to do the space before Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-03-27 19:05 ` [PATCH v8 09/20] xenctx: Add output of stack address to Call and Stack Trace Don Slutz
` (11 subsequent siblings)
19 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Jan Beulich
From: Don Slutz <Don@CloudSwitch.com>
Also output an extra new line since we may be in the middle of output.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
tools/xentrace/xenctx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 30f8f2c..1637348 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -618,7 +618,7 @@ static void *map_page(vcpu_guest_context_any_t *ctx, int vcpu, guest_word_t virt
mapped = xc_map_foreign_range(xenctx.xc_handle, xenctx.domid, XC_PAGE_SIZE, PROT_READ, mfn);
if (mapped == NULL) {
- fprintf(stderr, "failed to map page.\n");
+ fprintf(stderr, "\nfailed to map page for "FMT_32B_WORD".\n", virt);
return NULL;
}
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 09/20] xenctx: Add output of stack address to Call and Stack Trace.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (7 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 08/20] xenctx: More info on failed to map page Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 13:28 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 10/20] xenctx: Add -m (--memory) <maddr> option to dump memory at maddr Don Slutz
` (10 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Don Slutz, Jan Beulich
Here is an example:
Call Trace:
[<ffffffff8006b2b0>] default_idle+0x29 <--
ffffffff803ddf90: [<ffffffff80048d19>] cpu_idle+0x95
ffffffff803ddfa0: [<ffffffff803e7801>] start_kernel+0x220
ffffffff803ddfc0: [<ffffffff803e722f>] x86_64_start_kernel+0x22f
and
Stack Trace:
* [<ffffffff8006b2b0>] default_idle+0x29 <--
ffffffff803ddf90: [<ffffffff80048d19>] cpu_idle+0x95
ffffffff803ddf98: 0000000000200800
ffffffff803ddfa0: [<ffffffff803e7801>] start_kernel+0x220
ffffffff803ddfa8: 0000000000086800
ffffffff803ddfb0: 0000000000000000
ffffffff803ddfb8: ffffffff80430720
ffffffff803ddfc0: [<ffffffff803e722f>] x86_64_start_kernel+0x22f
ffffffff803ddfc8: 80008e000010019c
ffffffff803ddfd0: 00000000ffffffff
ffffffff803ddfd8: 0000000000000000
ffffffff803ddfe0: 0000000000000000
ffffffff803ddfe8: 0000000000200000
ffffffff803ddff0: 0000000000000000
ffffffff803ddff8: 0000000000000000
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
v8:
Change subject from: xenctx: Add command line option -T (--tag-trace)
Drop option.
Add new routine: print_stack_addr
tools/xentrace/xenctx.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 1637348..0c16ec8 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -665,6 +665,12 @@ static int print_code(vcpu_guest_context_any_t *ctx, int vcpu)
return 0;
}
+static void print_stack_addr(guest_word_t addr, int width)
+{
+ print_stack_word(addr, width);
+ printf(": ");
+}
+
static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
{
guest_word_t stack = stack_pointer(ctx);
@@ -742,7 +748,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
printf("Stack Trace:\n");
else
printf("Call Trace:\n");
- printf("%c [<", xenctx.stack_trace ? '*' : ' ');
+ printf("%*s %c [<", width*2, "", xenctx.stack_trace ? '*' : ' ');
print_stack_word(instr_pointer(ctx), width);
printf(">]");
@@ -757,9 +763,10 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
p = map_page(ctx, vcpu, stack);
if (!p)
return -1;
+ print_stack_addr(stack, width);
printf("| ");
print_stack_word(read_stack_word(p, width), width);
- printf(" \n");
+ printf("\n");
stack += width;
}
} else {
@@ -771,6 +778,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
return -1;
frame = read_stack_word(p, width);
if (xenctx.stack_trace) {
+ print_stack_addr(stack, width);
printf("|-- ");
print_stack_word(read_stack_word(p, width), width);
printf("\n");
@@ -782,6 +790,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
if (!p)
return -1;
word = read_stack_word(p, width);
+ print_stack_addr(stack, width);
printf("%c [<", xenctx.stack_trace ? '|' : ' ');
print_stack_word(word, width);
printf(">]");
@@ -798,12 +807,14 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
return -1;
word = read_stack_word(p, width);
if (is_kernel_text(word)) {
+ print_stack_addr(stack, width);
printf(" [<");
print_stack_word(word, width);
printf(">]");
print_symbol(word);
printf("\n");
} else if (xenctx.stack_trace) {
+ print_stack_addr(stack, width);
printf(" ");
print_stack_word(word, width);
printf("\n");
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 09/20] xenctx: Add output of stack address to Call and Stack Trace.
2014-03-27 19:05 ` [PATCH v8 09/20] xenctx: Add output of stack address to Call and Stack Trace Don Slutz
@ 2014-04-01 13:28 ` Ian Campbell
0 siblings, 0 replies; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 13:28 UTC (permalink / raw)
To: Don Slutz
Cc: Stefano Stabellini, George Dunlap, Don Slutz, Ian Jackson,
xen-devel, Jan Beulich
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> Here is an example:
>
> Call Trace:
> [<ffffffff8006b2b0>] default_idle+0x29 <--
> ffffffff803ddf90: [<ffffffff80048d19>] cpu_idle+0x95
> ffffffff803ddfa0: [<ffffffff803e7801>] start_kernel+0x220
> ffffffff803ddfc0: [<ffffffff803e722f>] x86_64_start_kernel+0x22f
>
> and
>
> Stack Trace:
> * [<ffffffff8006b2b0>] default_idle+0x29 <--
> ffffffff803ddf90: [<ffffffff80048d19>] cpu_idle+0x95
> ffffffff803ddf98: 0000000000200800
> ffffffff803ddfa0: [<ffffffff803e7801>] start_kernel+0x220
> ffffffff803ddfa8: 0000000000086800
> ffffffff803ddfb0: 0000000000000000
> ffffffff803ddfb8: ffffffff80430720
> ffffffff803ddfc0: [<ffffffff803e722f>] x86_64_start_kernel+0x22f
> ffffffff803ddfc8: 80008e000010019c
> ffffffff803ddfd0: 00000000ffffffff
> ffffffff803ddfd8: 0000000000000000
> ffffffff803ddfe0: 0000000000000000
> ffffffff803ddfe8: 0000000000200000
> ffffffff803ddff0: 0000000000000000
> ffffffff803ddff8: 0000000000000000
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 10/20] xenctx: Add -m (--memory) <maddr> option to dump memory at maddr.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (8 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 09/20] xenctx: Add output of stack address to Call and Stack Trace Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 13:30 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 11/20] xenctx: Add error output if --all-vcpus (-C) and [VCPU] are both specified Don Slutz
` (9 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Don Slutz, Jan Beulich
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.
Moved xenctx because guest_word_t is not defined where it was.
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>
---
v8:
Add "Moved xenctx because.." to commit message
Changed init of sopts to only have one copy of common options.
Make common code into routine.
Fixed bug with extra set bits on small widths.
tools/xentrace/xenctx.c | 242 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 172 insertions(+), 70 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 0c16ec8..06b10f2 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -30,22 +30,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 nr_stack_pages;
- int bytes_per_line;
- int lines;
- int decode_as_ascii;
- int tag_stack_dump;
- int all_vcpus;
- int self_paused;
- xc_dominfo_t dominfo;
-} xenctx;
-
#define DEFAULT_NR_STACK_PAGES 1
#define DEFAULT_BYTES_PER_LINE 32
#define DEFAULT_LINES 5
@@ -73,6 +57,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 nr_stack_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;
@@ -634,6 +639,45 @@ static guest_word_t read_stack_word(guest_word_t *src, int width)
return word;
}
+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 = 0;
+ char *src, *dst;
+ int i;
+
+ /* Little-endian only */
+ dst = (char *)&word;
+ for (i = 0; i < width; i++)
+ {
+ src = map_page(ctx, vcpu, virt + i);
+ if ( src )
+ *dst++ = *src;
+ else
+ {
+ guest_word_t missing = -1LL;
+
+ /* Return all ones for missing memory */
+ memcpy(dst, &missing, width - i);
+ return word;
+ }
+ }
+ return word;
+ }
+}
+#endif
+
static void print_stack_word(guest_word_t word, int width)
{
if (width == 4)
@@ -642,6 +686,78 @@ static void print_stack_word(guest_word_t word, int width)
printf(FMT_64B_WORD, word);
}
+#ifndef NO_TRANSLATION
+static int print_lines(vcpu_guest_context_any_t *ctx, int vcpu, int width,
+ guest_word_t mem_addr, guest_word_t mem_limit)
+{
+ guest_word_t mem_start = mem_addr;
+ guest_word_t word;
+ guest_word_t ascii[MAX_BYTES_PER_LINE/4];
+ int i;
+
+ for (i = 1; i < xenctx.lines + 1 && mem_addr < mem_limit; i++)
+ {
+ int j = 0;
+ int k;
+
+ if ( xenctx.tag_stack_dump )
+ {
+ print_stack_word(mem_addr, width);
+ printf(":");
+ }
+ while ( mem_addr < mem_limit &&
+ mem_addr < mem_start + i * xenctx.bytes_per_line )
+ {
+ void *p = map_page(ctx, vcpu, mem_addr);
+ if ( !p )
+ return -1;
+ word = read_mem_word(ctx, vcpu, mem_addr, width);
+ if ( xenctx.decode_as_ascii )
+ ascii[j++] = word;
+ printf(" ");
+ print_stack_word(word, width);
+ mem_addr += width;
+ }
+ if ( xenctx.decode_as_ascii )
+ {
+ /*
+ * Line up ascii output if less than bytes_per_line
+ * were printed.
+ */
+ for (k = j; k < xenctx.bytes_per_line / width; k++)
+ printf(" %*s", width * 2, "");
+ printf(" ");
+ for (k = 0; k < j; k++)
+ {
+ int l;
+ unsigned char *bytep = (unsigned char *)&ascii[k];
+
+ for (l = 0; l < width; l++)
+ {
+ if (isprint(*bytep))
+ printf("%c", *bytep);
+ else
+ printf(".");
+ bytep++;
+ }
+ }
+ }
+ printf("\n");
+ }
+ printf("\n");
+ return 0;
+}
+
+static void print_mem(vcpu_guest_context_any_t *ctx, int vcpu, int width,
+ guest_word_t mem_addr)
+{
+ printf("Memory (address ");
+ print_stack_word(mem_addr, width);
+ printf("):\n");
+ print_lines(ctx, vcpu, width, mem_addr,
+ mem_addr + xenctx.lines * xenctx.bytes_per_line);
+}
+
static int print_code(vcpu_guest_context_any_t *ctx, int vcpu)
{
guest_word_t instr;
@@ -678,8 +794,6 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
guest_word_t frame;
guest_word_t word;
guest_word_t *p;
- guest_word_t ascii[MAX_BYTES_PER_LINE/4];
- int i;
if ( width )
xenctx.bytes_per_line =
@@ -692,56 +806,8 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
if ( xenctx.lines )
{
printf("Stack:\n");
- for (i = 1; i < xenctx.lines + 1 && stack < stack_limit; i++)
- {
- int j = 0;
- int k;
-
- if ( xenctx.tag_stack_dump )
- {
- print_stack_word(stack, width);
- printf(":");
- }
- while ( stack < stack_limit &&
- stack < stack_pointer(ctx) + i * xenctx.bytes_per_line )
- {
- p = map_page(ctx, vcpu, stack);
- if ( !p )
- return -1;
- word = read_stack_word(p, width);
- if ( xenctx.decode_as_ascii )
- ascii[j++] = word;
- printf(" ");
- print_stack_word(word, width);
- stack += width;
- }
- if ( xenctx.decode_as_ascii )
- {
- /*
- * Line up ascii output if less than bytes_per_line
- * were printed.
- */
- for (k = j; k < xenctx.bytes_per_line / width; k++)
- printf(" %*s", width * 2, "");
- printf(" ");
- for (k = 0; k < j; k++)
- {
- int l;
- unsigned char *bytep = (unsigned char *)&ascii[k];
-
- for (l = 0; l < width; l++)
- {
- if (isprint(*bytep))
- printf("%c", *bytep);
- else
- printf(".");
- bytep++;
- }
- }
- }
- printf("\n");
- }
- printf("\n");
+ if ( print_lines(ctx, vcpu, width, stack, stack_limit) )
+ return -1;
}
if(xenctx.stack_trace)
@@ -862,6 +928,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))
@@ -921,13 +994,21 @@ static void usage(void)
printf(" add a decode of Stack dump as ascii.\n");
printf(" -t, --tag-stack-dump\n");
printf(" add address on each line of Stack dump.\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;
- static const char *sopts = "fs:hak:SCn:b:l:Dt";
+ static const char *sopts = "fs:hak:SCn:b:l:Dt"
+#ifndef NO_TRANSLATION
+ "m:"
+#endif
+ ;
static const struct option lopts[] = {
{"stack-trace", 0, NULL, 'S'},
{"symbol-table", 1, NULL, 's'},
@@ -936,6 +1017,9 @@ int main(int argc, char **argv)
{"display-stack-pages", 0, NULL, 'n'},
{"decode-as-ascii", 0, NULL, 'D'},
{"tag-stack-dump", 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'},
@@ -946,6 +1030,7 @@ int main(int argc, char **argv)
const char *symbol_table = NULL;
int vcpu = 0;
+ int do_default = 1;
xenctx.bytes_per_line = DEFAULT_BYTES_PER_LINE;
xenctx.lines = DEFAULT_LINES;
@@ -1009,10 +1094,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);
@@ -1062,9 +1155,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);
if (xenctx.self_paused) {
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 10/20] xenctx: Add -m (--memory) <maddr> option to dump memory at maddr.
2014-03-27 19:05 ` [PATCH v8 10/20] xenctx: Add -m (--memory) <maddr> option to dump memory at maddr Don Slutz
@ 2014-04-01 13:30 ` Ian Campbell
0 siblings, 0 replies; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 13:30 UTC (permalink / raw)
To: Don Slutz
Cc: Stefano Stabellini, George Dunlap, Don Slutz, Ian Jackson,
xen-devel, Jan Beulich
On Thu, 2014-03-27 at 15:05 -0400, 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.
>
> Moved xenctx because guest_word_t is not defined where it was.
>
> 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>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 11/20] xenctx: Add error output if --all-vcpus (-C) and [VCPU] are both specified.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (9 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 10/20] xenctx: Add -m (--memory) <maddr> option to dump memory at maddr Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 13:44 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 12/20] xenctx: Add -d (--dump-as-stack) <daddr> option to dump memory at daddr as a stack Don Slutz
` (8 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
To do this correctly the program name must be remembered since argv
is adjusted at the end of option parsing.
Switch all uses of argv[0] to prog.
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v8:
Renamed form "xenctx: Fixup options checking"
New commit message.
make the new copy const.
tools/xentrace/xenctx.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 06b10f2..299ba5e 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -1004,6 +1004,7 @@ int main(int argc, char **argv)
{
int ch;
int ret;
+ const char *prog = argv[0];
static const char *sopts = "fs:hak:SCn:b:l:Dt"
#ifndef NO_TRANSLATION
"m:"
@@ -1073,7 +1074,7 @@ int main(int argc, char **argv)
{
fprintf(stderr,
"%s: Unsupported value for --bytes-per-line '%s'. Needs to be 4 <= %d <= %d\n",
- argv[0], optarg, xenctx.bytes_per_line,
+ prog, optarg, xenctx.bytes_per_line,
MAX_BYTES_PER_LINE);
exit(-1);
}
@@ -1088,7 +1089,7 @@ int main(int argc, char **argv)
{
fprintf(stderr,
"%s: Unsupported value(%d) for --lines '%s'. Needs to be >= 0, < %d\n",
- argv[0], xenctx.lines, optarg, INT_MAX);
+ prog, xenctx.lines, optarg, INT_MAX);
exit(-1);
}
break;
@@ -1110,7 +1111,7 @@ int main(int argc, char **argv)
usage();
exit(-1);
case '?':
- fprintf(stderr, "%s --help for more options\n", argv[0]);
+ fprintf(stderr, "%s --help for more options\n", prog);
exit(-1);
}
}
@@ -1128,8 +1129,17 @@ int main(int argc, char **argv)
exit(-1);
}
- if (argc == 2)
+ if ( argc == 2 )
+ {
+ if ( xenctx.all_vcpus )
+ {
+ fprintf(stderr,
+ "%s both --all-vcpus and [VCPU] is not supported\n",
+ prog);
+ exit(-1);
+ }
vcpu = atoi(argv[1]);
+ }
if (symbol_table)
read_symbol_table(symbol_table);
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 12/20] xenctx: Add -d (--dump-as-stack) <daddr> option to dump memory at daddr as a stack.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (10 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 11/20] xenctx: Add error output if --all-vcpus (-C) and [VCPU] are both specified Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 13:46 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr() Don Slutz
` (7 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Don Slutz,
Ian Jackson, Don Slutz, Jan Beulich
Also switch from read_stack_word to read_mem_word since the provided
address may not be aligned.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
tools/xentrace/xenctx.c | 70 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 52 insertions(+), 18 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 299ba5e..f6e5455 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -72,7 +72,9 @@ static struct xenctx {
int all_vcpus;
#ifndef NO_TRANSLATION
guest_word_t mem_addr;
+ guest_word_t stk_addr;
int do_memory;
+ int do_stack;
#endif
int self_paused;
xc_dominfo_t dominfo;
@@ -775,9 +777,7 @@ static int print_code(vcpu_guest_context_any_t *ctx, int vcpu)
else
printf("%02x ", *c);
}
- printf("\n");
-
- printf("\n");
+ printf("\n\n\n");
return 0;
}
@@ -787,9 +787,10 @@ static void print_stack_addr(guest_word_t addr, int width)
printf(": ");
}
-static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
+static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width,
+ guest_word_t stk_addr_start)
{
- guest_word_t stack = stack_pointer(ctx);
+ guest_word_t stack = stk_addr_start;
guest_word_t stack_limit;
guest_word_t frame;
guest_word_t word;
@@ -798,11 +799,10 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
if ( width )
xenctx.bytes_per_line =
((xenctx.bytes_per_line + width - 1) / width) * width;
- stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
+ stack_limit = ((stack + XC_PAGE_SIZE)
& ~((guest_word_t) XC_PAGE_SIZE - 1));
if ( xenctx.nr_stack_pages > 1 )
stack_limit += (xenctx.nr_stack_pages - 1) * XC_PAGE_SIZE;
- printf("\n");
if ( xenctx.lines )
{
printf("Stack:\n");
@@ -814,12 +814,15 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
printf("Stack Trace:\n");
else
printf("Call Trace:\n");
- printf("%*s %c [<", width*2, "", xenctx.stack_trace ? '*' : ' ');
- print_stack_word(instr_pointer(ctx), width);
- printf(">]");
+ if ( !xenctx.do_stack )
+ {
+ printf("%*s %c [<", width*2, "", xenctx.stack_trace ? '*' : ' ');
+ print_stack_word(instr_pointer(ctx), width);
+ printf(">]");
- print_symbol(instr_pointer(ctx));
- printf(" <--\n");
+ print_symbol(instr_pointer(ctx));
+ printf(" <--\n");
+ }
if (xenctx.frame_ptrs) {
stack = stack_pointer(ctx);
frame = frame_pointer(ctx);
@@ -866,12 +869,12 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
}
}
} else {
- stack = stack_pointer(ctx);
+ stack = stk_addr_start;
while(stack < stack_limit) {
p = map_page(ctx, vcpu, stack);
if (!p)
return -1;
- word = read_stack_word(p, width);
+ word = read_mem_word(ctx, vcpu, stack, width);
if (is_kernel_text(word)) {
print_stack_addr(stack, width);
printf(" [<");
@@ -934,13 +937,19 @@ static void dump_ctx(int vcpu)
print_mem(&ctx, vcpu, guest_word_size, xenctx.mem_addr);
return;
}
+ if ( xenctx.do_stack )
+ {
+ print_stack(&ctx, vcpu, guest_word_size, xenctx.stk_addr);
+ return;
+ }
#endif
print_ctx(&ctx);
#ifndef NO_TRANSLATION
if (print_code(&ctx, vcpu))
return;
if (is_kernel_text(instr_pointer(&ctx)))
- if (print_stack(&ctx, vcpu, guest_word_size))
+ if ( print_stack(&ctx, vcpu, guest_word_size,
+ stack_pointer(&ctx)) )
return;
#endif
}
@@ -997,6 +1006,8 @@ static void usage(void)
#ifndef NO_TRANSLATION
printf(" -m maddr, --memory=maddr\n");
printf(" dump memory at maddr.\n");
+ printf(" -d daddr, --dump-as-stack=daddr\n");
+ printf(" dump memory as a stack at daddr.\n");
#endif
}
@@ -1007,7 +1018,7 @@ int main(int argc, char **argv)
const char *prog = argv[0];
static const char *sopts = "fs:hak:SCn:b:l:Dt"
#ifndef NO_TRANSLATION
- "m:"
+ "m:d:"
#endif
;
static const struct option lopts[] = {
@@ -1020,6 +1031,7 @@ int main(int argc, char **argv)
{"tag-stack-dump", 0, NULL, 't'},
#ifndef NO_TRANSLATION
{"memory", 1, NULL, 'm'},
+ {"dump-as-stack", 1, NULL, 'd'},
#endif
{"bytes-per-line", 1, NULL, 'b'},
{"lines", 1, NULL, 'l'},
@@ -1057,7 +1069,7 @@ int main(int argc, char **argv)
{
fprintf(stderr,
"%s: Unsupported value(%d) for --display-stack-pages '%s'. Needs to be >= 1\n",
- argv[0], xenctx.nr_stack_pages, optarg);
+ prog, xenctx.nr_stack_pages, optarg);
exit(-1);
}
break;
@@ -1106,6 +1118,11 @@ int main(int argc, char **argv)
xenctx.do_memory = 1;
do_default = 0;
break;
+ case 'd':
+ xenctx.stk_addr = strtoull(optarg, NULL, 0);
+ xenctx.do_stack = 1;
+ do_default = 0;
+ break;
#endif
case 'h':
usage();
@@ -1123,6 +1140,16 @@ int main(int argc, char **argv)
exit(-1);
}
+#ifndef NO_TRANSLATION
+ if ( xenctx.frame_ptrs && xenctx.do_stack )
+ {
+ fprintf(stderr,
+ "%s both --frame-pointers and --dump-as-stack is not supported\n",
+ prog);
+ exit(-1);
+ }
+#endif
+
xenctx.domid = atoi(argv[0]);
if (xenctx.domid==0) {
fprintf(stderr, "cannot trace dom0\n");
@@ -1169,10 +1196,17 @@ int main(int argc, char **argv)
if ( xenctx.do_memory )
{
dump_ctx(vcpu);
- if (xenctx.all_vcpus)
+ if ( xenctx.do_stack || xenctx.all_vcpus )
printf("\n");
}
xenctx.do_memory = 0;
+ if ( xenctx.do_stack )
+ {
+ dump_ctx(vcpu);
+ if ( xenctx.all_vcpus )
+ printf("\n");
+ }
+ xenctx.do_stack = 0;
#endif
if (xenctx.all_vcpus)
dump_all_vcpus();
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 12/20] xenctx: Add -d (--dump-as-stack) <daddr> option to dump memory at daddr as a stack.
2014-03-27 19:05 ` [PATCH v8 12/20] xenctx: Add -d (--dump-as-stack) <daddr> option to dump memory at daddr as a stack Don Slutz
@ 2014-04-01 13:46 ` Ian Campbell
2014-04-01 18:23 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 13:46 UTC (permalink / raw)
To: Don Slutz
Cc: Stefano Stabellini, George Dunlap, Don Slutz, Ian Jackson,
xen-devel, Jan Beulich
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> Also switch from read_stack_word to read_mem_word since the provided
> address may not be aligned.
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
{
But:
> @@ -1057,7 +1069,7 @@ int main(int argc, char **argv)
> {
> fprintf(stderr,
> "%s: Unsupported value(%d) for --display-stack-pages '%s'. Needs to be >= 1\n",
> - argv[0], xenctx.nr_stack_pages, optarg);
> + prog, xenctx.nr_stack_pages, optarg);
Stray hunk from a previous patch?
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 12/20] xenctx: Add -d (--dump-as-stack) <daddr> option to dump memory at daddr as a stack.
2014-04-01 13:46 ` Ian Campbell
@ 2014-04-01 18:23 ` Don Slutz
0 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-04-01 18:23 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: Stefano Stabellini, George Dunlap, Don Slutz, Ian Jackson,
xen-devel, Jan Beulich
On 04/01/14 09:46, Ian Campbell wrote:
> But:
>> @@ -1057,7 +1069,7 @@ int main(int argc, char **argv)
>> {
>> fprintf(stderr,
>> "%s: Unsupported value(%d) for --display-stack-pages '%s'. Needs to be >= 1\n",
>> - argv[0], xenctx.nr_stack_pages, optarg);
>> + prog, xenctx.nr_stack_pages, optarg);
> Stray hunk from a previous patch?
Yup, will clean it up.
-Don Slutz
> Ian.
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr().
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (11 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 12/20] xenctx: Add -d (--dump-as-stack) <daddr> option to dump memory at daddr as a stack Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:10 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 14/20] xenctx: Add convert of more registers to symbols Don Slutz
` (6 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
A new enum has been added to allow the caller to determine if this
kernel address is a text, data, or module address. This can help
understand what is going on.
Kernel modules are only found when they are more then 1MiB after
kernel_end or the symbol "__brk_limit". The symbol "vgettimeofday"
is used to mark the end of where modules can be loaded.
For example (before this change):
xenctx -s /boot/System.map-2.6.32-279.2.1.el6.mpbios5.x86_64 21 1
rip: ffffffff81346876 io_serial_in+0x16
flags: 00000002 nz
rsp: ffff88003b759b48
rax: 0000000000000075 rcx: 0000000000000000 rdx: 00000000000003fd
rbx: ffffffff81ff8f00 rsi: 0000000000000005 rdi: ffffffff81ff8f00
rbp: ffff88003b759b48 r8: ffffffff81c03a10 r9: 0000000000000080
r10: 0000000000000005 r11: 00000000000000b4 r12: 000000000000270f
r13: 0000000000000020 r14: 000000000000003b r15: ffffffff81346f20
cs: 0010 ss: 0018 ds: 0000 es: 0000
fs: 0000 @ 00007f2ce3df1700
gs: 0000 @ ffff88000b420000/0000000000000000/
Code (instr addr ffffffff81346876)
48 89 e5 0f 1f 44 00 00 0f b6 4f 41 0f b7 57 08 d3 e6 01 f2 ec <0f> b6 c0 c9 c3 0f 1f 44 00 00 55
Stack:
ffff88003b759b78 ffffffff81346e64 ffffffff81ff8f00 0000000000000074
0000000000000050 000000000000003b ffff88003b759b98 ffffffff81346f46
ffffffff81e391b0 ffffffff81ff8f00 ffff88003b759bd8 ffffffff813428de
ffff88003b759bd8 0000000000000000 ffffffff81ff8f00 0000000000000001
0000000000000050 ffffffff81e39176 ffff88003b759c28 ffffffff813472ad
Call Trace:
[<ffffffff81346876>] io_serial_in+0x16 <--
ffff88003b759b50: [<ffffffff81346e64>] wait_for_xmitr+0x24
ffff88003b759b80: [<ffffffff81346f46>] serial8250_console_putchar+0x26
ffff88003b759ba0: [<ffffffff813428de>] uart_console_write+0x3e
ffff88003b759be0: [<ffffffff813472ad>] serial8250_console_write+0xbd
ffff88003b759c30: [<ffffffff8106b8f5>] __call_console_drivers+0x75
ffff88003b759c60: [<ffffffff8106b95a>] _call_console_drivers+0x4a
ffff88003b759c80: [<ffffffff8106be6e>] release_console_sem+0x4e
ffff88003b759cc0: [<ffffffff8106c628>] vprintk+0x248
ffff88003b759d60: [<ffffffff814fd363>] printk+0x41
Now:
xenctx -s /boot/System.map-2.6.32-279.2.1.el6.mpbios5.x86_64 21 1
rip: ffffffff81346876 io_serial_in+0x16
flags: 00000002 nz
rsp: ffff88003b759b48
rax: 0000000000000075 rcx: 0000000000000000 rdx: 00000000000003fd
rbx: ffffffff81ff8f00 rsi: 0000000000000005 rdi: ffffffff81ff8f00
rbp: ffff88003b759b48 r8: ffffffff81c03a10 r9: 0000000000000080
r10: 0000000000000005 r11: 00000000000000b4 r12: 000000000000270f
r13: 0000000000000020 r14: 000000000000003b r15: ffffffff81346f20
cs: 0010 ss: 0018 ds: 0000 es: 0000
fs: 0000 @ 00007f2ce3df1700
gs: 0000 @ ffff88000b420000/0000000000000000/
Code (instr addr ffffffff81346876)
48 89 e5 0f 1f 44 00 00 0f b6 4f 41 0f b7 57 08 d3 e6 01 f2 ec <0f> b6 c0 c9 c3 0f 1f 44 00 00 55
Stack:
ffff88003b759b78 ffffffff81346e64 ffffffff81ff8f00 0000000000000074
0000000000000050 000000000000003b ffff88003b759b98 ffffffff81346f46
ffffffff81e391b0 ffffffff81ff8f00 ffff88003b759bd8 ffffffff813428de
ffff88003b759bd8 0000000000000000 ffffffff81ff8f00 0000000000000001
0000000000000050 ffffffff81e39176 ffff88003b759c28 ffffffff813472ad
Call Trace:
[<ffffffff81346876>] io_serial_in+0x16 <--
ffff88003b759b50: [<ffffffff81346e64>] wait_for_xmitr+0x24
ffff88003b759b80: [<ffffffff81346f46>] serial8250_console_putchar+0x26
ffff88003b759ba0: [<ffffffff813428de>] uart_console_write+0x3e
ffff88003b759be0: [<ffffffff813472ad>] serial8250_console_write+0xbd
ffff88003b759c30: [<ffffffff8106b8f5>] __call_console_drivers+0x75
ffff88003b759c60: [<ffffffff8106b95a>] _call_console_drivers+0x4a
ffff88003b759c80: [<ffffffff8106be6e>] release_console_sem+0x4e
ffff88003b759cc0: [<ffffffff8106c628>] vprintk+0x248
ffff88003b759d60: [<ffffffff814fd363>] printk+0x41
ffff88003b759dc0: [<ffffffffa005f19d>]
ffff88003b759e50: [<ffffffffa005f1e8>]
ffff88003b759ee0: [<ffffffffa005f1e8>]
ffff88003b759f70: [<ffffffffa005f1e8>]
This shows that a kernel module is using a lot of stack.
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v8:
Added more to commit message.
Added some basic linux kernel module reporting.
Moved kernel_end into define tree in case no symbol found.
At some point __bss_stop was added and _end was dropped. Both
mean end of named kernel data.
tools/xentrace/xenctx.c | 107 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 85 insertions(+), 22 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index f6e5455..f270c24 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -34,6 +34,21 @@
#define DEFAULT_BYTES_PER_LINE 32
#define DEFAULT_LINES 5
+/* Note: the order of these matter.
+ * NOT_KERNEL_ADDR must be < all others.
+ * KERNEL_DATA_ADDR must be < KERNEL_TEXT_ADDR.
+ * KERNEL_DATA_ADDR must be < KERNEL_MOD_ADDR.
+ * KERNEL_MOD_ADDR must be > KERNEL_TEXT_ADDR.
+ */
+typedef enum type_of_addr_ {
+ NOT_KERNEL_ADDR,
+ KERNEL_DATA_ADDR,
+ KERNEL_TEXT_ADDR,
+ KERNEL_MOD_ADDR,
+} type_of_addr;
+
+#define MAX_MOD_OFFSET (1 << 20)
+
#if defined (__i386__) || defined (__x86_64__)
typedef unsigned long long guest_word_t;
#define FMT_32B_WORD "%08llx"
@@ -76,6 +91,7 @@ static struct xenctx {
int do_memory;
int do_stack;
#endif
+ int kernel_start_set;
int self_paused;
xc_dominfo_t dominfo;
} xenctx;
@@ -87,31 +103,57 @@ struct symbol {
} *symbol_table = NULL;
guest_word_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext, kernel_hypercallpage;
+guest_word_t kernel_text, kernel_mod_start, kernel_mod_end;
#if defined (__i386__) || defined (__arm__)
unsigned long long kernel_start = 0xc0000000;
+unsigned long long kernel_end = 0xffffffffULL;
#elif defined (__x86_64__)
unsigned long long kernel_start = 0xffffffff80000000UL;
+unsigned long long kernel_end = 0xffffffffffffffffUL;
#elif defined (__aarch64__)
unsigned long long kernel_start = 0xffffff8000000000UL;
+unsigned long long kernel_end = 0xffffffffffffffffULL;
#endif
-static int is_kernel_text(guest_word_t addr)
+static type_of_addr kernel_addr(guest_word_t addr)
{
- if (symbol_table == NULL)
- return (addr > kernel_start);
+ if ( symbol_table == NULL )
+ {
+ if ( addr > kernel_start )
+ return KERNEL_TEXT_ADDR;
+ else
+ return NOT_KERNEL_ADDR;
+ }
if (addr >= kernel_stext &&
addr <= kernel_etext)
- return 1;
+ return KERNEL_TEXT_ADDR;
if ( kernel_hypercallpage &&
(addr >= kernel_hypercallpage &&
addr <= kernel_hypercallpage + 4096) )
- return 1;
- if (addr >= kernel_sinittext &&
- addr <= kernel_einittext)
- return 1;
- return 0;
+ return KERNEL_TEXT_ADDR;
+ if ( kernel_sinittext &&
+ (addr >= kernel_sinittext &&
+ addr <= kernel_einittext) )
+ return KERNEL_TEXT_ADDR;
+ if ( xenctx.kernel_start_set )
+ {
+ if ( addr >= kernel_start )
+ return KERNEL_TEXT_ADDR;
+ }
+ else
+ {
+ if ( kernel_text &&
+ (addr >= kernel_text &&
+ addr <= kernel_end) )
+ return KERNEL_DATA_ADDR;
+ if ( kernel_mod_start &&
+ (addr >= kernel_mod_start &&
+ addr <= kernel_mod_end) )
+ return KERNEL_MOD_ADDR;
+ }
+ return NOT_KERNEL_ADDR;
}
#if 0
@@ -165,11 +207,12 @@ static struct symbol *lookup_symbol(guest_word_t address)
return s->next && s->next->address <= address ? s->next : s;
}
-static void print_symbol(guest_word_t addr)
+static void print_symbol(guest_word_t addr, type_of_addr type)
{
struct symbol *s;
+ type_of_addr addr_type = kernel_addr(addr);
- if (!is_kernel_text(addr))
+ if ( addr_type < type )
return;
s = lookup_symbol(addr);
@@ -180,7 +223,14 @@ static void print_symbol(guest_word_t addr)
if (addr==s->address)
printf(" %s", s->name);
else
- printf(" %s+%#x", s->name, (unsigned int)(addr - s->address));
+ {
+ unsigned long long offset = addr - s->address;
+
+ if ( addr_type == KERNEL_MOD_ADDR &&
+ offset > MAX_MOD_OFFSET )
+ return;
+ printf(" %s+%#llx", s->name, offset);
+ }
}
static void read_symbol_table(const char *symtab)
@@ -249,12 +299,23 @@ static void read_symbol_table(const char *symtab)
kernel_stext = address;
else if (strcmp(p, "_etext") == 0)
kernel_etext = address;
+ else if ( strcmp(p, "_text") == 0 )
+ kernel_text = address;
+ else if ( strcmp(p, "_end") == 0 || strcmp(p, "__bss_stop") == 0 )
+ {
+ kernel_end = address;
+ kernel_mod_start = address + MAX_MOD_OFFSET;
+ }
else if (strcmp(p, "_sinittext") == 0)
kernel_sinittext = address;
else if (strcmp(p, "_einittext") == 0)
kernel_einittext = address;
else if (strcmp(p, "hypercall_page") == 0)
kernel_hypercallpage = address;
+ else if (strcmp(p, "__brk_limit") == 0)
+ kernel_mod_start = address + MAX_MOD_OFFSET;
+ else if (strcmp(p, "vgettimeofday") == 0)
+ kernel_mod_end = address - 1;
}
fclose(f);
@@ -320,7 +381,7 @@ static void print_ctx_32(vcpu_guest_context_x86_32_t *ctx)
struct cpu_user_regs_x86_32 *regs = &ctx->user_regs;
printf("cs:eip: %04x:%08x", regs->cs, regs->eip);
- print_symbol(regs->eip);
+ print_symbol(regs->eip, KERNEL_TEXT_ADDR);
print_flags(regs->eflags);
printf("ss:esp: %04x:%08x\n", regs->ss, regs->esp);
@@ -349,7 +410,7 @@ static void print_ctx_32on64(vcpu_guest_context_x86_64_t *ctx)
struct cpu_user_regs_x86_64 *regs = &ctx->user_regs;
printf("cs:eip: %04x:%08x", regs->cs, (uint32_t)regs->eip);
- print_symbol((uint32_t)regs->eip);
+ print_symbol((uint32_t)regs->eip, KERNEL_TEXT_ADDR);
print_flags((uint32_t)regs->eflags);
printf("ss:esp: %04x:%08x\n", regs->ss, (uint32_t)regs->esp);
@@ -378,7 +439,7 @@ static void print_ctx_64(vcpu_guest_context_x86_64_t *ctx)
struct cpu_user_regs_x86_64 *regs = &ctx->user_regs;
printf("rip: %016"PRIx64, regs->rip);
- print_symbol(regs->rip);
+ print_symbol(regs->rip, KERNEL_TEXT_ADDR);
print_flags(regs->rflags);
printf("rsp: %016"PRIx64"\n", regs->rsp);
@@ -476,7 +537,7 @@ static void print_ctx_32(vcpu_guest_context_t *ctx)
vcpu_guest_core_regs_t *regs = &ctx->user_regs;
printf("PC: %08"PRIx32, regs->pc32);
- print_symbol(regs->pc32);
+ print_symbol(regs->pc32, KERNEL_TEXT_ADDR);
printf("\n");
printf("CPSR: %08"PRIx32"\n", regs->cpsr);
printf("USR: SP:%08"PRIx32" LR:%08"PRIx32"\n",
@@ -528,7 +589,7 @@ static void print_ctx_64(vcpu_guest_context_t *ctx)
vcpu_guest_core_regs_t *regs = &ctx->user_regs;
printf("PC: %016"PRIx64, regs->pc64);
- print_symbol(regs->pc64);
+ print_symbol(regs->pc64, KERNEL_TEXT_ADDR);
printf("\n");
printf("LR: %016"PRIx64"\n", regs->x30);
@@ -820,7 +881,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width,
print_stack_word(instr_pointer(ctx), width);
printf(">]");
- print_symbol(instr_pointer(ctx));
+ print_symbol(instr_pointer(ctx), KERNEL_TEXT_ADDR);
printf(" <--\n");
}
if (xenctx.frame_ptrs) {
@@ -863,7 +924,7 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width,
printf("%c [<", xenctx.stack_trace ? '|' : ' ');
print_stack_word(word, width);
printf(">]");
- print_symbol(word);
+ print_symbol(word, KERNEL_TEXT_ADDR);
printf("\n");
stack += width;
}
@@ -875,12 +936,13 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width,
if (!p)
return -1;
word = read_mem_word(ctx, vcpu, stack, width);
- if (is_kernel_text(word)) {
+ if ( kernel_addr(word) >= KERNEL_TEXT_ADDR )
+ {
print_stack_addr(stack, width);
printf(" [<");
print_stack_word(word, width);
printf(">]");
- print_symbol(word);
+ print_symbol(word, KERNEL_TEXT_ADDR);
printf("\n");
} else if (xenctx.stack_trace) {
print_stack_addr(stack, width);
@@ -947,7 +1009,7 @@ static void dump_ctx(int vcpu)
#ifndef NO_TRANSLATION
if (print_code(&ctx, vcpu))
return;
- if (is_kernel_text(instr_pointer(&ctx)))
+ if ( kernel_addr(instr_pointer(&ctx)) >= KERNEL_TEXT_ADDR )
if ( print_stack(&ctx, vcpu, guest_word_size,
stack_pointer(&ctx)) )
return;
@@ -1111,6 +1173,7 @@ int main(int argc, char **argv)
break;
case 'k':
kernel_start = strtoull(optarg, NULL, 0);
+ xenctx.kernel_start_set = 1;
break;
#ifndef NO_TRANSLATION
case 'm':
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr().
2014-03-27 19:05 ` [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr() Don Slutz
@ 2014-04-01 14:10 ` Ian Campbell
2014-04-01 21:33 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 14:10 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> A new enum has been added to allow the caller to determine if this
> kernel address is a text, data, or module address. This can help
> understand what is going on.
>
> Kernel modules are only found when they are more then 1MiB after
s/then/than/
But where does this magic assumption come from? Where does 1MiB come
from?
> kernel_end or the symbol "__brk_limit". The symbol "vgettimeofday"
> is used to mark the end of where modules can be loaded.
I can just about see from the vmlinux.lds.S why __brk_limit might be
somewhat relevant, but where does the use of vgettimeofday come from?
The 3.2 kernel on my desktop doesn't list vgettimeofday in System.map
for example and in any case you can't rely on it not being moved around.
(you can't really rely on __brk_limit either, but it seems less likely
to move).
(TBH, I'd suggest that this new functionality be left out for now, this
series has gone on for long enough as it is)
> ffff88003b759dc0: [<ffffffffa005f19d>]
> ffff88003b759e50: [<ffffffffa005f1e8>]
> ffff88003b759ee0: [<ffffffffa005f1e8>]
> ffff88003b759f70: [<ffffffffa005f1e8>]
>
> This shows that a kernel module is using a lot of stack.
Does it? All I see is the four additional entries at the base, consuming
about 0.5k which I suppose is a lot. I suppose those are stack frames
corresponding to some module? Perhaps mark them as such with "unknown
module function"?
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>
> ---
> v8:
> Added more to commit message.
> Added some basic linux kernel module reporting.
> Moved kernel_end into define tree in case no symbol found.
kernel_start is overridable on the command line, so kernel_end probably
should be too.
> At some point __bss_stop was added and _end was dropped. Both
> mean end of named kernel data.
Hrm I suppose we already encode a bunch of Linux kernel specific symbols
in this tool so a couple more don't hurt.
>
> -static int is_kernel_text(guest_word_t addr)
> +static type_of_addr kernel_addr(guest_word_t addr)
> {
> - if (symbol_table == NULL)
> - return (addr > kernel_start);
> + if ( symbol_table == NULL )
> + {
> + if ( addr > kernel_start )
> + return KERNEL_TEXT_ADDR;
> + else
> + return NOT_KERNEL_ADDR;
> + }
>
> if (addr >= kernel_stext &&
> addr <= kernel_etext)
> - return 1;
> + return KERNEL_TEXT_ADDR;
> if ( kernel_hypercallpage &&
> (addr >= kernel_hypercallpage &&
> addr <= kernel_hypercallpage + 4096) )
> - return 1;
> - if (addr >= kernel_sinittext &&
> - addr <= kernel_einittext)
> - return 1;
> - return 0;
> + return KERNEL_TEXT_ADDR;
> + if ( kernel_sinittext &&
> + (addr >= kernel_sinittext &&
> + addr <= kernel_einittext) )
> + return KERNEL_TEXT_ADDR;
> + if ( xenctx.kernel_start_set )
> + {
> + if ( addr >= kernel_start )
Has this logic changed since last time? Why no check of kernel_end?
Previously we only used kernel_start if no symbol table was provided.
That seemed logical enough to me, is there a reason to change that?
> + return KERNEL_TEXT_ADDR;
> + }
> + else
> + {
> + if ( kernel_text &&
> + (addr >= kernel_text &&
> + addr <= kernel_end) )
> + return KERNEL_DATA_ADDR;
> + if ( kernel_mod_start &&
> + (addr >= kernel_mod_start &&
> + addr <= kernel_mod_end) )
> + return KERNEL_MOD_ADDR;
> + }
> + return NOT_KERNEL_ADDR;
> }
>
> @@ -180,7 +223,14 @@ static void print_symbol(guest_word_t addr)
> if (addr==s->address)
> printf(" %s", s->name);
> else
> - printf(" %s+%#x", s->name, (unsigned int)(addr - s->address));
> + {
> + unsigned long long offset = addr - s->address;
> +
> + if ( addr_type == KERNEL_MOD_ADDR &&
> + offset > MAX_MOD_OFFSET )
> + return;
Shouldn't kernel_addr have not returned KERNEL_MOD_ADDR in that case?
> + printf(" %s+%#llx", s->name, offset);
> + }
> }
>
> static void read_symbol_table(const char *symtab)
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr().
2014-04-01 14:10 ` Ian Campbell
@ 2014-04-01 21:33 ` Don Slutz
2014-04-02 10:34 ` Ian Campbell
0 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-04-01 21:33 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/01/14 10:10, Ian Campbell wrote:
> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
>> A new enum has been added to allow the caller to determine if this
>> kernel address is a text, data, or module address. This can help
>> understand what is going on.
>>
>> Kernel modules are only found when they are more then 1MiB after
> s/then/than/
>
> But where does this magic assumption come from? Where does 1MiB come
> from?
I just picked it. I did base it on the theory that a given routine
should not be too large. I do feel that any routine that has more
then 1MiB of code bytes is too large.
>> kernel_end or the symbol "__brk_limit". The symbol "vgettimeofday"
>> is used to mark the end of where modules can be loaded.
> I can just about see from the vmlinux.lds.S why __brk_limit might be
> somewhat relevant, but where does the use of vgettimeofday come from?
>
> The 3.2 kernel on my desktop doesn't list vgettimeofday in System.map
> for example and in any case you can't rely on it not being moved around.
> (you can't really rely on __brk_limit either, but it seems less likely
> to move).
I would guess you are running a 32 bit desktop.
> (TBH, I'd suggest that this new functionality be left out for now, this
> series has gone on for long enough as it is)
I will drop the module stuff. (basically back to v5).
>
>> ffff88003b759dc0: [<ffffffffa005f19d>]
>> ffff88003b759e50: [<ffffffffa005f1e8>]
>> ffff88003b759ee0: [<ffffffffa005f1e8>]
>> ffff88003b759f70: [<ffffffffa005f1e8>]
>>
>> This shows that a kernel module is using a lot of stack.
> Does it? All I see is the four additional entries at the base, consuming
> about 0.5k which I suppose is a lot. I suppose those are stack frames
> corresponding to some module? Perhaps mark them as such with "unknown
> module function"?
Here is maybe a better output:
dcs-xen-54:~/xen>sudo tools/xentrace/xenctx -s /boot/System.map-2.6.32-279.2.1.el6.mpbios5.x86_64 3 1 -n 3
rip: ffffffff81346898 io_serial_out+0x18
flags: 00000002 nz
rsp: ffff880032bb1308
rax: 0000000000000074 rcx: 0000000000000000 rdx: 00000000000003f8
rbx: ffffffff81ff8f00 rsi: 0000000000000000 rdi: ffffffff81ff8f00
rbp: ffff880032bb1308 r8: ffffffff81c03a10 r9: 0000000000000080
r10: 0000000000000004 r11: 0000000000000000 r12: 0000000000000074
r13: 0000000000000064 r14: 000000000000001b r15: ffffffff81346f20
cs: 0010 ss: 0018 ds: 0000 es: 0000
fs: 0000 @ 00007f41d1061700
gs: 0000 @ ffff88000b420000/0000000000000000/
Code (instr addr ffffffff81346898)
e5 0f 1f 44 00 00 0f b6 4f 41 89 d0 0f b7 57 08 d3 e6 01 f2 ee <c9> c3 66 0f 1f 44 00 00 55 48 89
Stack:
ffff880032bb1328 ffffffff81346f51 ffffffff81e361c1 ffffffff81ff8f00
ffff880032bb1368 ffffffff813428de ffffffff8100bc0e 0000000000000000
ffffffff81ff8f00 0000000000000001 0000000000000064 ffffffff81e361a7
ffff880032bb13b8 ffffffff813472ad 0000000032bb14f8 0000000000000006
ffff880032bb1428 ffffffff81affa00 ffffffff81c03800 000000000000e707
Call Trace:
[<ffffffff81346898>] io_serial_out+0x18 <--
ffff880032bb1310: [<ffffffff81346f51>] serial8250_console_putchar+0x31
ffff880032bb1330: [<ffffffff813428de>] uart_console_write+0x3e
ffff880032bb1338: [<ffffffff8100bc0e>] apic_timer_interrupt+0xe
ffff880032bb1370: [<ffffffff813472ad>] serial8250_console_write+0xbd
ffff880032bb13c0: [<ffffffff8106b8f5>] __call_console_drivers+0x75
ffff880032bb13f0: [<ffffffff8106b95a>] _call_console_drivers+0x4a
ffff880032bb1410: [<ffffffff8106be6e>] release_console_sem+0x4e
ffff880032bb1450: [<ffffffff8106c628>] vprintk+0x248
ffff880032bb14f0: [<ffffffff814fd363>] printk+0x41
ffff880032bb1550: [<ffffffffa005119d>]
ffff880032bb15e0: [<ffffffffa00511e8>]
ffff880032bb1670: [<ffffffffa00511e8>]
ffff880032bb1700: [<ffffffffa00511e8>]
ffff880032bb1790: [<ffffffffa00511e8>]
ffff880032bb1820: [<ffffffffa00511e8>]
ffff880032bb18b0: [<ffffffffa00511e8>]
ffff880032bb1940: [<ffffffffa00511e8>]
ffff880032bb19d0: [<ffffffffa00511e8>]
ffff880032bb1a60: [<ffffffffa00511e8>]
ffff880032bb1af0: [<ffffffffa00511e8>]
ffff880032bb1b80: [<ffffffffa00511e8>]
ffff880032bb1c10: [<ffffffffa00511e8>]
ffff880032bb1ca0: [<ffffffffa00511e8>]
ffff880032bb1d30: [<ffffffffa00511e8>]
ffff880032bb1dc0: [<ffffffffa00511e8>]
ffff880032bb1e50: [<ffffffffa00511e8>]
ffff880032bb1ee0: [<ffffffffa00511e8>]
ffff880032bb1f70: [<ffffffffa00511e8>]
ffff880032bb2000: [<ffffffffa00511e8>]
ffff880032bb2090: [<ffffffffa00511e8>]
ffff880032bb2120: [<ffffffffa00511e8>]
ffff880032bb21b0: [<ffffffffa00511e8>]
ffff880032bb2240: [<ffffffffa00511e8>]
ffff880032bb22d0: [<ffffffffa00511e8>]
ffff880032bb2360: [<ffffffffa00511e8>]
ffff880032bb23f0: [<ffffffffa00511e8>]
ffff880032bb2480: [<ffffffffa00511e8>]
ffff880032bb2510: [<ffffffffa00511e8>]
ffff880032bb25a0: [<ffffffffa00511e8>]
ffff880032bb2630: [<ffffffffa00511e8>]
ffff880032bb26c0: [<ffffffffa00511e8>]
ffff880032bb2750: [<ffffffffa00511e8>]
ffff880032bb27e0: [<ffffffffa00511e8>]
ffff880032bb2870: [<ffffffffa00511e8>]
ffff880032bb2900: [<ffffffffa00511e8>]
ffff880032bb2990: [<ffffffffa00511e8>]
ffff880032bb2a20: [<ffffffffa00511e8>]
ffff880032bb2ab0: [<ffffffffa00511e8>]
ffff880032bb2b40: [<ffffffffa00511e8>]
ffff880032bb2bd0: [<ffffffffa00511e8>]
ffff880032bb2c60: [<ffffffffa00511e8>]
ffff880032bb2cf0: [<ffffffffa00511e8>]
ffff880032bb2d80: [<ffffffffa00511e8>]
ffff880032bb2e10: [<ffffffffa00511e8>]
ffff880032bb2ea0: [<ffffffffa00511e8>]
ffff880032bb2f30: [<ffffffffa00511e8>]
ffff880032bb2fc0: [<ffffffffa00511e8>]
ffff880032bb3050: [<ffffffffa00511e8>]
ffff880032bb30e0: [<ffffffffa00511e8>]
ffff880032bb3170: [<ffffffffa00511e8>]
ffff880032bb3200: [<ffffffffa00511e8>]
ffff880032bb3290: [<ffffffffa00511e8>]
ffff880032bb3320: [<ffffffffa00511e8>]
ffff880032bb33b0: [<ffffffffa00511e8>]
ffff880032bb3440: [<ffffffffa00511e8>]
ffff880032bb34d0: [<ffffffffa00511e8>]
ffff880032bb3560: [<ffffffffa00511e8>]
ffff880032bb35f0: [<ffffffffa00511e8>]
ffff880032bb3680: [<ffffffffa00511e8>]
ffff880032bb3710: [<ffffffffa00511e8>]
ffff880032bb37a0: [<ffffffffa00511e8>]
ffff880032bb3830: [<ffffffffa00511e8>]
ffff880032bb38c0: [<ffffffffa00511e8>]
ffff880032bb3950: [<ffffffffa00511e8>]
ffff880032bb39e0: [<ffffffffa00511e8>]
ffff880032bb3a70: [<ffffffffa00511e8>]
ffff880032bb3b00: [<ffffffffa00511e8>]
ffff880032bb3b90: [<ffffffffa00511e8>]
ffff880032bb3c20: [<ffffffffa00511e8>]
ffff880032bb3cb0: [<ffffffffa00511e8>]
ffff880032bb3d40: [<ffffffffa00511e8>]
ffff880032bb3dd0: [<ffffffffa00511e8>]
ffff880032bb3e60: [<ffffffffa00511e8>]
ffff880032bb3ee0: [<ffffffffa0051210>]
ffff880032bb3ef0: [<ffffffffa0051241>]
ffff880032bb3f20: [<ffffffff8100204c>] do_one_initcall+0x3c
ffff880032bb3f30: [<ffffffffa0055740>]
ffff880032bb3f50: [<ffffffff810b0eb1>] sys_init_module+0xe1
ffff880032bb3f80: [<ffffffff8100b0f2>] system_call_fastpath+0x16
dcs-xen-54:~/xen>
I could, but that looks to be a task for later.
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>> ---
>> v8:
>> Added more to commit message.
>> Added some basic linux kernel module reporting.
>> Moved kernel_end into define tree in case no symbol found.
> kernel_start is overridable on the command line, so kernel_end probably
> should be too.
Ok, but at this time I think I will defer adding "kernel_end command
option" to later.
In old 32bit linux virtual addresses were split at kernel start. Kernel end
was the same as end of memory. With 64bit linux adding vsyscall32
(/proc/sys/abi/vsyscall32) These are no longer kernel addresses.
>> At some point __bss_stop was added and _end was dropped. Both
>> mean end of named kernel data.
> Hrm I suppose we already encode a bunch of Linux kernel specific symbols
> in this tool so a couple more don't hurt.
>
>>
[...]
>> + return KERNEL_TEXT_ADDR;
>> + if ( xenctx.kernel_start_set )
>> + {
>> + if ( addr >= kernel_start )
> Has this logic changed since last time? Why no check of kernel_end?
No. No check because the user requested a particular split.
> Previously we only used kernel_start if no symbol table was provided.
> That seemed logical enough to me, is there a reason to change that?
>
This is what to do when both are specified. What I went with is that
if both are specified and we know this is a kernel symbol, then say so.
if the user said anything above KADDR is a kernel address, also accept
that.
Here is output of the same 3 stack pages in use guest that is paused:
dcs-xen-54:~/xen>sudo tools/xentrace/xenctx -s /boot/System.map-2.6.32-279.2.1.el6.mpbios5.x86_64 3 1 -n 3 -k 0xffffffff80000000
rip: ffffffff81346898 io_serial_out+0x18
flags: 00000002 nz
rsp: ffff880032bb1308
rax: 0000000000000074 rcx: 0000000000000000 rdx: 00000000000003f8
rbx: ffffffff81ff8f00 rsi: 0000000000000000 rdi: ffffffff81ff8f00
rbp: ffff880032bb1308 r8: ffffffff81c03a10 r9: 0000000000000080
r10: 0000000000000004 r11: 0000000000000000 r12: 0000000000000074
r13: 0000000000000064 r14: 000000000000001b r15: ffffffff81346f20
cs: 0010 ss: 0018 ds: 0000 es: 0000
fs: 0000 @ 00007f41d1061700
gs: 0000 @ ffff88000b420000/0000000000000000/
Code (instr addr ffffffff81346898)
e5 0f 1f 44 00 00 0f b6 4f 41 89 d0 0f b7 57 08 d3 e6 01 f2 ee <c9> c3 66 0f 1f 44 00 00 55 48 89
Stack:
ffff880032bb1328 ffffffff81346f51 ffffffff81e361c1 ffffffff81ff8f00
ffff880032bb1368 ffffffff813428de ffffffff8100bc0e 0000000000000000
ffffffff81ff8f00 0000000000000001 0000000000000064 ffffffff81e361a7
ffff880032bb13b8 ffffffff813472ad 0000000032bb14f8 0000000000000006
ffff880032bb1428 ffffffff81affa00 ffffffff81c03800 000000000000e707
Call Trace:
[<ffffffff81346898>] io_serial_out+0x18 <--
ffff880032bb1310: [<ffffffff81346f51>] serial8250_console_putchar+0x31
ffff880032bb1318: [<ffffffff81e361c1>] __log_buf+0xe721
ffff880032bb1320: [<ffffffff81ff8f00>] serial8250_ports
ffff880032bb1330: [<ffffffff813428de>] uart_console_write+0x3e
ffff880032bb1338: [<ffffffff8100bc0e>] apic_timer_interrupt+0xe
ffff880032bb1348: [<ffffffff81ff8f00>] serial8250_ports
ffff880032bb1360: [<ffffffff81e361a7>] __log_buf+0xe707
ffff880032bb1370: [<ffffffff813472ad>] serial8250_console_write+0xbd
ffff880032bb1390: [<ffffffff81affa00>] serial8250_console
ffff880032bb1398: [<ffffffff81c03800>] cpu_online_bits
ffff880032bb13c0: [<ffffffff8106b8f5>] __call_console_drivers+0x75
ffff880032bb13d0: [<ffffffff81e2797c>] logbuf_lock
ffff880032bb13f0: [<ffffffff8106b95a>] _call_console_drivers+0x4a
ffff880032bb1410: [<ffffffff8106be6e>] release_console_sem+0x4e
ffff880032bb1428: [<ffffffff81ea7b24>] printk_buf+0x64
ffff880032bb1450: [<ffffffff8106c628>] vprintk+0x248
ffff880032bb14a8: [<ffffffff81c03a10>] cpu_present_bits+0x10
ffff880032bb14f0: [<ffffffff814fd363>] printk+0x41
ffff880032bb1538: [<ffffffff81c03a10>] cpu_present_bits+0x10
ffff880032bb1550: [<ffffffffa005119d>] __brk_limit+0x1e01c19d
ffff880032bb15e0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1670: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1700: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1790: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1820: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb18b0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1940: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb19d0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1a60: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1af0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1b80: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1c10: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1ca0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1d30: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1dc0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1e50: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1ee0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb1f70: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2000: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2090: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2120: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb21b0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2240: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb22d0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2360: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb23f0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2480: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2510: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb25a0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2630: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb26c0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2750: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb27e0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2870: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2900: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2990: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2a20: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2ab0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2b40: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2bd0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2c60: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2cf0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2d80: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2e10: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2ea0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2f30: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb2fc0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3050: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb30e0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3170: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3200: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3290: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3320: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb33b0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3440: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb34d0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3560: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb35f0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3680: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3710: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb37a0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3830: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb38c0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3950: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb39e0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3a70: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3b00: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3b90: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3c20: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3cb0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3d40: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3dd0: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3e60: [<ffffffffa00511e8>] __brk_limit+0x1e01c1e8
ffff880032bb3ee0: [<ffffffffa0051210>] __brk_limit+0x1e01c210
ffff880032bb3ef0: [<ffffffffa0051241>] __brk_limit+0x1e01c241
ffff880032bb3f20: [<ffffffff8100204c>] do_one_initcall+0x3c
ffff880032bb3f30: [<ffffffffa0055740>] __brk_limit+0x1e020740
ffff880032bb3f50: [<ffffffff810b0eb1>] sys_init_module+0xe1
ffff880032bb3f80: [<ffffffff8100b0f2>] system_call_fastpath+0x16
>> + return KERNEL_TEXT_ADDR;
>> + }
>> + else
>> + {
>> + if ( kernel_text &&
>> + (addr >= kernel_text &&
>> + addr <= kernel_end) )
>> + return KERNEL_DATA_ADDR;
>> + if ( kernel_mod_start &&
>> + (addr >= kernel_mod_start &&
>> + addr <= kernel_mod_end) )
>> + return KERNEL_MOD_ADDR;
>> + }
>> + return NOT_KERNEL_ADDR;
>> }
>>
>> @@ -180,7 +223,14 @@ static void print_symbol(guest_word_t addr)
>> if (addr==s->address)
>> printf(" %s", s->name);
>> else
>> - printf(" %s+%#x", s->name, (unsigned int)(addr - s->address));
>> + {
>> + unsigned long long offset = addr - s->address;
>> +
>> + if ( addr_type == KERNEL_MOD_ADDR &&
>> + offset > MAX_MOD_OFFSET )
>> + return;
> Shouldn't kernel_addr have not returned KERNEL_MOD_ADDR in that case?
>
I did. But that symbol may also be too far also:
Like this is:
ffff880032bb3950: [<ffffffffa08711e8>] offline::checkit+0x41c1e8
This was an attempt to allow a more complete map to be used.
Like a copy of /proc/kallsyms from the guest. This would add
lines like:
ffffffffa000a510 t rpc_destroy_wait_queue [sunrpc]
ffffffffa002d140 b rpciod_workqueue [sunrpc]
ffffffffa00128c0 t auth_domain_put [sunrpc]
ffffffffa002cd00 d __tracepoint_rpc_task_sleep [sunrpc]
ffffffffa002cd40 d __tracepoint_rpc_task_complete [sunrpc]
ffffffffa0017100 t xdr_shift_buf [sunrpc]
ffffffffa000c9e0 t rpcauth_register [sunrpc]
I.E doing this gives:
...
ffff880032bb3c20: [<ffffffffa00511e8>] init_module [offline]+0x1e8
ffff880032bb3cb0: [<ffffffffa00511e8>] init_module [offline]+0x1e8
ffff880032bb3d40: [<ffffffffa00511e8>] init_module [offline]+0x1e8
ffff880032bb3dd0: [<ffffffffa00511e8>] init_module [offline]+0x1e8
ffff880032bb3e60: [<ffffffffa00511e8>] init_module [offline]+0x1e8
ffff880032bb3ee0: [<ffffffffa0051210>] init_module [offline]+0x210
ffff880032bb3ef0: [<ffffffffa0051241>] init_module [offline]+0x241
ffff880032bb3f20: [<ffffffff8100204c>] do_one_initcall+0x3c
ffff880032bb3f30: [<ffffffffa0055740>] init_module [offline]+0x4740
ffff880032bb3f50: [<ffffffff810b0eb1>] sys_init_module+0xe1
ffff880032bb3f80: [<ffffffff8100b0f2>] system_call_fastpath+0x16
-Don Slutz
>> + printf(" %s+%#llx", s->name, offset);
>> + }
>> }
>>
>> static void read_symbol_table(const char *symtab)
> Ian.
>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr().
2014-04-01 21:33 ` Don Slutz
@ 2014-04-02 10:34 ` Ian Campbell
2014-04-02 17:08 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-02 10:34 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Tue, 2014-04-01 at 17:33 -0400, Don Slutz wrote:
> On 04/01/14 10:10, Ian Campbell wrote:
> > On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> >> A new enum has been added to allow the caller to determine if this
> >> kernel address is a text, data, or module address. This can help
> >> understand what is going on.
> >>
> >> Kernel modules are only found when they are more then 1MiB after
> > s/then/than/
> >
> > But where does this magic assumption come from? Where does 1MiB come
> > from?
>
> I just picked it. I did base it on the theory that a given routine
> should not be too large. I do feel that any routine that has more
> then 1MiB of code bytes is too large.
>
> >> kernel_end or the symbol "__brk_limit". The symbol "vgettimeofday"
> >> is used to mark the end of where modules can be loaded.
> > I can just about see from the vmlinux.lds.S why __brk_limit might be
> > somewhat relevant, but where does the use of vgettimeofday come from?
> >
> > The 3.2 kernel on my desktop doesn't list vgettimeofday in System.map
> > for example and in any case you can't rely on it not being moved around.
> > (you can't really rely on __brk_limit either, but it seems less likely
> > to move).
>
> I would guess you are running a 32 bit desktop.
No. 3.13-1-amd64 and I looked in System.map-3.13-1-amd64
System.map-3.2.0-4-amd64 and System.map-3.9-1-amd64 which happened to be
present in /boot.
> Here is output of the same 3 stack pages in use guest that is paused:
You keep dropping in these massive output dumps without explaining what
they are supposed to illustrate. I have no idea what you think this is
telling me.
> >> + return KERNEL_TEXT_ADDR;
> >> + }
> >> + else
> >> + {
> >> + if ( kernel_text &&
> >> + (addr >= kernel_text &&
> >> + addr <= kernel_end) )
> >> + return KERNEL_DATA_ADDR;
> >> + if ( kernel_mod_start &&
> >> + (addr >= kernel_mod_start &&
> >> + addr <= kernel_mod_end) )
> >> + return KERNEL_MOD_ADDR;
> >> + }
> >> + return NOT_KERNEL_ADDR;
> >> }
> >>
> >> @@ -180,7 +223,14 @@ static void print_symbol(guest_word_t addr)
> >> if (addr==s->address)
> >> printf(" %s", s->name);
> >> else
> >> - printf(" %s+%#x", s->name, (unsigned int)(addr - s->address));
> >> + {
> >> + unsigned long long offset = addr - s->address;
> >> +
> >> + if ( addr_type == KERNEL_MOD_ADDR &&
> >> + offset > MAX_MOD_OFFSET )
> >> + return;
> > Shouldn't kernel_addr have not returned KERNEL_MOD_ADDR in that case?
> >
>
> I did.
You did what?
> But that symbol may also be too far also:
If it is too far then why is addr_type == KERNEL_MOD_ADDR in the first
place. Isn't it kernel_addr()s job to return the right answer?
>
> Like this is:
>
> ffff880032bb3950: [<ffffffffa08711e8>] offline::checkit+0x41c1e8
>
>
> This was an attempt to allow a more complete map to be used.
> Like a copy of /proc/kallsyms from the guest. This would add
> lines like:
>
> ffffffffa000a510 t rpc_destroy_wait_queue [sunrpc]
> ffffffffa002d140 b rpciod_workqueue [sunrpc]
> ffffffffa00128c0 t auth_domain_put [sunrpc]
> ffffffffa002cd00 d __tracepoint_rpc_task_sleep [sunrpc]
> ffffffffa002cd40 d __tracepoint_rpc_task_complete [sunrpc]
> ffffffffa0017100 t xdr_shift_buf [sunrpc]
> ffffffffa000c9e0 t rpcauth_register [sunrpc]
>
> I.E doing this gives:
>
> ...
> ffff880032bb3c20: [<ffffffffa00511e8>] init_module [offline]+0x1e8
> ffff880032bb3cb0: [<ffffffffa00511e8>] init_module [offline]+0x1e8
> ffff880032bb3d40: [<ffffffffa00511e8>] init_module [offline]+0x1e8
> ffff880032bb3dd0: [<ffffffffa00511e8>] init_module [offline]+0x1e8
> ffff880032bb3e60: [<ffffffffa00511e8>] init_module [offline]+0x1e8
> ffff880032bb3ee0: [<ffffffffa0051210>] init_module [offline]+0x210
> ffff880032bb3ef0: [<ffffffffa0051241>] init_module [offline]+0x241
> ffff880032bb3f20: [<ffffffff8100204c>] do_one_initcall+0x3c
> ffff880032bb3f30: [<ffffffffa0055740>] init_module [offline]+0x4740
> ffff880032bb3f50: [<ffffffff810b0eb1>] sys_init_module+0xe1
> ffff880032bb3f80: [<ffffffff8100b0f2>] system_call_fastpath+0x16
I have no clue what you think this is telling me.
Apparently a bunch of "[offline]" and "offline::" prefixes have appeared
out of thin air though.
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr().
2014-04-02 10:34 ` Ian Campbell
@ 2014-04-02 17:08 ` Don Slutz
0 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-04-02 17:08 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/02/14 06:34, Ian Campbell wrote:
> On Tue, 2014-04-01 at 17:33 -0400, Don Slutz wrote:
>> On 04/01/14 10:10, Ian Campbell wrote:
>>> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
>>
>>>> kernel_end or the symbol "__brk_limit". The symbol "vgettimeofday"
>>>> is used to mark the end of where modules can be loaded.
>>> I can just about see from the vmlinux.lds.S why __brk_limit might be
>>> somewhat relevant, but where does the use of vgettimeofday come from?
>>>
>>> The 3.2 kernel on my desktop doesn't list vgettimeofday in System.map
>>> for example and in any case you can't rely on it not being moved around.
>>> (you can't really rely on __brk_limit either, but it seems less likely
>>> to move).
>> I would guess you are running a 32 bit desktop.
> No. 3.13-1-amd64 and I looked in System.map-3.13-1-amd64
> System.map-3.2.0-4-amd64 and System.map-3.9-1-amd64 which happened to be
> present in /boot.
I only find it in 2.6 kernels. Since I am dropping the module support
this symbol is no longer checked for.
>> Here is output of the same 3 stack pages in use guest that is paused:
> You keep dropping in these massive output dumps without explaining what
> they are supposed to illustrate. I have no idea what you think this is
> telling me.
This was in response to:
>>> This shows that a kernel module is using a lot of stack.
>> Does it? All I see is the four additional entries at the base, consuming
>> about 0.5k which I suppose is a lot. I suppose those are stack frames
>> corresponding to some module? Perhaps mark them as such with "unknown
>> module function"?
I was trying to tell you that the module code was using much more then 0.5k.
It is just over 2 pages. But forgot to write this sentence 1st.
Clearly what I am writing in e-mails is not at all clear to you. Will try to do better.
>>>> + return KERNEL_TEXT_ADDR;
>>>> + }
>>>> + else
>>>> + {
>>>> + if ( kernel_text &&
>>>> + (addr >= kernel_text &&
>>>> + addr <= kernel_end) )
>>>> + return KERNEL_DATA_ADDR;
>>>> + if ( kernel_mod_start &&
>>>> + (addr >= kernel_mod_start &&
>>>> + addr <= kernel_mod_end) )
>>>> + return KERNEL_MOD_ADDR;
>>>> + }
>>>> + return NOT_KERNEL_ADDR;
>>>> }
>>>>
>>>> @@ -180,7 +223,14 @@ static void print_symbol(guest_word_t addr)
>>>> if (addr==s->address)
>>>> printf(" %s", s->name);
>>>> else
>>>> - printf(" %s+%#x", s->name, (unsigned int)(addr - s->address));
>>>> + {
>>>> + unsigned long long offset = addr - s->address;
>>>> +
>>>> + if ( addr_type == KERNEL_MOD_ADDR &&
>>>> + offset > MAX_MOD_OFFSET )
>>>> + return;
>>> Shouldn't kernel_addr have not returned KERNEL_MOD_ADDR in that case?
>>>
>> I did.
> You did what?
>
I had meant to type "It". But that is also wrong. Somehow I dropped the not in
"not returned KERNEL_MOD_ADDR". What I should have said:
kernel_addr when checking for KERNEL_MOD_ADDR only does a range check.
It does not search the symbols to see if the address is close enough.
With these issues, I see no reason to attempt adding module support at this time.
If you want I can also answer the later questions.
-Don Slutz
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 14/20] xenctx: Add convert of more registers to symbols
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (12 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 13/20] xenctx: change is_kernel_text() into kernel_addr() Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:11 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 15/20] xenctx: Add output of vcpu value and state for --all-vcpus Don Slutz
` (5 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
For example can change:
gs: 0000 @ ffffffff803ac000/0000000000000000
to
gs: 0000 @ ffffffff803ac000/0000000000000000 boot_cpu_pda/
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
tools/xentrace/xenctx.c | 47 +++++++++++++++++++++++++++++++++++------------
1 file changed, 35 insertions(+), 12 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index f270c24..2b279f4 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -50,6 +50,8 @@ typedef enum type_of_addr_ {
#define MAX_MOD_OFFSET (1 << 20)
#if defined (__i386__) || defined (__x86_64__)
+static const uint64_t cr_reg_mask[5] = { [2] = ~UINT64_C(0) };
+static const uint64_t dr_reg_mask[8] = { [0 ... 3] = ~UINT64_C(0) };
typedef unsigned long long guest_word_t;
#define FMT_32B_WORD "%08llx"
#define FMT_64B_WORD "%016llx"
@@ -362,17 +364,29 @@ static void print_flags(uint64_t flags)
printf("\n");
}
-static void print_special(void *regs, const char *name, unsigned int mask, int width)
+static void print_special(void *regs, const char *name, unsigned int mask,
+ const uint64_t reg_is_addr_mask[], int width)
{
unsigned int i;
printf("\n");
for (i = 0; mask; mask >>= 1, ++i)
if (mask & 1) {
- if (width == 4)
- printf("%s%u: %08"PRIx32"\n", name, i, ((uint32_t *) regs)[i]);
+ if ( width == 4 )
+ {
+ printf("%s%u: %08"PRIx32, name, i, ((uint32_t *) regs)[i]);
+ if ( reg_is_addr_mask[i] )
+ print_symbol(reg_is_addr_mask[i] & ((uint32_t *) regs)[i],
+ KERNEL_DATA_ADDR);
+ }
else
- printf("%s%u: %08"PRIx64"\n", name, i, ((uint64_t *) regs)[i]);
+ {
+ printf("%s%u: %016"PRIx64, name, i, ((uint64_t *) regs)[i]);
+ if ( reg_is_addr_mask[i] )
+ print_symbol(reg_is_addr_mask[i] & ((uint64_t *) regs)[i],
+ KERNEL_DATA_ADDR);
+ }
+ printf("\n");
}
}
@@ -400,8 +414,8 @@ static void print_ctx_32(vcpu_guest_context_x86_32_t *ctx)
printf(" gs: %04x\n", regs->gs);
if (xenctx.disp_all) {
- print_special(ctx->ctrlreg, "cr", 0x1d, 4);
- print_special(ctx->debugreg, "dr", 0xcf, 4);
+ print_special(ctx->ctrlreg, "cr", 0x1d, cr_reg_mask, 4);
+ print_special(ctx->debugreg, "dr", 0xcf, dr_reg_mask, 4);
}
}
@@ -429,8 +443,8 @@ static void print_ctx_32on64(vcpu_guest_context_x86_64_t *ctx)
printf(" gs: %04x\n", regs->gs);
if (xenctx.disp_all) {
- print_special(ctx->ctrlreg, "cr", 0x1d, 4);
- print_special(ctx->debugreg, "dr", 0xcf, 4);
+ print_special(ctx->ctrlreg, "cr", 0x1d, cr_reg_mask, 4);
+ print_special(ctx->debugreg, "dr", 0xcf, dr_reg_mask, 4);
}
}
@@ -468,13 +482,22 @@ static void print_ctx_64(vcpu_guest_context_x86_64_t *ctx)
printf(" ds: %04x\t", regs->ds);
printf(" es: %04x\n", regs->es);
- printf(" fs: %04x @ %016"PRIx64"\n", regs->fs, ctx->fs_base);
- printf(" gs: %04x @ %016"PRIx64"/%016"PRIx64"\n", regs->gs,
+ printf(" fs: %04x @ %016"PRIx64, regs->fs, ctx->fs_base);
+ print_symbol(ctx->fs_base, KERNEL_DATA_ADDR);
+ printf("\n");
+ printf(" gs: %04x @ %016"PRIx64"/%016"PRIx64, regs->gs,
ctx->gs_base_kernel, ctx->gs_base_user);
+ if ( symbol_table )
+ {
+ print_symbol(ctx->gs_base_kernel, KERNEL_DATA_ADDR);
+ printf("/");
+ print_symbol(ctx->gs_base_user, KERNEL_DATA_ADDR);
+ }
+ printf("\n");
if (xenctx.disp_all) {
- print_special(ctx->ctrlreg, "cr", 0x1d, 8);
- print_special(ctx->debugreg, "dr", 0xcf, 8);
+ print_special(ctx->ctrlreg, "cr", 0x1d, cr_reg_mask, 8);
+ print_special(ctx->debugreg, "dr", 0xcf, dr_reg_mask, 8);
}
}
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 15/20] xenctx: Add output of vcpu value and state for --all-vcpus
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (13 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 14/20] xenctx: Add convert of more registers to symbols Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-03-27 19:05 ` [PATCH v8 16/20] xenctx: Fix handling of !guest_protected_mode Don Slutz
` (4 subsequent siblings)
19 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
This makes it easier to know which vcpu the registers belong to and
when not all vcpus are online, which vcpu it is.
Signed-off-by: Don Slutz <dslutz@verizon.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
v8: Removed extra {}
tools/xentrace/xenctx.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 2b279f4..1d5b36e 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -1048,7 +1048,13 @@ static void dump_all_vcpus(void)
if ( xc_vcpu_getinfo(xenctx.xc_handle, xenctx.domid, vcpu, &vinfo) )
continue;
if ( vinfo.online )
+ {
+ printf("vcpu%d:\n", vcpu);
dump_ctx(vcpu);
+ printf("\n");
+ }
+ else
+ printf("vcpu%d offline\n\n", vcpu);
}
}
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 16/20] xenctx: Fix handling of !guest_protected_mode
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (14 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 15/20] xenctx: Add output of vcpu value and state for --all-vcpus Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:14 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 17/20] xenctx: Allow output for offline vcpu when specified Don Slutz
` (3 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
Start with adding the code to the 64 bit path that the 32 bit path
has.
Next disable the "Stack Trace" or "Call Trace".
Finally allow stack dump.
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v8:
A little more in the commit message.
tools/xentrace/xenctx.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 1d5b36e..1ab837e 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -524,8 +524,13 @@ static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx)
r += ctx->x32.user_regs.cs << NONPROT_MODE_SEGMENT_SHIFT;
}
else
+ {
r = ctx->x64.user_regs.rip;
+ if ( !guest_protected_mode )
+ r += ctx->x64.user_regs.cs << NONPROT_MODE_SEGMENT_SHIFT;
+ }
+
return r;
}
@@ -540,8 +545,13 @@ static guest_word_t stack_pointer(vcpu_guest_context_any_t *ctx)
r += ctx->x32.user_regs.ss << NONPROT_MODE_SEGMENT_SHIFT;
}
else
+ {
r = ctx->x64.user_regs.rsp;
+ if ( !guest_protected_mode )
+ r += ctx->x64.user_regs.ss << NONPROT_MODE_SEGMENT_SHIFT;
+ }
+
return r;
}
@@ -894,6 +904,9 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width,
return -1;
}
+ if ( !guest_protected_mode )
+ return 0;
+
if(xenctx.stack_trace)
printf("Stack Trace:\n");
else
@@ -1032,7 +1045,8 @@ static void dump_ctx(int vcpu)
#ifndef NO_TRANSLATION
if (print_code(&ctx, vcpu))
return;
- if ( kernel_addr(instr_pointer(&ctx)) >= KERNEL_TEXT_ADDR )
+ if ( !guest_protected_mode ||
+ kernel_addr(instr_pointer(&ctx)) >= KERNEL_TEXT_ADDR )
if ( print_stack(&ctx, vcpu, guest_word_size,
stack_pointer(&ctx)) )
return;
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 16/20] xenctx: Fix handling of !guest_protected_mode
2014-03-27 19:05 ` [PATCH v8 16/20] xenctx: Fix handling of !guest_protected_mode Don Slutz
@ 2014-04-01 14:14 ` Ian Campbell
2014-04-01 18:35 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 14:14 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> Start with adding the code to the 64 bit path that the 32 bit path
> has.
One for people who keep x86 in their brains, is it possible for a
processor to be in 64-bit non-protected mode?
> Next disable the "Stack Trace" or "Call Trace".
>
> Finally allow stack dump.
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>
> ---
> v8:
> A little more in the commit message.
>
> tools/xentrace/xenctx.c | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
> index 1d5b36e..1ab837e 100644
> --- a/tools/xentrace/xenctx.c
> +++ b/tools/xentrace/xenctx.c
> @@ -524,8 +524,13 @@ static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx)
> r += ctx->x32.user_regs.cs << NONPROT_MODE_SEGMENT_SHIFT;
> }
> else
> + {
> r = ctx->x64.user_regs.rip;
>
> + if ( !guest_protected_mode )
> + r += ctx->x64.user_regs.cs << NONPROT_MODE_SEGMENT_SHIFT;
> + }
> +
> return r;
> }
>
> @@ -540,8 +545,13 @@ static guest_word_t stack_pointer(vcpu_guest_context_any_t *ctx)
> r += ctx->x32.user_regs.ss << NONPROT_MODE_SEGMENT_SHIFT;
> }
> else
> + {
> r = ctx->x64.user_regs.rsp;
>
> + if ( !guest_protected_mode )
> + r += ctx->x64.user_regs.ss << NONPROT_MODE_SEGMENT_SHIFT;
> + }
> +
> return r;
> }
>
> @@ -894,6 +904,9 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width,
> return -1;
> }
>
> + if ( !guest_protected_mode )
> + return 0;
> +
> if(xenctx.stack_trace)
> printf("Stack Trace:\n");
> else
> @@ -1032,7 +1045,8 @@ static void dump_ctx(int vcpu)
> #ifndef NO_TRANSLATION
> if (print_code(&ctx, vcpu))
> return;
> - if ( kernel_addr(instr_pointer(&ctx)) >= KERNEL_TEXT_ADDR )
> + if ( !guest_protected_mode ||
> + kernel_addr(instr_pointer(&ctx)) >= KERNEL_TEXT_ADDR )
> if ( print_stack(&ctx, vcpu, guest_word_size,
> stack_pointer(&ctx)) )
> return;
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 16/20] xenctx: Fix handling of !guest_protected_mode
2014-04-01 14:14 ` Ian Campbell
@ 2014-04-01 18:35 ` Don Slutz
2014-04-02 10:41 ` Ian Campbell
0 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-04-01 18:35 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/01/14 10:14, Ian Campbell wrote:
> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
>> Start with adding the code to the 64 bit path that the 32 bit path
>> has.
> One for people who keep x86 in their brains, is it possible for a
> processor to be in 64-bit non-protected mode?
Not in the way the question is asked. This case is:
Breakpoint 1, instr_pointer (ctx=ctx@entry=0x7fffffffd040) at xenctx.c:413
413 {
(gdb) p ctxt_word_size
$1 = 8
(gdb) p guest_word_size
$2 = 4
I.E. the context is in 64, the guest is not.
This is why:
void print_ctx(vcpu_guest_context_any_t *ctx)
{
if (ctxt_word_size == 4)
print_ctx_32(&ctx->x32);
else if (guest_word_size == 4)
print_ctx_32on64(&ctx->x64);
else
print_ctx_64(&ctx->x64);
}
exists.
-Don Slutz
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 16/20] xenctx: Fix handling of !guest_protected_mode
2014-04-01 18:35 ` Don Slutz
@ 2014-04-02 10:41 ` Ian Campbell
0 siblings, 0 replies; 50+ messages in thread
From: Ian Campbell @ 2014-04-02 10:41 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Tue, 2014-04-01 at 14:35 -0400, Don Slutz wrote:
> On 04/01/14 10:14, Ian Campbell wrote:
> > On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> >> Start with adding the code to the 64 bit path that the 32 bit path
> >> has.
> > One for people who keep x86 in their brains, is it possible for a
> > processor to be in 64-bit non-protected mode?
>
> Not in the way the question is asked. This case is:
>
> Breakpoint 1, instr_pointer (ctx=ctx@entry=0x7fffffffd040) at xenctx.c:413
> 413 {
> (gdb) p ctxt_word_size
> $1 = 8
> (gdb) p guest_word_size
> $2 = 4
>
> I.E. the context is in 64, the guest is not.
Ah, I missed that thanks.
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 17/20] xenctx: Allow output for offline vcpu when specified.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (15 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 16/20] xenctx: Fix handling of !guest_protected_mode Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:24 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 18/20] xenctx: Add 16 bit output Don Slutz
` (2 subsequent siblings)
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
xc_domain_hvm_getcontext_partial() will fail to get data for an
offline cpu. Switch back to PV mode of calculating ctxt_word_size
and guest_word_size in the case.
Do this change to xc_translate_foreign_address() also. In order to
handle 32bit PAE mode, use the hvm way not the pv way to do the
cr3 handling.
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v8: Also change xc_translate_foreign_address() to work.
tools/libxc/xc_pagetab.c | 46 +++++++++++++++++++++++++++++++++++++++-------
tools/xentrace/xenctx.c | 6 ++++++
2 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/tools/libxc/xc_pagetab.c b/tools/libxc/xc_pagetab.c
index 8525967..9d3349f 100644
--- a/tools/libxc/xc_pagetab.c
+++ b/tools/libxc/xc_pagetab.c
@@ -41,15 +41,47 @@ unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
/* What kind of paging are we dealing with? */
if (dominfo.hvm) {
- struct hvm_hw_cpu ctx;
+ struct hvm_hw_cpu hvm_ctx;
if (xc_domain_hvm_getcontext_partial(xch, dom,
HVM_SAVE_CODE(CPU), vcpu,
- &ctx, sizeof ctx) != 0)
- return 0;
- if (!(ctx.cr0 & CR0_PG))
- return virt >> PAGE_SHIFT;
- pt_levels = (ctx.msr_efer&EFER_LMA) ? 4 : (ctx.cr4&CR4_PAE) ? 3 : 2;
- paddr = ctx.cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull);
+ &hvm_ctx, sizeof hvm_ctx) != 0)
+ {
+ unsigned int gwidth;
+ vcpu_guest_context_any_t ctx;
+
+ if ( errno != EBADSLT )
+ return 0;
+ /*
+ * Offline CPU, use xc_vcpu_getcontext() if possible
+ */
+ if ( xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0 )
+ return 0;
+ if ( xc_domain_get_guest_width(xch, dom, &gwidth) != 0 )
+ return 0;
+ if ( gwidth == 8 )
+ {
+ if ( !(ctx.x64.ctrlreg[0] & CR0_PG) )
+ return virt >> PAGE_SHIFT;
+ pt_levels = 4;
+ paddr = ctx.x64.ctrlreg[3] & ~0xfffull;
+ }
+ else
+ {
+ if ( !(ctx.x32.ctrlreg[0] & CR0_PG) )
+ return virt >> PAGE_SHIFT;
+ pt_levels = (ctx.x32.ctrlreg[4] & CR4_PAE) ? 3 : 2;
+ paddr = ctx.x32.ctrlreg[3] & ((pt_levels == 3) ?
+ ~0x1full : ~0xfffull);
+ }
+ }
+ else
+ {
+ if ( !(hvm_ctx.cr0 & CR0_PG) )
+ return virt >> PAGE_SHIFT;
+ pt_levels = (hvm_ctx.msr_efer & EFER_LMA) ?
+ 4 : (hvm_ctx.cr4 & CR4_PAE) ? 3 : 2;
+ paddr = hvm_ctx.cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull);
+ }
} else {
unsigned int gwidth;
vcpu_guest_context_any_t ctx;
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 1ab837e..9aed57e 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -1010,6 +1010,11 @@ static void dump_ctx(int vcpu)
if (xc_domain_hvm_getcontext_partial(
xenctx.xc_handle, xenctx.domid, HVM_SAVE_CODE(CPU),
vcpu, &cpuctx, sizeof cpuctx) != 0) {
+ if ( errno == EBADSLT )
+ {
+ printf("Note: vcpu%d offline:\n\n", vcpu);
+ goto vcpu_off_line;
+ }
perror("xc_domain_hvm_getcontext_partial");
return;
}
@@ -1023,6 +1028,7 @@ static void dump_ctx(int vcpu)
ctxt_word_size = (strstr(xen_caps, "xen-3.0-x86_64")) ? 8 : 4;
} else {
unsigned int gw;
+ vcpu_off_line:
if ( !xc_domain_get_guest_width(xenctx.xc_handle, xenctx.domid, &gw) )
ctxt_word_size = guest_word_size = gw;
}
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 17/20] xenctx: Allow output for offline vcpu when specified.
2014-03-27 19:05 ` [PATCH v8 17/20] xenctx: Allow output for offline vcpu when specified Don Slutz
@ 2014-04-01 14:24 ` Ian Campbell
2014-04-01 19:24 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 14:24 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> xc_domain_hvm_getcontext_partial() will fail to get data for an
> offline cpu. Switch back to PV mode of calculating ctxt_word_size
> and guest_word_size in the case.
>
> Do this change to xc_translate_foreign_address() also. In order to
> handle 32bit PAE mode, use the hvm way not the pv way to do the
> cr3 handling.
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>
> ---
> v8: Also change xc_translate_foreign_address() to work.
>
> tools/libxc/xc_pagetab.c | 46 +++++++++++++++++++++++++++++++++++++++-------
> tools/xentrace/xenctx.c | 6 ++++++
> 2 files changed, 45 insertions(+), 7 deletions(-)
>
> diff --git a/tools/libxc/xc_pagetab.c b/tools/libxc/xc_pagetab.c
> index 8525967..9d3349f 100644
> --- a/tools/libxc/xc_pagetab.c
> +++ b/tools/libxc/xc_pagetab.c
This is not xenctx like $subject promised.
What does it even mean to translate addresses for a processor which is
offline? It's all a bit tree falling the woods for my tastes.
In fact, what use is dumping state for an offline CPU at all? I was
willing to gloss over a two line change to xenctx.c but this is now
adding a whole bunch of complexity for reasons that haven't really been
explained.
Is it guaranteed that xc_vcpu_getcontext returns something sane for an
offline CPU? It seems like it could just as easily return memset or
garbage or EINVAL and the hypervisor would be quite at liberty to do so
since an offline cpu does not logically have any state so it might throw
it away, the fact that the implementation is currently such that the
last known state is returned doesn't seem reliable to me.
But maybe one of the x86 guys wants to contradict this and say its all
fine?
> @@ -41,15 +41,47 @@ unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
> + /*
> + * Offline CPU, use xc_vcpu_getcontext() if possible
> + */
> + if ( xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0 )
> + return 0;
> + if ( xc_domain_get_guest_width(xch, dom, &gwidth) != 0 )
> + return 0;
> + if ( gwidth == 8 )
> + {
> + if ( !(ctx.x64.ctrlreg[0] & CR0_PG) )
> + return virt >> PAGE_SHIFT;
Another one for the x86 guys -- can a 64-bit processor have paging
disabled?
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 17/20] xenctx: Allow output for offline vcpu when specified.
2014-04-01 14:24 ` Ian Campbell
@ 2014-04-01 19:24 ` Don Slutz
2014-04-02 10:42 ` Ian Campbell
0 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-04-01 19:24 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/01/14 10:24, Ian Campbell wrote:
> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> + {
> + if ( !(ctx.x64.ctrlreg[0] & CR0_PG) )
> + return virt >> PAGE_SHIFT;
> Another one for the x86 guys -- can a 64-bit processor have paging
> disabled?
Again this is ctx size vs hvm guest mode.
-Don Slutz
> Ian.
>
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 17/20] xenctx: Allow output for offline vcpu when specified.
2014-04-01 19:24 ` Don Slutz
@ 2014-04-02 10:42 ` Ian Campbell
0 siblings, 0 replies; 50+ messages in thread
From: Ian Campbell @ 2014-04-02 10:42 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Tue, 2014-04-01 at 15:24 -0400, Don Slutz wrote:
> On 04/01/14 10:24, Ian Campbell wrote:
> > On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> > + {
> > + if ( !(ctx.x64.ctrlreg[0] & CR0_PG) )
> > + return virt >> PAGE_SHIFT;
> > Another one for the x86 guys -- can a 64-bit processor have paging
> > disabled?
>
> Again this is ctx size vs hvm guest mode.
Got it. There were other questions about this patch though so I won't
ack just yet.
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 18/20] xenctx: Add 16 bit output
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (16 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 17/20] xenctx: Allow output for offline vcpu when specified Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:25 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 19/20] xenctx: Fix print_ctx_32on64's print_special call Don Slutz
2014-03-27 19:05 ` [PATCH v8 20/20] xenctx: Ensure errno is not zero on error in xc_translate_foreign_address() Don Slutz
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
This output happens on !guest_protected_mode. The cpu is in 16 bit
mode in this case.
The "-m" option was not changed so that a 32 bit memory dump could
still be done.
For example:
$ xenctx 3
cs:eip: f000:00006dee
flags: 00000046 z p
ss:esp: 0000:00001fea
eax: 00000000 ebx: 0000e000 ecx: 00006de9 edx: 00000000
esi: 0000fff0 edi: 00000000 ebp: 00000000
ds: 0000 es: 0040 fs: 0000 gs: 0000
Code (instr addr 000f6dee)
66 53 66 e8 0f 65 00 00 66 5b 66 5e 66 5f 66 c3 fb 90 f3 90 fa <fc> 66 c3 eb 06 66 49 67 88 14 08
Stack:
7bf6 0000 8e30 0000 0246 812f 0000 0206 80e7 0080 0080
And:
$ xenctx 3 -d 0x00001fea -m 0x00001fe8 -l 1
Memory (address 00001fe8):
7bf60000 8e300000 02460000 0000812f 80e70206 00800080 c2c2c2c2 c2c2c2c2
Stack:
7bf6 0000 8e30 0000 0246 812f 0000 0206 80e7 0080 0080
Note: the memory address is aligned to 32 bits. The unaligned output:
$ xenctx 3 -m 0x00001fea -l 1
Memory (address 00001fea):
00007bf6 00008e30 812f0246 02060000 008080e7 c2c20080 c2c2c2c2 c2c2c2c2
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
tools/xentrace/xenctx.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 9aed57e..b7f6e0f 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -53,6 +53,7 @@ typedef enum type_of_addr_ {
static const uint64_t cr_reg_mask[5] = { [2] = ~UINT64_C(0) };
static const uint64_t dr_reg_mask[8] = { [0 ... 3] = ~UINT64_C(0) };
typedef unsigned long long guest_word_t;
+#define FMT_16B_WORD "%04llx"
#define FMT_32B_WORD "%08llx"
#define FMT_64B_WORD "%016llx"
/* Word-length of the guest's own data structures */
@@ -776,7 +777,9 @@ static guest_word_t read_mem_word(vcpu_guest_context_any_t *ctx, int vcpu,
static void print_stack_word(guest_word_t word, int width)
{
- if (width == 4)
+ if (width == 2)
+ printf(FMT_16B_WORD, word);
+ else if (width == 4)
printf(FMT_32B_WORD, word);
else
printf(FMT_64B_WORD, word);
@@ -1043,7 +1046,9 @@ static void dump_ctx(int vcpu)
}
if ( xenctx.do_stack )
{
- print_stack(&ctx, vcpu, guest_word_size, xenctx.stk_addr);
+ print_stack(&ctx, vcpu,
+ !guest_protected_mode ? 2 : guest_word_size,
+ xenctx.stk_addr);
return;
}
#endif
@@ -1053,7 +1058,8 @@ static void dump_ctx(int vcpu)
return;
if ( !guest_protected_mode ||
kernel_addr(instr_pointer(&ctx)) >= KERNEL_TEXT_ADDR )
- if ( print_stack(&ctx, vcpu, guest_word_size,
+ if ( print_stack(&ctx, vcpu,
+ !guest_protected_mode ? 2 : guest_word_size,
stack_pointer(&ctx)) )
return;
#endif
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 18/20] xenctx: Add 16 bit output
2014-03-27 19:05 ` [PATCH v8 18/20] xenctx: Add 16 bit output Don Slutz
@ 2014-04-01 14:25 ` Ian Campbell
2014-04-01 18:53 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 14:25 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> @@ -1043,7 +1046,9 @@ static void dump_ctx(int vcpu)
> }
> if ( xenctx.do_stack )
> {
> - print_stack(&ctx, vcpu, guest_word_size, xenctx.stk_addr);
> + print_stack(&ctx, vcpu,
> + !guest_protected_mode ? 2 : guest_word_size,
Doesn't this indicate that guest_word_size is set wrongly in the !
guest_protected_mode case?
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread* Re: [PATCH v8 18/20] xenctx: Add 16 bit output
2014-04-01 14:25 ` Ian Campbell
@ 2014-04-01 18:53 ` Don Slutz
0 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-04-01 18:53 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/01/14 10:25, Ian Campbell wrote:
> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
>> @@ -1043,7 +1046,9 @@ static void dump_ctx(int vcpu)
>> }
>> if ( xenctx.do_stack )
>> {
>> - print_stack(&ctx, vcpu, guest_word_size, xenctx.stk_addr);
>> + print_stack(&ctx, vcpu,
>> + !guest_protected_mode ? 2 : guest_word_size,
> Doesn't this indicate that guest_word_size is set wrongly in the !
> guest_protected_mode case?
I guess so, will fix it there.
-Don Slutz
> Ian.
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v8 19/20] xenctx: Fix print_ctx_32on64's print_special call.
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (17 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 18/20] xenctx: Add 16 bit output Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:27 ` Ian Campbell
2014-03-27 19:05 ` [PATCH v8 20/20] xenctx: Ensure errno is not zero on error in xc_translate_foreign_address() Don Slutz
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
print_special() uses the width argument to both select output format
and array size. So by passing 4 it expects an array of uint32_t.
But an array of uint64_t is passed.
So copy and mask the registers to 32 bits.
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
tools/xentrace/xenctx.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index b7f6e0f..6105ffb 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -444,8 +444,15 @@ static void print_ctx_32on64(vcpu_guest_context_x86_64_t *ctx)
printf(" gs: %04x\n", regs->gs);
if (xenctx.disp_all) {
- print_special(ctx->ctrlreg, "cr", 0x1d, cr_reg_mask, 4);
- print_special(ctx->debugreg, "dr", 0xcf, dr_reg_mask, 4);
+ uint32_t tmp_regs[8];
+ int i;
+
+ for (i = 0; i < 5; i++)
+ tmp_regs[i] = ctx->ctrlreg[i];
+ print_special(tmp_regs, "cr", 0x1d, cr_reg_mask, 4);
+ for (i = 0; i < 8; i++)
+ tmp_regs[i] = ctx->debugreg[i];
+ print_special(tmp_regs, "dr", 0xcf, dr_reg_mask, 4);
}
}
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* [PATCH v8 20/20] xenctx: Ensure errno is not zero on error in xc_translate_foreign_address()
2014-03-27 19:05 [PATCH v8 00/20] xenctx: Many changes Don Slutz
` (18 preceding siblings ...)
2014-03-27 19:05 ` [PATCH v8 19/20] xenctx: Fix print_ctx_32on64's print_special call Don Slutz
@ 2014-03-27 19:05 ` Don Slutz
2014-04-01 14:30 ` Ian Campbell
19 siblings, 1 reply; 50+ messages in thread
From: Don Slutz @ 2014-03-27 19:05 UTC (permalink / raw)
To: xen-devel
Cc: Ian Campbell, Stefano Stabellini, George Dunlap, Ian Jackson,
Don Slutz, Jan Beulich
This is because xc_translate_foreign_address() returns 0 in both the
error case and when 0 is the mfn. By making sure that errno is set
callers can now determine if it is an error or not.
Fixup map_page() to set errno to zero (0) to improve error handling.
Also call on perror() in map_page().
Signed-off-by: Don Slutz <dslutz@verizon.com>
---
tools/libxc/xc_pagetab.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
tools/xentrace/xenctx.c | 22 +++++++++++++++++++---
2 files changed, 60 insertions(+), 10 deletions(-)
diff --git a/tools/libxc/xc_pagetab.c b/tools/libxc/xc_pagetab.c
index 9d3349f..5c8049b 100644
--- a/tools/libxc/xc_pagetab.c
+++ b/tools/libxc/xc_pagetab.c
@@ -35,12 +35,17 @@ unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
int size, level, pt_levels = 2;
void *map;
- if (xc_domain_getinfo(xch, dom, 1, &dominfo) != 1
- || dominfo.domid != dom)
+ if ( xc_domain_getinfo(xch, dom, 1, &dominfo) != 1
+ || dominfo.domid != dom )
+ {
+ if ( !errno )
+ errno = EINVAL;
return 0;
+ }
/* What kind of paging are we dealing with? */
- if (dominfo.hvm) {
+ if ( dominfo.hvm )
+ {
struct hvm_hw_cpu hvm_ctx;
if (xc_domain_hvm_getcontext_partial(xch, dom,
HVM_SAVE_CODE(CPU), vcpu,
@@ -50,14 +55,26 @@ unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
vcpu_guest_context_any_t ctx;
if ( errno != EBADSLT )
+ {
+ if ( !errno )
+ errno = EINVAL;
return 0;
+ }
/*
* Offline CPU, use xc_vcpu_getcontext() if possible
*/
if ( xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0 )
+ {
+ if ( !errno )
+ errno = EINVAL;
return 0;
+ }
if ( xc_domain_get_guest_width(xch, dom, &gwidth) != 0 )
+ {
+ if ( !errno )
+ errno = EINVAL;
return 0;
+ }
if ( gwidth == 8 )
{
if ( !(ctx.x64.ctrlreg[0] & CR0_PG) )
@@ -85,10 +102,18 @@ unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
} else {
unsigned int gwidth;
vcpu_guest_context_any_t ctx;
- if (xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0)
+ if ( xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0 )
+ {
+ if ( !errno )
+ errno = EINVAL;
return 0;
+ }
if (xc_domain_get_guest_width(xch, dom, &gwidth) != 0)
+ {
+ if ( !errno )
+ errno = EINVAL;
return 0;
+ }
if (gwidth == 8) {
pt_levels = 4;
paddr = (uint64_t)xen_cr3_to_pfn_x86_64(ctx.x64.ctrlreg[3])
@@ -117,14 +142,23 @@ unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
paddr += ((virt & mask) >> (xc_ffs64(mask) - 1)) * size;
map = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_READ,
paddr >>PAGE_SHIFT);
- if (!map)
+ if ( !map )
+ {
+ if ( !errno )
+ errno = EINVAL;
return 0;
+ }
memcpy(&pte, map + (paddr & (PAGE_SIZE - 1)), size);
munmap(map, PAGE_SIZE);
- if (!(pte & 1))
+ if ( !(pte & 1) )
+ {
+ if ( !errno )
+ errno = EADDRNOTAVAIL;
return 0;
+ }
paddr = pte & 0x000ffffffffff000ull;
- if (level == 2 && (pte & PTE_PSE)) {
+ if ( level == 2 && (pte & PTE_PSE) )
+ {
mask = ((mask ^ ~-mask) >> 1); /* All bits below first set bit */
return ((paddr & ~mask) | (virt & mask)) >> PAGE_SHIFT;
}
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 6105ffb..f485ade 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -713,21 +713,37 @@ static void *map_page(vcpu_guest_context_any_t *ctx, int vcpu, guest_word_t virt
static unsigned long previous_mfn = 0;
static void *mapped = NULL;
- unsigned long mfn = xc_translate_foreign_address(xenctx.xc_handle, xenctx.domid, vcpu, virt);
+ unsigned long mfn;
unsigned long offset = virt & ~XC_PAGE_MASK;
+ int saved_errno;
- if (mapped && mfn == previous_mfn)
+ errno = 0;
+ mfn = xc_translate_foreign_address(xenctx.xc_handle, xenctx.domid,
+ vcpu, virt);
+ saved_errno = errno;
+ if ( mapped && mfn == previous_mfn && !saved_errno )
goto out;
if (mapped)
munmap(mapped, XC_PAGE_SIZE);
+ if ( saved_errno )
+ {
+ fprintf(stderr, "\nfailed to map page for "FMT_32B_WORD".\n", virt);
+ errno = saved_errno;
+ perror("xenctx");
+ return NULL;
+ }
previous_mfn = mfn;
mapped = xc_map_foreign_range(xenctx.xc_handle, xenctx.domid, XC_PAGE_SIZE, PROT_READ, mfn);
- if (mapped == NULL) {
+ if ( mapped == NULL )
+ {
+ saved_errno = errno;
fprintf(stderr, "\nfailed to map page for "FMT_32B_WORD".\n", virt);
+ errno = saved_errno;
+ perror("xenctx");
return NULL;
}
--
1.8.4
^ permalink raw reply related [flat|nested] 50+ messages in thread* Re: [PATCH v8 20/20] xenctx: Ensure errno is not zero on error in xc_translate_foreign_address()
2014-03-27 19:05 ` [PATCH v8 20/20] xenctx: Ensure errno is not zero on error in xc_translate_foreign_address() Don Slutz
@ 2014-04-01 14:30 ` Ian Campbell
2014-04-01 20:49 ` Don Slutz
0 siblings, 1 reply; 50+ messages in thread
From: Ian Campbell @ 2014-04-01 14:30 UTC (permalink / raw)
To: Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
> This is because xc_translate_foreign_address() returns 0 in both the
> error case and when 0 is the mfn. By making sure that errno is set
> callers can now determine if it is an error or not.
I think it would be preferable to change the function to return the
translated address via an output pointer and make the formal return be
an int 0 (success) or -1 (error, sets errno).
That would be both more normal and remove all the frobbing around with
errno.
Ian.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v8 20/20] xenctx: Ensure errno is not zero on error in xc_translate_foreign_address()
2014-04-01 14:30 ` Ian Campbell
@ 2014-04-01 20:49 ` Don Slutz
0 siblings, 0 replies; 50+ messages in thread
From: Don Slutz @ 2014-04-01 20:49 UTC (permalink / raw)
To: Ian Campbell, Don Slutz
Cc: George Dunlap, Stefano Stabellini, Ian Jackson, Jan Beulich,
xen-devel
On 04/01/14 10:30, Ian Campbell wrote:
> On Thu, 2014-03-27 at 15:05 -0400, Don Slutz wrote:
>> This is because xc_translate_foreign_address() returns 0 in both the
>> error case and when 0 is the mfn. By making sure that errno is set
>> callers can now determine if it is an error or not.
> I think it would be preferable to change the function to return the
> translated address via an output pointer and make the formal return be
> an int 0 (success) or -1 (error, sets errno).
>
> That would be both more normal and remove all the frobbing around with
> errno.
>
> Ian.
>
I was not of mind to change an existing interface. Will drop this from this patch set.
-Don Slutz
^ permalink raw reply [flat|nested] 50+ messages in thread