[crash-utility][ARM64][patch] Auto calculate kimage_voffset by kaslr offset
by �� �h��
Hi Dave,
In my develop enviroment, kaslr offset will be stored in SoC on-chip memory for debuging, but crash utility is not work if i only set kaslr offset by command '--kaslr XXX', it also need correct kimage_voffset.
error message without the patch:
VA_BITS: 39
using 40000000 as phys_offset
kimage_voffset: 0
phys_offset: 40000000
.....cut....
<readmem: ffffff9381e074a0, KVADDR, "cpu_possible_mask", 8, (FOE), 7fffce0dfa48>
<read_ramdump: addr: ffffff9381e074a0 paddr: 13b9e074a0 cnt: 8>
read_ramdump: READ_ERROR: offset not found for paddr: 13b9e074a0
crash: read error: kernel virtual address: ffffff9381e074a0 type: "cpu_possible_mask"
This patch add a function to auto calculate kimage_voffset by kaslr offset. Please review it.
Thanks,
Yueyi Li
7 years, 8 months
Use crash utility tool through cygwin
by Gourab Biswas
Hi Team,
We want to enable and use crash utility tool for crash analysis from Windows(Windows 7) machine through cygwin.
Please let us know whether is it feasible ??
If yes please let us know the procedure. Already tried enabling on Windows using Cygwin, but didn't work.
Thanks and Regards
Gourab Biswas
[logo]
HTIPL Bangalore RnD
7 years, 8 months
feature to dump audit logs in vmcore
by HATAYAMA Daisuke
Dave,
I wrote an extension module to dump audit logs in vmcore.
How about this in crash utility as a built-in command?
crash> extend /root/repos/crash-dumpaudit-command/src/dumpaudit.so
/root/repos/crash-dumpaudit-command/src/dumpaudit.so: shared object loaded
crash> dumpaudit
type=1300 audit(1489022639.875:164489): arch=c000003e syscall=0 success=yes exit=0 a0=5 a1=7fedd3b00000 a2=400 a3=22 items=0 ppid=2575 pid=10428 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm="pidof" exe="/usr/sbin/killall5" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=1320 audit(1489022639.875:164489):
type=1320 audit(1489022639.875:164487):
type=1300 audit(1489022639.875:164490): arch=c000003e syscall=3 success=yes exit=0 a0=5 a1=1 a2=8 a3=0 items=0 ppid=2575 pid=10428 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm="pidof" exe="/usr/sbin /killall5" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
...<cut>...
What the extension module does is so simple that it retrives audit
logs from a queue. Looking back into kernel git logs, this design that
audit logs are held in the queue, was introduced at the following
patch to introduce kauditd kernel thread and have never changed until
now:
# git describe b7d1125817c9a46cc46f57db89d9c195e7af22f8
v2.6.12-rc4-48-gb7d1125
# git log -1 -p b7d1125817c9a46cc46f57db89d9c195e7af22f8
commit b7d1125817c9a46cc46f57db89d9c195e7af22f8
Author: David Woodhouse <dwmw2(a)shinybook.infradead.org>
Date: Thu May 19 10:56:58 2005 +0100
AUDIT: Send netlink messages from a separate kernel thread
netlink_unicast() will attempt to reallocate and will free messages if
the socket's rcvbuf limit is reached unless we give it an infinite
timeout. So do that, from a kernel thread which is dedicated to spewing
stuff up the netlink socket.
Signed-off-by: David Woodhouse <dwmw2(a)infradead.org>
I confirmed the comamnd works well on fedora 4.8 kernel, RHEL7.3,
RHEL6.8 and RHEL5.11; RHEL6.8 was tested both on x86_64 and x86_32.
So, I guess the design will rarely be changed also in the future for
some time.
To get vmcore full of audit logs, run the following commands:
# auditctl -a exit,always -S all # always record exit of all system calls
# auditctl -e 1 # enable audit logging
# auditctl -f 2 # configure kernel to panic when audit buffer becomes full
# kill -STOP $(pidof auditd) # stop auditd that is a unique process
# to read and reduce audit buffer
# dd if=/dev/zero of=/dev/null # issue system calls a lot
then kernel will panic when audit buffer becomes full.
To dump audit logs, simply, run dumpaudit command:
crash> extend /root/repos/crash-dumpaudit-command/src/dumpaudit.so
/root/repos/crash-dumpaudit-command/src/dumpaudit.so: shared object loaded
crash> dumpaudit
type=1300 audit(1489022639.875:164489): arch=c000003e syscall=0 success=yes exit=0 a0=5 a1=7fedd3b00000 a2=400 a3=22 items=0 ppid=2575 pid=10428 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm="pidof" exe="/usr/sbin/killall5" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=1320 audit(1489022639.875:164489):
type=1320 audit(1489022639.875:164487):
type=1300 audit(1489022639.875:164490): arch=c000003e syscall=3 success=yes exit=0 a0=5 a1=1 a2=8 a3=0 items=0 ppid=2575 pid=10428 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm="pidof" exe="/usr/sbin /killall5" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
...<cut>...
On the vmcore created like above, log command should show the messages
ending with:
crash> log | tail -n 21
[253655.583070] audit: audit_backlog=321 > audit_backlog_limit=320
[253655.583124] audit: audit_backlog=321 > audit_backlog_limit=320
[253655.583129] audit: audit_lost=1 audit_rate_limit=0 audit_backlog_limit=320
[253655.583139] Kernel panic - not syncing: audit: backlog limit exceeded
[253655.583142] CPU: 0 PID: 2575 Comm: bash Not tainted 3.10.0-327.el7.x86_64 #1
[253655.583143] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2007
[253655.583147] ffffffff81870541 000000007dd10266 ffff8800b8a43d40 ffffffff816351f1
[253655.583149] ffff8800b8a43dc0 ffffffff8162ea6c ffffffff00000010 ffff8800b8a43dd0
[253655.583151] ffff8800b8a43d70 000000007dd10266 0000000000000000 ffffffff818705e8
[253655.583152] Call Trace:
[253655.583168] [<ffffffff816351f1>] dump_stack+0x19/0x1b
[253655.583170] [<ffffffff8162ea6c>] panic+0xd8/0x1e7
[253655.583178] [<ffffffff81103ce4>] audit_panic+0x64/0x70
[253655.583180] [<ffffffff81103d2f>] audit_log_lost+0x3f/0xd0
[253655.583186] [<ffffffff811049bc>] audit_log_start+0x1bc/0x4b0
[253655.583189] [<ffffffff810919dc>] ? do_send_sig_info+0x6c/0xa0
[253655.583193] [<ffffffff810b8c10>] ? wake_up_state+0x20/0x20
[253655.583199] [<ffffffff81108ce1>] audit_log_exit+0x51/0xb90
[253655.583201] [<ffffffff8110b7cd>] __audit_syscall_exit+0x21d/0x280
[253655.583208] [<ffffffff81645a2b>] sysret_audit+0x17/0x21
where audit_backlog_limit=320 means the limit number of audit logs
configured in /etc/audit.conf was 320 and audit_backlog=321 means the
audit queue, or audit backlog, became full amounting to 321.
dumpaudit should dump audit logs as many lines as the limit:
crash> dumpaudit | wc -l
321
--
Thanks.
HATAYAMA, Daisuke
7 years, 8 months
[PATCH] gcore: Add MIPS support
by Rabin Vincent
From: Rabin Vincent <rabinv(a)axis.com>
This adds basic support for MIPS to the gcore extension.
---
gcore.mk | 10 +++
libgcore/gcore_coredump.c | 2 +-
libgcore/gcore_defs.h | 39 ++++++++++--
libgcore/gcore_mips.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 205 insertions(+), 5 deletions(-)
create mode 100644 libgcore/gcore_mips.c
diff --git a/gcore.mk b/gcore.mk
index c9683d4..ffc9ce7 100644
--- a/gcore.mk
+++ b/gcore.mk
@@ -42,6 +42,12 @@ ifeq ($(shell arch), aarch64)
ARCH=SUPPORTED
endif
+ifeq ($(shell arch), mips)
+ TARGET=MIPS
+ TARGET_CFLAGS=
+ ARCH=SUPPORTED
+endif
+
ifeq ($(shell arch), ppc64)
TARGET=PPC64
TARGET_CFLAGS=
@@ -85,6 +91,10 @@ ifneq (,$(findstring $(TARGET), ARM64))
GCORE_CFILES += libgcore/gcore_arm64.c
endif
+ifneq (,$(findstring $(TARGET), MIPS))
+GCORE_CFILES += libgcore/gcore_mips.c
+endif
+
ifneq (,$(findstring $(TARGET), PPC64))
GCORE_CFILES += libgcore/gcore_ppc64.c
endif
diff --git a/libgcore/gcore_coredump.c b/libgcore/gcore_coredump.c
index 892ddf9..e91f29a 100644
--- a/libgcore/gcore_coredump.c
+++ b/libgcore/gcore_coredump.c
@@ -683,7 +683,7 @@ fill_prstatus_note(struct elf_note_info *info, struct task_context *tc,
struct memelfnote *memnote)
{
struct elf_prstatus *prstatus;
-#if defined(X86) || defined(X86_64) || defined(ARM) || defined(PPC64)
+#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS) || defined(PPC64)
struct user_regs_struct *regs = (struct user_regs_struct *)memnote->data;
#endif
#ifdef ARM64
diff --git a/libgcore/gcore_defs.h b/libgcore/gcore_defs.h
index ba1fde2..6fdb943 100644
--- a/libgcore/gcore_defs.h
+++ b/libgcore/gcore_defs.h
@@ -94,6 +94,26 @@
#define Elf_Nhdr Elf32_Nhdr
#endif
+#ifdef MIPS
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_MACHINE EM_MIPS
+#define ELF_OSABI ELFOSABI_NONE
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_MIPS
+
+#define Elf_Half Elf32_Half
+#define Elf_Word Elf32_Word
+#define Elf_Off Elf32_Off
+
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Phdr Elf32_Phdr
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Nhdr Elf32_Nhdr
+#endif
+
#ifdef ARM64
#define ELF_EXEC_PAGESIZE PAGESIZE()
@@ -290,6 +310,11 @@ extern void gcore_default_regsets_init(void);
#define REGSET_VIEW_MACHINE EM_AARCH64
#endif
+#ifdef MIPS
+#define REGSET_VIEW_NAME "mips"
+#define REGSET_VIEW_MACHINE EM_MIPS
+#endif
+
#ifdef PPC64
#define REGSET_VIEW_NAME "ppc64"
#define REGSET_VIEW_MACHINE EM_PPC64
@@ -594,6 +619,12 @@ struct user_regs_struct32{
#endif /* GCORE_ARCH_COMPAT */
#endif
+#ifdef MIPS
+struct user_regs_struct {
+ unsigned long gregs[45];
+};
+#endif
+
#ifdef PPC64
/* taken from asm/ptrace.h */
struct user_regs_struct {
@@ -620,13 +651,13 @@ struct user_regs_struct {
};
#endif
-#if defined(X86) || defined(X86_64) || defined(ARM)
+#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS)
typedef ulong elf_greg_t;
#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
#endif
-#if defined(X86) || defined(ARM)
+#if defined(X86) || defined(ARM) || defined(MIPS)
#define PAGE_SIZE 4096
#endif
#if defined(ARM64) || defined(PPC64)
@@ -783,7 +814,7 @@ struct elf_prstatus
int pr_fpvalid; /* True if math co-processor being used. */
};
-#if defined(X86) || defined(X86_64) || defined(ARM)
+#if defined(X86) || defined(X86_64) || defined(ARM) || defined(MIPS)
typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
#endif
@@ -803,7 +834,7 @@ typedef __kernel_gid_t __kernel_old_gid_t;
typedef __kernel_old_uid_t old_uid_t;
typedef __kernel_old_gid_t old_gid_t;
-#if defined(X86) || defined(ARM)
+#if defined(X86) || defined(ARM) || defined(MIPS)
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
#endif
diff --git a/libgcore/gcore_mips.c b/libgcore/gcore_mips.c
new file mode 100644
index 0000000..be67d51
--- /dev/null
+++ b/libgcore/gcore_mips.c
@@ -0,0 +1,159 @@
+/* gcore_mips.c -- core analysis suite
+ *
+ * Copyright (C) 2016 Axis Communications
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#if defined(MIPS)
+
+#include "defs.h"
+#include <gcore_defs.h>
+#include <stdint.h>
+#include <elf.h>
+#include <asm/ldt.h>
+
+#define MIPS32_EF_R0 6
+#define MIPS32_EF_R1 7
+#define MIPS32_EF_R26 32
+#define MIPS32_EF_R27 33
+#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
+
+static int gpr_get(struct task_context *target,
+ const struct user_regset *regset,
+ unsigned int size, void *buf)
+{
+ static int once;
+ struct user_regs_struct *regs = buf;
+ struct mips_pt_regs_main *mains;
+ struct mips_pt_regs_cp0 *cp0;
+ char pt_regs[SIZE(pt_regs)];
+ int i;
+
+ /*
+ * All registers are saved in thread_info.regs only on certain types of
+ * entries to the kernel (such as abort handling). For other types of
+ * entries (such as system calls), only a subset of the registers are
+ * saved on entry and the rest are saved on the stack according to the
+ * ABI's calling conventions. To always get the full register set we
+ * would have to unwind the stack and find where the registers are by
+ * using DWARF information. We don't have an implementation for this
+ * right now so warn to avoid misleading the user. Only warn since
+ * this function is called multiple times even for a single invocation
+ * of the gcore command.
+ */
+ if (!once) {
+ once = 1;
+ error(WARNING, "WARNING: Current register values may be inaccurate\n");
+ }
+
+ readmem(machdep->get_stacktop(target->task) - 32 - SIZE(pt_regs),
+ KVADDR, pt_regs, SIZE(pt_regs), "genregs_get: pt_regs",
+ gcore_verbose_error_handle());
+
+ mains = (struct mips_pt_regs_main *) (pt_regs + OFFSET(pt_regs_regs));
+ cp0 = (struct mips_pt_regs_cp0 *) \
+ (pt_regs + OFFSET(pt_regs_cp0_badvaddr));
+
+ BZERO(regs, sizeof(*regs));
+
+ for (i = MIPS32_EF_R1; i <= MIPS32_EF_R31; i++) {
+ /* k0/k1 are copied as zero. */
+ if (i == MIPS32_EF_R26 || i == MIPS32_EF_R27)
+ continue;
+
+ regs->gregs[i] = mains->regs[i - MIPS32_EF_R0];
+ }
+
+ regs->gregs[MIPS32_EF_LO] = mains->lo;
+ regs->gregs[MIPS32_EF_HI] = mains->hi;
+ regs->gregs[MIPS32_EF_CP0_EPC] = cp0->cp0_epc;
+ regs->gregs[MIPS32_EF_CP0_BADVADDR] = cp0->cp0_badvaddr;
+ regs->gregs[MIPS32_EF_CP0_STATUS] = mains->cp0_status;
+ regs->gregs[MIPS32_EF_CP0_CAUSE] = cp0->cp0_cause;
+
+ return 0;
+}
+
+enum gcore_regset {
+ REGSET_GPR,
+};
+
+static struct user_regset mips_regsets[] = {
+ [REGSET_GPR] = {
+ .core_note_type = NT_PRSTATUS,
+ .name = "CORE",
+ .size = ELF_NGREG * sizeof(unsigned int),
+ .get = gpr_get,
+ },
+};
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+static const struct user_regset_view mips_regset_view = {
+ .name = "mips",
+ .regsets = mips_regsets,
+ .n = ARRAY_SIZE(mips_regsets),
+ .e_machine = EM_MIPS,
+};
+
+const struct user_regset_view *
+task_user_regset_view(void)
+{
+ return &mips_regset_view;
+}
+
+int gcore_is_arch_32bit_emulation(struct task_context *tc)
+{
+ return FALSE;
+}
+
+ulong gcore_arch_get_gate_vma(void)
+{
+ return 0UL;
+}
+
+char *gcore_arch_vma_name(ulong vma)
+{
+ ulong mm, vm_start, vdso;
+
+ readmem(vma + OFFSET(vm_area_struct_vm_mm), KVADDR, &mm, sizeof(mm),
+ "gcore_arch_vma_name: vma->vm_mm",
+ gcore_verbose_error_handle());
+
+ readmem(vma + OFFSET(vm_area_struct_vm_start), KVADDR, &vm_start,
+ sizeof(vm_start), "gcore_arch_vma_name: vma->vm_start",
+ gcore_verbose_error_handle());
+
+ readmem(mm + GCORE_OFFSET(mm_struct_context) +
+ GCORE_OFFSET(mm_context_t_vdso), KVADDR, &vdso,
+ sizeof(vdso), "gcore_arch_vma_name: mm->context.vdso",
+ gcore_verbose_error_handle());
+
+ if (mm && vm_start == vdso)
+ return "[vdso]";
+
+ return NULL;
+}
+
+int gcore_arch_vsyscall_has_vm_alwaysdump_flag(void)
+{
+ return FALSE;
+}
+
+#endif /* defined(MIPS) */
--
2.1.4
7 years, 8 months