crash doesn't decode regs with 7.1.5
by Sagar Borikar
Hi,
I am facing issues with crash 7.1.5 for little endian mips CPU. Crash
is not able to decode the registers. But except registers all other
information is good. I tried to look at the notes section in the core
but doesn't seem anything wrong there. If I trace the vmcore with mips
gdb I can get the correct stack trace and register info.
crash> i r
The program has no registers now.
gdb: gdb request failed: i r
crash> bt
PID: 267 TASK: 808f66d0 CPU: 0 COMMAND: "sh"
For the same vmcore, on gdb:
(gdb) i r
zero at v0 v1 a0 a1 a2 a3
R0 00000000 004b376a 00000002 00000001 000024b0 0000000a ffffffff 00000002
t0 t1 t2 t3 t4 t5 t6 t7
R8 808f1180 00000000 00000001 77ab8000 7fd53050 004b4580 00000000 00000000
s0 s1 s2 s3 s4 s5 s6 s7
R16 00000002 808f0b80 808f1180 fffffff2 80d97f10 808f0b8c 00000030 00480000
t8 t9 k0 k1 gp sp s8 ra
R24 00000002 803b05bc 0000000a 81005890 80d94000 80d97e18 00000020 803b05e0
sr lo hi bad cause pc
50808000 1100fc03 00000000 00000002 803b05e0 00000000
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x803b05e0 in pcieport_sysfs_store (kobj=<optimized out>,
attr=<optimized out>, data=<optimized out>, len=<optimized out>) at
/build/sborikar/bodegadev/bodega-dev/mcpu/firmware/linux-4.4/drivers/cisco/pcieport/sysfs.c:59
#2 0x8021c6bc in kernfs_fop_write (file=<optimized out>,
user_buf=<optimized out>, count=<optimized out>, ppos=0x80d97f10) at
/build/sborikar/bodegadev/bodega-dev/mcpu/firmware/linux-4.4/fs/kernfs/file.c:312
#3 0x801c9020 in __vfs_write (file=0x24b0, p=<optimized out>,
count=<optimized out>, pos=<optimized out>) at
/build/sborikar/bodegadev/bodega-dev/mcpu/firmware/linux-4.4/fs/read_write.c:489
#4 0x801c9eac in vfs_write (file=0x83b187c0, buf=0xa <Address 0xa out
of bounds>, count=<optimized out>, pos=0x80d97f10) at
/build/sborikar/bodegadev/bodega-dev/mcpu/firmware/linux-4.4/fs/read_write.c:538
#5 0x801ca0dc in SYSC_write (count=<optimized out>, buf=<optimized
out>, fd=<optimized out>) at
/build/sborikar/bodegadev/bodega-dev/mcpu/firmware/linux-4.4/fs/read_write.c:585
#6 SyS_write (fd=<optimized out>, buf=<optimized out>,
count=<optimized out>) at
/build/sborikar/bodegadev/bodega-dev/mcpu/firmware/linux-4.4/fs/read_write.c:578
#7 0x8010e1dc in syscall_common () at
/build/sborikar/bodegadev/bodega-dev/mcpu/firmware/linux-4.4/arch/mips/kernel/scall32-o32.S:102
Any idea?
Thanks
Sagar
8 years, 2 months
[PATCH] mips: support help -r
by Rabin Vincent
From: Rabin Vincent <rabinv(a)axis.com>
Add support form printing out the registers from the dump file. We
don't take the registers directly from the ELF notes but instead use the
version we've saved into the machine_specific structure. If we don't do
this, we'd get misleading output when the number of ELF notes don't
match the number of online CPUs.
---
defs.h | 11 ++++++++++
mips.c | 6 +-----
netdump.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 84 insertions(+), 7 deletions(-)
diff --git a/defs.h b/defs.h
index 0384f4e..9daf792 100644
--- a/defs.h
+++ b/defs.h
@@ -3128,6 +3128,17 @@ struct arm64_stackframe {
#define _SECTION_SIZE_BITS 26
#define _MAX_PHYSMEM_BITS 32
+
+#define MIPS32_EF_R0 6
+#define MIPS32_EF_R29 35
+#define MIPS32_EF_R31 37
+#define MIPS32_EF_LO 38
+#define MIPS32_EF_HI 39
+#define MIPS32_EF_CP0_EPC 40
+#define MIPS32_EF_CP0_BADVADDR 41
+#define MIPS32_EF_CP0_STATUS 42
+#define MIPS32_EF_CP0_CAUSE 43
+
#endif /* MIPS */
#ifdef X86
diff --git a/mips.c b/mips.c
index 4eeab55..6cd8d1f 100644
--- a/mips.c
+++ b/mips.c
@@ -47,10 +47,6 @@ typedef ulong pte_t;
#define MIPS_CPU_RIXI 0x00800000llu
-#define MIPS32_EF_R0 6
-#define MIPS32_EF_R29 35
-#define MIPS32_EF_R31 37
-#define MIPS32_EF_CPU0_EPC 40
static struct machine_specific mips_machine_specific = { 0 };
@@ -650,7 +646,7 @@ mips_dumpfile_stack_frame(struct bt_info *bt, ulong *nip, ulong *ksp)
}
regs = &ms->crash_task_regs[bt->tc->processor];
- epc = regs->regs[MIPS32_EF_CPU0_EPC];
+ epc = regs->regs[MIPS32_EF_CP0_EPC];
r29 = regs->regs[MIPS32_EF_R29];
if (!epc && !r29) {
diff --git a/netdump.c b/netdump.c
index 3350c28..4b5af9c 100644
--- a/netdump.c
+++ b/netdump.c
@@ -2505,7 +2505,8 @@ display_regs_from_elf_notes(int cpu, FILE *ofp)
}
}
- if ((cpu - skipped_count) >= nd->num_prstatus_notes) {
+ if ((cpu - skipped_count) >= nd->num_prstatus_notes &&
+ !machine_type("MIPS")) {
error(INFO, "registers not collected for cpu %d\n", cpu);
return;
}
@@ -2691,6 +2692,74 @@ display_regs_from_elf_notes(int cpu, FILE *ofp)
ULONG(user_regs + sizeof(ulong) * 32),
ULONG(user_regs + sizeof(ulong) * 33),
UINT(user_regs + sizeof(ulong) * 34));
+ } if (machine_type("MIPS")) {
+ const struct machine_specific *ms = machdep->machspec;
+ struct mips_regset *regs;
+
+ if (!ms->crash_task_regs) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ regs = &ms->crash_task_regs[cpu];
+ if (!regs->regs[MIPS32_EF_R29] && !regs->regs[MIPS32_EF_CP0_EPC]) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ fprintf(ofp,
+ " R0: %08lx R1: %08lx R2: %08lx\n"
+ " R3: %08lx R4: %08lx R5: %08lx\n"
+ " R6: %08lx R7: %08lx R8: %08lx\n"
+ " R9: %08lx R10: %08lx R11: %08lx\n"
+ " R12: %08lx R13: %08lx R14: %08lx\n"
+ " R15: %08lx R16: %08lx R17: %08lx\n"
+ " R18: %08lx R19: %08lx R20: %08lx\n"
+ " R21: %08lx R22: %08lx R23: %08lx\n"
+ " R24: %08lx R25: %08lx R26: %08lx\n"
+ " R27: %08lx R28: %08lx R29: %08lx\n"
+ " R30: %08lx R31: %08lx\n"
+ " LO: %08lx HI: %08lx\n"
+ " EPC: %08lx BADVADDR: %08lx\n"
+ " STATUS: %08lx CAUSE: %08lx\n",
+ regs->regs[MIPS32_EF_R0],
+ regs->regs[MIPS32_EF_R0 + 1],
+ regs->regs[MIPS32_EF_R0 + 2],
+ regs->regs[MIPS32_EF_R0 + 3],
+ regs->regs[MIPS32_EF_R0 + 4],
+ regs->regs[MIPS32_EF_R0 + 5],
+ regs->regs[MIPS32_EF_R0 + 6],
+ regs->regs[MIPS32_EF_R0 + 7],
+ regs->regs[MIPS32_EF_R0 + 8],
+ regs->regs[MIPS32_EF_R0 + 9],
+ regs->regs[MIPS32_EF_R0 + 10],
+ regs->regs[MIPS32_EF_R0 + 11],
+ regs->regs[MIPS32_EF_R0 + 12],
+ regs->regs[MIPS32_EF_R0 + 13],
+ regs->regs[MIPS32_EF_R0 + 14],
+ regs->regs[MIPS32_EF_R0 + 15],
+ regs->regs[MIPS32_EF_R0 + 16],
+ regs->regs[MIPS32_EF_R0 + 17],
+ regs->regs[MIPS32_EF_R0 + 18],
+ regs->regs[MIPS32_EF_R0 + 19],
+ regs->regs[MIPS32_EF_R0 + 20],
+ regs->regs[MIPS32_EF_R0 + 21],
+ regs->regs[MIPS32_EF_R0 + 22],
+ regs->regs[MIPS32_EF_R0 + 23],
+ regs->regs[MIPS32_EF_R0 + 24],
+ regs->regs[MIPS32_EF_R0 + 25],
+ regs->regs[MIPS32_EF_R0 + 26],
+ regs->regs[MIPS32_EF_R0 + 27],
+ regs->regs[MIPS32_EF_R0 + 28],
+ regs->regs[MIPS32_EF_R0 + 29],
+ regs->regs[MIPS32_EF_R0 + 30],
+ regs->regs[MIPS32_EF_R0 + 31],
+ regs->regs[MIPS32_EF_LO],
+ regs->regs[MIPS32_EF_HI],
+ regs->regs[MIPS32_EF_CP0_EPC],
+ regs->regs[MIPS32_EF_CP0_BADVADDR],
+ regs->regs[MIPS32_EF_CP0_STATUS],
+ regs->regs[MIPS32_EF_CP0_CAUSE]);
}
}
@@ -2700,7 +2769,8 @@ dump_registers_for_elf_dumpfiles(void)
int c;
if (!(machine_type("X86") || machine_type("X86_64") ||
- machine_type("ARM64") || machine_type("PPC64")))
+ machine_type("ARM64") || machine_type("PPC64") ||
+ machine_type("MIPS")))
error(FATAL, "-r option not supported for this dumpfile\n");
if (NETDUMP_DUMPFILE()) {
--
2.1.4
8 years, 2 months
[PATCH 1/3] mips: set HZ to 100
by Rabin Vincent
From: Rabin Vincent <rabinv(a)axis.com>
Set a default value for machdep->hz to 100, which will be used if the in
kernel config data is unavailable.
---
mips.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/mips.c b/mips.c
index a4fc8b6..7ad6f61 100644
--- a/mips.c
+++ b/mips.c
@@ -57,6 +57,7 @@ static struct machine_specific mips_machine_specific = { 0 };
static void
mips_display_machine_stats(void)
{
+ fprintf(fp, " HZ: %d\n", machdep->hz);
fprintf(fp, " PAGE SIZE: %d\n", PAGESIZE());
fprintf(fp, "\n");
@@ -776,6 +777,7 @@ mips_dump_machdep_table(ulong arg)
fprintf(fp, " ptrs_per_pgd: %lu\n", PTRS_PER_PGD);
fprintf(fp, " ptrs_per_pte: %d\n", PTRS_PER_PTE);
fprintf(fp, " stacksize: %ld\n", machdep->stacksize);
+ fprintf(fp, " hz: %d\n", machdep->hz);
fprintf(fp, " memsize: %lld (0x%llx)\n",
machdep->memsize, machdep->memsize);
fprintf(fp, " bits: %d\n", machdep->bits);
@@ -904,6 +906,9 @@ mips_init(int when)
ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
"irq_desc", NULL, 0);
mips_stackframe_init();
+
+ if (!machdep->hz)
+ machdep->hz = 100;
break;
}
}
--
2.1.4
8 years, 2 months
"invalid structure member" on linux-4.9-rc1
by Steve Wise
Hi,
I'm trying to use the latest crash via the git repo, on the just
released linux-4.9-rc1 kernel, and I'm hitting this failure when loading
the vmcore. Any ideas?
My crash git HEAD is:
commit 64531dc850f2840cedafa143fe051d2cfeae5247
Author: Dave Anderson <anderson(a)redhat.com>
Date: Thu Oct 13 14:32:43 2016 -0400
crash-7.1.5 -> crash-7.1.6
[root@stevo1 crash]# ./crash /usr/local/src/linux-2.6/vmlinux
/var/crash/127.0.0.1-2016-10-17-02\:12\:50/vmcore
crash 7.1.6
Copyright (C) 2002-2016 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011 NEC Corporation
Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
crash: cannot determine thread return address
please wait... (gathering task table data)
crash: invalid structure member offset: thread_info_cpu
FILE: task.c LINE: 2364 FUNCTION: store_context()
[./crash] error trace: 4caf3c => 4c3010 => 4bbac6 => 51da6d
51da6d: OFFSET_verify+189
4bbac6: store_context+1030
4c3010: refresh_hlist_task_table_v3+2256
4caf3c: task_init+3724
[root@stevo1 crash]#
Thanks,
Steve.
8 years, 2 months
[ANNOUNCE] crash version 7.1.6 is available
by Dave Anderson
Download from: http://people.redhat.com/anderson
or
https://github.com/crash-utility/crash/releases
The github master branch serves as a development branch that will contain
all patches that are queued for the next release:
$ git clone git://github.com/crash-utility/crash.git
Changelog:
- Introduction of support for "live" ramdump files, such as those that
are specified by the QEMU mem-path argument of a memory-backend-file
object. This allows the running of a live crash session against a
QEMU guest from the host machine. In this example, the /tmp/MEM file
on a QEMU host represents the guest's physical memory:
$ qemu-kvm ...other-options... \
-object memory-backend-file,id=MEM,size=128m,mem-path=/tmp/MEM,share=on \
-numa node,memdev=MEM -m 128
and a live session run can be run against the guest kernel like so:
$ crash <path-to-guest-vmlinux> live:/tmp/MEM@0
By prepending the ramdump image name with "live:", the crash session will
act as if it were running a normal live session.
(oleg(a)redhat.com)
- Fix for the support of ELF vmcores created by the KVM "virsh dump
--memory-only" facility if the guest kernel was not configured with
CONFIG_KEXEC, or CONFIG_KEXEC_CORE in Linux 4.3 and later kernels.
Without the patch, the crash session fails during initialization with
the message "crash: cannot resolve kexec_crash_image".
(hirofumi(a)mail.parknet.co.jp)
- Added support for x86_64 ramdump files. Without the patch, the crash
session fails immediately with the message "ramdump: unsupported
machine type: X86_64".
(anderson(a)redhat.com)
- Fix for a "[-Werror=misleading-indentation]" compiler warning that
is generated by gdb-7.6/bfd/elf64-s390.c when building S390X in a
Fedora Rawhide environment with gcc-6.0.0
(anderson(a)redhat.com)
- Recognize and parse the new QEMU_VM_CONFIGURATION and QEMU_VM_FOOTER
sections used for live migration of KVM guests, which are seen in
the "kvmdump" format generated if "virsh dump" is used without the
"--memory-only" option.
(pagupta(a)redhat.com)
- Fix for Linux commit edf14cdbf9a0e5ab52698ca66d07a76ade0d5c46, which
has appended a NULL entry as the final member of the pageflag_names[]
array. Without the patch, a message that indicates "crash: failed to
read pageflag_names entry" is displayed during session initialization
in Linux 4.6 kernels.
(andrej.skvortzov(a)gmail.com)
- Fix for Linux commit 0139aa7b7fa12ceef095d99dc36606a5b10ab83a, which
renamed the page._count member to page._refcount. Without the patch,
certain "kmem" commands fail with the "kmem: invalid structure member
offset: page_count".
(anderson(a)redhat.com)
- Fix for an ARM64 crash-7.1.5 "bt" regression for a task that has
called panic(). Without the patch, the backtrace may fail with a
message such as "bt: WARNING: corrupt prstatus? pstate=0x20000000,
but no user frame found" followed by "bt: WARNING: cannot determine
starting stack frame for task <address>". The pstate register
warning will still be displayed (as it is essentially a kdump bug),
but the backtrace will proceed normally.
(anderson(a)redhat.com)
- Fix for the ARM64 "bt" command in Linux 4.5 and later kernels which
use per-cpu IRQ stacks. Without the patch, if an active non-crashing
task was running in user space when it received the shutdown IPI from
the crashing task, the "-- <IRQ stack> ---" transition marker from
the IRQ stack to the process stack is not displayed, and a message
indicating "bt: WARNING: arm64_unwind_frame: on IRQ stack: oriq_sp:
<address> fp: 0 (?)" gets displayed.
(anderson(a)redhat.com)
- Fix for the ARM64 "bt" command in Linux 4.5 and later kernels which
are not configured with CONFIG_FUNCTION_GRAPH_TRACER. Without the
patch, backtraces that originate from a per-cpu IRQ stack will dump
an invalid exception frame before transitioning to the process stack.
(anderson(a)redhat.com)
- Introduction of ARM64 support for 4K pages with 4-level page tables
and 48 VA bits.
(takahiro.akashi(a)linaro.org)
- Implemented support for the redesigned ARM64 kernel virtual memory
layout and associated KASLR support that was introduced in Linux 4.6.
The kernel text and static data has been moved from unity-mapped
memory into the vmalloc region, and its start address can be
randomized if CONFIG_RANDOMIZE_BASE is configured. Related support
is being put into the kernel's kdump code, the kexec-tools package,
and makedumpfile(8); with that in place, the analysis of Linux 4.6
ARM64 dumpfiles with or without KASLR enabled should work normally
by entering "crash vmlinux vmcore". On live systems, Linux 4.6 ARM64
kernels will only work automatically if CONFIG_RANDOMIZE_BASE is not
configured. Unfortunately, if CONFIG_RANDOMIZE_BASE is configured
on a live system, two --machdep command line arguments are required,
at least for the time being. The arguments are:
--machdep phys_offset=<base physical address>
--machdep kimage_voffset=<kernel kimage_voffset value>
Without the patch, any attempt to analyze a Linux 4.6 ARM64 kernel
fails during initialization with a stream of "read error" messages
followed by "crash: vmlinux and vmcore do not match!".
(takahiro.akashi(a)linaro.org)
- Linux 3.15 and later kernels configured with CONFIG_RANDOMIZE_BASE
could be identified because of the "randomize_modules" kernel symbol,
and if it existed, the "--kaslr=<offset>" and/or "--kaslr=auto"
options were unnecessary. Since the "randomize_modules" symbol was
removed in Linux 4.1, this patch has replaced the KASLR identifier
with the "module_load_offset" symbol, which was also introduced in
Linux 3.15, but still remains.
(anderson(a)redhat.com)
- Improvement of the ARM64 "bt -f" display such that in most cases,
each stack frame level delimiter will be set to the stack address
location containing the old FP and old LR pair.
(takahiro.akashi(a)linaro.org)
- Fix for the introduction of ARM64 support for 64K pages with 3-level
page tables in crash-7.1.5, which fails to translate user space
virtual addresses. Without the patch, "vtop <user-space address>"
fails to translate all user-space addresses, and any command that
needs to either translate or read user-space memory, such as "vm -p",
"ps -a", and "rd -u" will fail.
(anderson(a)redhat.com)
- Enhancement of the error message generated by the "tree -t radix"
option when a duplicate entry is encountered. Without the patch,
the error message shows the address of the radix_tree_node that
contains the duplicate entry, for example, "tree: duplicate tree
entry: <radix_tree_node>". It has been changed to also display
the radix_tree_node.slots[] array index and the duplicate entry
value, for example, "tree: duplicate tree entry: radix_tree_node:
<radix_tree_node> slots[<index>]: <entry>".
(anderson(a)redhat.com)
- Introduction of a new "bt -v" option that checks the kernel stack of
all tasks for evidence of stack overflows. It does so by verifying
the thread_info.task address, ensuring the thread_info.cpu value is
a valid cpu number, and checking the end of the stack for the
STACK_END_MAGIC value.
(anderson(a)redhat.com)
- Fix to recognize a kernel thread that has user space virtual memory
attached to it. While kernel threads typically do not have an
mm_struct referencing a user-space virtual address space, they can
either temporarily reference one for a user-space copy operation, or
in the case of KVM "vhost" kernel threads, keep a reference to the
user space of the "quem-kvm" task that created them. Without the
patch, they will be mistaken for user tasks; the "bt" command will
display an invalid kernel-entry exception frame that indicates
"[exception RIP: unknown or invalid address]", the "ps" command
will not enclose the command name with brackets, and the "ps -[uk]"
and "foreach [user|kernel]" options will show the kernel thread as
a user task.
(anderson(a)redhat.com)
- Fix for the "bt -[eE]" options on ARM64 to recognize kernel exception
frames in VHE enabled systems, in which the kernel runs in EL2.
(takahiro.akashi(a)linaro.org)
- Fix for the extensions/trace.c extension module to account for the
Linux 4.7 kernel commit dcb0b5575d24 that changed the bit index for
the TRACE_EVENT_FL_TRACEPOINT flag. Without the patch, the "extend"
command fails to load the trace.so module, with the error message
"extend: /path/to/crash/extensions/trace.so: no commands registered:
shared object unloaded". The patch reads the flag's enum value
dynamically instead of using a hard-coded value.
(namhyung(a)gmail.com)
- Incorporated Takahiro Akashi's alternative backtrace method as a
"bt" option, which can be accessed using "bt -o", and where "bt -O"
will toggle the original and optional methods as the default. The
original backtrace method has adopted two changes/features from
the optional method:
(1) ORIG_X0 and SYSCALLNO registers are not displayed in kernel
exception frames.
(2) stackframe entry text locations are modified to be the PC
address of the branch instruction instead of the subsequent
"return" PC address contained in the stackframe link register.
Accordingly, these are the essential differences between the original
and optional methods:
(1) optional: the backtrace will start with the IPI exception frame
located on the process stack.
(2) original: the starting point of backtraces for the active,
non-crashing, tasks, will continue to have crash_save_cpu()
on the IRQ stack as the starting point.
(3) optional: the exception entry stackframe adjusted to be located
farther down in the IRQ stack.
(4) optional: bt -f does not display IRQ stack memory above the
adjusted exception entry stackframe.
(5) optional: may display "(Next exception frame might be wrong)".
(takahiro.akashi(a)linaro.org, anderson(a)redhat.com)
- Fix for the failure of the "sym <symbol>" option in the extremely
unlikely case where the symbol's name string is composed entirely of
hexadecimal characters. For example, without the patch, "sym e820"
fails with the error message "sym: invalid address: e820".
(anderson(a)redhat.com)
- Fix for the failure of the "dis <symbol>" option in the extremely
unlikely case where the symbol's name string is composed entirely of
hexadecimal characters. For example, without the patch, "dis f"
fails with the error message "dis: WARNING: f: no associated kernel
symbol found" followed by "0xf: Cannot access memory at address 0xf".
(anderson(a)redhat.com)
- Fix for the X86_64 "bt -R <symbol>" option if the only reference
to the kernel text symbol in a backtrace is contained within the
"[exception RIP: <symbol+offset>]" line of an exception frame
dump. Without the patch, the reference will only be picked up if
the exception RIP's hexadecimal address value is used.
(anderson(a)redhat.com)
- Fix for the ARM64 "bt -R <symbol>" option if the only reference
to the kernel text symbol in a backtrace is contained within the
"[PC: <address> [<symbol+offset>]" line of an exception frame
dump. Without the patch, the reference will only be picked up if
the PC's hexadecimal address value is used.
(anderson(a)redhat.com)
- Fix for the gathering of module symbol name strings during session
initialization. In the unlikely case where the ordering of module
symbol name strings does not match the order of the kernel_symbol
structures, a faulty module symbol list entry may be created that
contains a bogus name string.
(sebastien.piechurski(a)bull.net)
- Fix the PERCENTAGE of total output of the "kmem -i" SWAP USED line
when the system has no swap pages at all. Without the patch, both
the PAGES and TOTAL columns show values of zero, but it confusingly
shows "100% of TOTAL SWAP", which upon first glance may seem to
indicate potential memory pressure.
(jsiddle(a)redhat.com)
- Enhancement to determine structure member data if the member is
contained within an anonymous structure or union. Without the patch,
it is necessary to parse the output of a discrete gdb "printf"
command to determine the offset of such a structure member.
(Alexandr_Terekhov(a)epam.com)
- Speed up session initialization by attempting MEMBER_OFFSET_INIT()
before falling back to ANON_MEMBER_OFFSET_INIT() in several known
cases of structure members that are contained within anonymous
structures.
(anderson(a)redhat.com)
- Implemented new "list -S" and "tree -S" options that are similar to
each command's -s option, but instead of parsing gdb output, member
values are read directly from memory, so the command is much faster
for 1-, 2-, 4-, and 8-byte members.
(Alexandr_Terekhov(a)epam.com)
- Fix to recognize and support x86_64 Linux 4.8-rc1 and later kernels
that are configured with CONFIG_RANDOMIZE_MEMORY, which randomizes
the base addresses of the kernel's unity-map address (PAGE_OFFSET),
and the vmalloc region. Without the patch, the crash utility fails
with a segmentation violation during session initialization on a
live system, or will generate a number of WARNING messages followed
by the fatal error message "crash: vmlinux and <dumpfile name> do
not match!" with dumpfiles.
(anderson(a)redhat.com)
- Fix for Linux 4.1 commit d0a0de21f82bbc1737ea3c831f018d0c2bc6b9c2,
which renamed the x86_64 "init_tss" per-cpu variable to "cpu_tss".
Without the patch, the addresses of the 4 per-cpu exception stacks
cannot be determined, which causes backtraces that originate on
any of the per-cpu DOUBLEFAULT, NMI, DEBUG, or MCE stacks to be
truncated.
(anderson(a)redhat.com)
- With the introduction of radix MMU in Power ISA 3.0, there are
changes in kernel page table management accommodating it. This patch
series makes appropriate changes here to work for such kernels.
Also, this series fixes a few bugs along the way:
ppc64: fix vtop page translation for 4K pages
ppc64: Use kernel terminology for each level in 4-level page table
ppc64/book3s: address changes in kernel v4.5
ppc64/book3s: address change in page flags for PowerISA v3.0
ppc64: use physical addresses and unfold pud for 64K page size
ppc64/book3s: support big endian Linux page tables
The patches are needed for Linux v4.5 and later kernels on all
ppc64 hardware.
(hbathini(a)linux.vnet.ibm.com)
- Fix for Linux 4.8-rc1 commit 500462a9de657f86edaa102f8ab6bff7f7e43fc2,
in which Thomas Gleixner redesigned the kernel timer mechanism to
switch to a non-cascading wheel. Without the patch, the "timer"
command fails with the message "timer: zero-size memory allocation!
(called from <address>)"
(anderson(a)redhat.com)
- Support for PPC64/BOOK3S virtual address translation for radix MMU.
As both radix and hash MMU are supported in a single kernel on
Power ISA 3.0 based server processors, identify the current MMU
type and set page table index values accordingly. Also, in Linux
4.7 and later kernels, PPC64/BOOK3S uses the same masked bit values
in page table entries for 4K and 64K page sizes.
(hbathini(a)linux.vnet.ibm.com)
- Change the RESIZEBUF() macro so that it will accept buffer pointers
that are not declared as "char *" types. Change two prior direct
callers of resizebuf() to use RESIZEBUF(), and fix two prior users of
RESIZEBUF() to correctly calculate the need to resize their buffers.
(anderson(a)redhat.com)
- Fix for the "trace.so" extension module to properly recognize Linux
3.15 and later kernels. In crash-7.1.6, the MEMBER_OFFSET() macro
has been improved so that it is able to recognize members of embedded
anonymous structures. However, the module's manner of recognizing
Linux 3.15 and later kernels depended upon MEMBER_OFFSET() failing
to handle anonymous members, and therefore the improvement prevented
the module from successfully loading.
(rabinv(a)axis.com)
- If a "struct" command address argument is expressed using the per-cpu
"symbol:cpuspec" format, and the symbol is a pointer type, i.e., not
the address of the structure, display a WARNING message.
(atomlin(a)redhat.com)
- Exclude ARM64 kernel module linker mapping symbols like "$d" and "$x"
as is done with 32-bit ARM. Without the patch, a crash session may
fail during the "gathering module symbol data" stage with a message
similar to "crash: store_module_symbols_v2: total: 15 mcnt: 16".
(takahiro.akashi(a)linaro.org)
- Enhancement to the ARM64 "dis" command when the kernel has enabled
KASLR. When KASLR is enabled on ARM64, a function call between a
module and the base kernel code will be done via a veneer (PLT) if
the displacement is more than +/-128MB. As a result, disassembled
code will show a branch to the in-module veneer location instead of
the in-kernel target location. To avoid confusion, the output of
the "dis" command will translate the veneer location to the target
location preceded by "plt:", for example, "<plt:printk>".
(takahiro.akashi(a)linaro.org)
- Improvement of the "dev -d" option to display I/O statics for disks
whose device driver uses the blk-mq interface. Currently "dev -d"
always displays 0 in all fields for the blk-mq disk because blk-mq
does not increment/decrement request_list.count[2] on I/O creation
and I/O completion. The following values are used in blk-mq in such
situations:
- I/O creation: blk_mq_ctx.rq_dispatched[2]
- I/O completion: blk_mq_ctx.rq_completed[2]
So, we can get the counter of in-progress I/Os as follows:
in progress I/Os == rq_dispatched - rq_completed
This patch displays the result of above calculation for the disk.
It determines whether the device driver uses blk-mq if the
request_queue.mq_ops is not NULL. The "DRV" field is displayed as
"N/A(MQ)" if the value for in-flight in the device driver does not
exist for blk-mq.
(m.mizuma(a)jp.fujitsu.com)
8 years, 2 months
[PATCH] dev: improvement for displaying I/O statics for blk-mq disk
by Masayoshi Mizuma
Improvement -d option of dev command to display I/O statics
for the disk which the device driver uses blk-mq interface.
Current dev -d displays always 0 in the all fields for the
blk-mq disk because blk-mq does not increment/decrement to
request_list.count[2] on I/O creation and I/O completion.
The following value is used in blk-mq on such situation.
- I/O creation: blk_mq_ctx.rq_dispatched[2]
- I/O completion: blk_mq_ctx.rq_completed[2]
So, we can get the counter of in progress I/Os as follows.
in progress I/Os == rq_dispatched - rq_completed
This patch displays the result of above calculation for the
disk. It judges as the device driver uses blk-mq if the
request_queue.mq_ops is not NULL.
"DRV" field is displayed as "N/A(MQ)" because the value for in-flight
in the device driver is not exists for blk-mq...
Signed-off-by: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
---
defs.h | 4 +++
dev.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
help.c | 4 ++-
3 files changed, 96 insertions(+), 10 deletions(-)
diff --git a/defs.h b/defs.h
index a09fa9a..55c28c5 100755
--- a/defs.h
+++ b/defs.h
@@ -1822,6 +1822,10 @@ struct offset_table { /* stash of commonly-used offsets */
long request_list_count;
long request_queue_in_flight;
long request_queue_rq;
+ long request_queue_mq_ops;
+ long request_queue_queue_ctx;
+ long blk_mq_ctx_rq_dispatched;
+ long blk_mq_ctx_rq_completed;
long subsys_private_klist_devices;
long subsystem_kset;
long mount_mnt_parent;
diff --git a/dev.c b/dev.c
index c18f40e..e46081e 100644
--- a/dev.c
+++ b/dev.c
@@ -3800,18 +3800,84 @@ again:
return i->get_gendisk(klist_node_address);
}
+static int
+use_mq_interface(unsigned long q)
+{
+ unsigned long mq_ops;
+
+ if (!VALID_MEMBER(request_queue_mq_ops))
+ return 0;
+
+ readmem(q + OFFSET(request_queue_mq_ops), KVADDR, &mq_ops,
+ sizeof(ulong), "request_queue.mq_ops", FAULT_ON_ERROR);
+
+ if (mq_ops == 0)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+get_one_mctx_diskio(unsigned long mctx, struct diskio *io)
+{
+ unsigned long dispatch[2];
+ unsigned long comp[2];
+
+ readmem(mctx + OFFSET(blk_mq_ctx_rq_dispatched),
+ KVADDR, dispatch, sizeof(ulong) * 2, "blk_mq_ctx.rq_dispatched",
+ FAULT_ON_ERROR);
+
+ readmem(mctx + OFFSET(blk_mq_ctx_rq_completed),
+ KVADDR, comp, sizeof(ulong) * 2, "blk_mq_ctx.rq_completed",
+ FAULT_ON_ERROR);
+
+ io->read = (dispatch[0] - comp[0]);
+ io->write = (dispatch[1] - comp[1]);
+}
+
+static void
+get_mq_diskio(unsigned long q, unsigned long *mq_count)
+{
+ int cpu;
+ unsigned long queue_ctx;
+ unsigned long mctx_addr;
+ struct diskio tmp;
+
+ memset(&tmp, 0x00, sizeof(struct diskio));
+
+ readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
+ sizeof(ulong), "request_queue.queue_ctx",
+ FAULT_ON_ERROR);
+
+ for (cpu = 0; cpu < kt->cpus; cpu++) {
+ if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) {
+ mctx_addr = queue_ctx + kt->__per_cpu_offset[cpu];
+ get_one_mctx_diskio(mctx_addr, &tmp);
+ mq_count[0] += tmp.read;
+ mq_count[1] += tmp.write;
+ }
+ }
+}
+
/* read request_queue.rq.count[2] */
static void
get_diskio_1(unsigned long rq, struct diskio *io)
{
int count[2];
+ unsigned long mq_count[2] = { 0 };
- readmem(rq + OFFSET(request_queue_rq) + OFFSET(request_list_count),
- KVADDR, count, sizeof(int) * 2, "request_list.count",
- FAULT_ON_ERROR);
+ if (!use_mq_interface(rq)) {
+ readmem(rq + OFFSET(request_queue_rq) +
+ OFFSET(request_list_count), KVADDR, count,
+ sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
- io->read = count[0];
- io->write = count[1];
+ io->read = count[0];
+ io->write = count[1];
+ } else {
+ get_mq_diskio(rq, mq_count);
+ io->read = mq_count[0];
+ io->write = mq_count[1];
+ }
}
/* request_queue.in_flight contains total requests */
@@ -3961,9 +4027,8 @@ display_one_diskio(struct iter *i, unsigned long gendisk)
readmem(gendisk + OFFSET(gendisk_major), KVADDR, &major, sizeof(int),
"gen_disk.major", FAULT_ON_ERROR);
i->get_diskio(queue_addr, &io);
- in_flight = i->get_in_flight(queue_addr);
- fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s%5u\n",
+ fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
space(MINSPACE),
mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
@@ -3980,8 +4045,13 @@ display_one_diskio(struct iter *i, unsigned long gendisk)
space(MINSPACE),
mkstring(buf5, 5, RJUST|INT_DEC,
(char *)(unsigned long)io.write),
- space(MINSPACE),
- in_flight);
+ space(MINSPACE));
+
+ if (!use_mq_interface(queue_addr)) {
+ in_flight = i->get_in_flight(queue_addr);
+ fprintf(fp, "%5u\n", in_flight);
+ } else
+ fprintf(fp, "%s\n", "N/A(MQ)");
}
static void
@@ -4056,6 +4126,16 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(request_queue_rq, "request_queue", "rq");
else
MEMBER_OFFSET_INIT(request_queue_rq, "request_queue", "root_rl");
+ if (MEMBER_EXISTS("request_queue", "mq_ops")) {
+ MEMBER_OFFSET_INIT(request_queue_mq_ops, "request_queue",
+ "mq_ops");
+ ANON_MEMBER_OFFSET_INIT(request_queue_queue_ctx,
+ "request_queue", "queue_ctx");
+ MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",
+ "rq_dispatched");
+ MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
+ "rq_completed");
+ }
MEMBER_OFFSET_INIT(subsys_private_klist_devices, "subsys_private",
"klist_devices");
MEMBER_OFFSET_INIT(subsystem_kset, "subsystem", "kset");
diff --git a/help.c b/help.c
index 938251f..cfa0516 100644
--- a/help.c
+++ b/help.c
@@ -2684,7 +2684,9 @@ char *help_dev[] = {
" ASYNC: I/O requests that are asynchronous",
" READ: I/O requests that are reads (older kernels)",
" WRITE: I/O requests that are writes (older kernels)",
-" DRV: I/O requests that are in-flight in the device driver",
+" DRV: I/O requests that are in-flight in the device driver.",
+" If the device driver uses blk-mq interface, this field",
+" shows N/A(MQ).",
"\nEXAMPLES",
" Display character and block device data:\n",
" %s> dev",
--
1.8.3.1
8 years, 2 months
vmss.core and kernel dbgsym do not match!
by Eric Desrochers
Hi,
In reference to bug : https://bugzilla.redhat.com/show_bug.cgi?id=233151
I have the same problem trying to analyze a vmss.core file with kernel v4.4.0-36-generic (Ubuntu) :
crash: /usr/lib/debug/boot/*vmlinux-4.4.0-36-generic* and /var/vmss_m.core do not match!
I also tried with the following (as recommended in the bug threads) without success :
--machdep phys_base=0x200000
I'm using the right -dbgsym for the right kernel as confirmed here :
$ strings vmss_m.core | grep "Linux version"
Linux version *4.4.0-36-generic* (buildd@lgw01-20) (gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) ) #55~14.04.1-Ubuntu SMP Fri Aug 12 11:49:30 UTC 2016 (Ubuntu 4.4.0-36.55~14.04.1-generic 4.4.16)
$ readelf -a vmss_m.core
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
NOTE 0x00000000000000e8 0x0000000000000000 0x0000000000000000
0x0000000000000218 0x0000000000000000 0
LOAD 0x0000000080001000 0x00000000fff80000 0x00000000fff80000
0x0000000000080000 0x0000000000080000 RWE 1000
LOAD 0x0000000000001000 0x0000000000000000 0x0000000000000000
0x0000000080000000 0x0000000080000000 RWE 1000
The VirtAddr and PhysAddr are just zero.
I tried with the latest and greatest crash-utility from [https://github.com/crash-utility/crash.git] using version 7.1.5++ but this has no effect, I still have the error :
crash: /usr/lib/debug/boot/*vmlinux-4.4.0-36-generic* and /var/vmss_m.core do not match!
Any ideas ?
- Eric
8 years, 2 months
[RFC] arm64: symbolize PLT entries in disassembling module functions
by AKASHI Takahiro
Signed-off-by: AKASHI Takahiro <takahiro.akashi(a)linaro.org>
---
arm64.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/arm64.c b/arm64.c
index b9fa14d..8235e3c 100644
--- a/arm64.c
+++ b/arm64.c
@@ -2540,6 +2540,59 @@ arm64_is_task_addr(ulong task)
return (IS_KVADDR(task) && (ALIGNED_STACK_OFFSET(task) == 0));
}
+static ulong
+PLT_veneer_to_kvaddr(ulong value)
+{
+ uint32_t insn;
+ ulong addr = 0;
+ int i;
+
+ /*
+ * PLT veneer always looks:
+ * movn x16, #0x....
+ * movk x16, #0x...., lsl #16
+ * movk x16, #0x...., lsl #32
+ * br x16
+ */
+ for (i = 0; i < 4; i++) {
+ if (!readmem(value + i * sizeof(insn), KVADDR, &insn,
+ sizeof(insn), "PLT veneer", RETURN_ON_ERROR)) {
+ error(WARNING, "cannot read PLT veneer\n");
+ return value;
+ }
+ switch (i) {
+ case 0:
+ if ((insn & 0xffe0001f) != 0x92800010)
+ goto not_plt;
+ addr = ~((ulong)(insn & 0x1fffe0) >> 5);
+ break;
+ case 1:
+ if ((insn & 0xffe0001f) != 0xf2a00010)
+ goto not_plt;
+ addr &= 0xffffffff0000ffff;
+ addr |= (ulong)(insn & 0x1fffe0) << (16 - 5);
+ break;
+ case 2:
+ if ((insn & 0xffe0001f) != 0xf2c00010)
+ goto not_plt;
+ addr &= 0xffff0000ffffffff;
+ addr |= (ulong)(insn & 0x1fffe0) << (32 - 5);
+ break;
+ case 3:
+ if (insn != 0xd61f0200)
+ goto not_plt;
+ break;
+ default:
+ return value; /* to avoid any warnings */
+ }
+ }
+
+ return addr;
+
+not_plt:
+ return value;
+}
+
/*
* Filter dissassembly output if the output radix is not gdb's default 10
*/
@@ -2589,6 +2642,22 @@ arm64_dis_filter(ulong vaddr, char *inbuf, unsigned int output_radix)
sprintf(p1, "%s", buf1);
}
+ if (IS_MODULE_VADDR(vaddr)) {
+ ulong orig_value;
+
+ p1 = &inbuf[strlen(inbuf)-1];
+ strcpy(buf1, inbuf);
+ argc = parse_line(buf1, argv);
+
+ if ((STREQ(argv[argc-2], "b") || STREQ(argv[argc-2], "bl")) &&
+ extract_hex(argv[argc-1], &orig_value, NULLCHAR, TRUE)) {
+ value = PLT_veneer_to_kvaddr(orig_value);
+ sprintf(p1, " <%s%s>\n",
+ value == orig_value ? "" : "plt:",
+ value_to_symstr(value, buf2, output_radix));
+ }
+ }
+
console(" %s", inbuf);
return TRUE;
--
2.10.0
8 years, 2 months
[PATCH] arm64: exclude mapping symbols in modules
by AKASHI Takahiro
If some module has been inserted, crash util complains about
module symbols:
...
please wait... (gathering module symbol data)
crash: store_module_symbols_v2: total: 15 mcnt: 16
and end up with stopping.
This patch excludes mapping symbols, like $d and $x, as arm does.
Signed-off-by: AKASHI Takahiro <takahiro.akashi(a)linaro.org>
---
symbols.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/symbols.c b/symbols.c
index 99c8b8b..a657ead 100644
--- a/symbols.c
+++ b/symbols.c
@@ -2251,10 +2251,11 @@ store_module_kallsyms_v2(struct load_module *lm, int start, int curr,
continue;
/*
- * On ARM we have linker mapping symbols like '$a' and '$d'.
+ * On ARM/ARM64 we have linker mapping symbols like '$a'
+ * or '$x' for ARM64, and '$d'.
* Make sure that these don't end up into our symbol list.
*/
- if (machine_type("ARM") &&
+ if ((machine_type("ARM") || machine_type("ARM64")) &&
!machdep->verify_symbol(nameptr, ec->st_value, ec->st_info))
continue;
--
2.10.0
8 years, 2 months