Hi Lianbo,
On 2023/03/15 18:07, Lianbo Jiang wrote:
The help/man page of the "vm" command suggests that the
"-M" option
accepts the mm_struct address as a valid argument. However, the "vm
-M" option always prints the virtual memory data of the current
task, regardless of its arguments.
I think that it's the intended behavior, isn't it?
-M mm if the mm_struct address has been removed from the task_struct
of an exiting task, the virtual memory data cannot be displayed.
However, if the address can be determined from the kernel stack,
it can be entered manually in order to try to resurrect the
virtual memory data of the task.
Thanks,
Kazu
>
> Without the patch:
> crash> ps |grep sshd
> 1159 1 19 ffff9915858a9980 IN 0.1 15820 9020 sshd
> 47236 1159 21 ffff991572b40000 IN 0.1 18916 11116 sshd
> ...
> crash> vm -M ffff991572b40000
> PID: 49647 TASK: ffff991580b39980 CPU: 10 COMMAND: "crash"
> ...
>
> With the patch:
> crash> vm -M ffff991572b40000
> PID: 47236 TASK: ffff991572b40000 CPU: 21 COMMAND: "sshd"
> ...
>
> Reported-by: Buland Kumar Singh <bsingh(a)redhat.com>
> Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
> ---
> memory.c | 39 +++++++++++++++++++++------------------
> 1 file changed, 21 insertions(+), 18 deletions(-)
>
> diff --git a/memory.c b/memory.c
> index 592a5ef49d50..c9861dd6d0fb 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -3640,6 +3640,7 @@ cmd_vm(void)
> else if (radix == 16)
> flag |= PRINT_RADIX_16;
>
> + optind = 1;
> if (!args[optind]) {
> if (!ref)
> print_task_header(fp, CURRENT_CONTEXT(), 0);
> @@ -3650,26 +3651,28 @@ cmd_vm(void)
> subsequent = 0;
>
> while (args[optind]) {
> - switch (str_to_context(args[optind], &value, &tc))
> - {
> - case STR_PID:
> - for (tc = pid_to_context(value); tc; tc = tc->tc_next) {
> - if (!ref)
> - print_task_header(fp, tc, subsequent++);
> - vm_area_dump(tc->task, flag, single_vma, ref);
> - }
> - break;
> + if (IS_A_NUMBER(args[optind])) {
> + switch (str_to_context(args[optind], &value, &tc))
> + {
> + case STR_PID:
> + for (tc = pid_to_context(value); tc; tc = tc->tc_next) {
> + if (!ref)
> + print_task_header(fp, tc, subsequent++);
> + vm_area_dump(tc->task, flag, single_vma, ref);
> + }
> + break;
>
> - case STR_TASK:
> - if (!ref)
> - print_task_header(fp, tc, subsequent++);
> - vm_area_dump(tc->task, flag, single_vma, ref);
> - break;
> + case STR_TASK:
> + if (!ref)
> + print_task_header(fp, tc, subsequent++);
> + vm_area_dump(tc->task, flag, single_vma, ref);
> + break;
>
> - case STR_INVALID:
> - error(INFO, "%sinvalid task or pid value: %s\n",
> - subsequent++ ? "\n" : "", args[optind]);
> - break;
> + case STR_INVALID:
> + error(INFO, "%sinvalid task or pid value: %s\n",
> + subsequent++ ? "\n" : "", args[optind]);
> + break;
> + }
> }
>
> optind++;