[PATCH] Add read diagnostics to crash
by David Mair
I have been shown several alleged crash bugs that much effort revealed to be actually just incomplete or corrupt dump files. This set of changes adds a debug level 8 set of messages that allows for an easier optional diagnosis of faulty crash dumps through identification of the runtime read_mem() instance and tracing of it's behavior. It also adds some optional messages for identifiable error cases that currently only use error codes.
This patch is based on crash-6.0.2
Signed-off-by: David Mair <dmair(a)suse.com>
---
diff --git a/a/diskdump.c b/b/diskdump.c
index 5519af7..7cad9dc 100644
--- a/a/diskdump.c
+++ b/b/diskdump.c
@@ -432,6 +432,8 @@ restart:
dd->dumpable_bitmap = calloc(bitmap_len, 1);
+ if (CRASHDEBUG(8))
+ error(INFO, " memory bitmap: %llx\n", offset);
if (FLAT_FORMAT()) {
if (!read_flattened_format(dd->dfd, offset, dd->bitmap, bitmap_len)) {
error(INFO, "%s: cannot read memory bitmap\n",
@@ -829,6 +831,9 @@ read_diskdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
pfn = paddr_to_pfn(paddr);
+ if (CRASHDEBUG(8))
+ error(INFO, "read_diskdump(%d, %llx, %d, %lx, %llx), pfn=%lx\n",
+ fd, (ulonglong)bufptr, cnt, addr, (ulonglong)paddr, pfn);
if (KDUMP_SPLIT()) {
/* Find proper dd */
int i;
@@ -844,27 +849,54 @@ read_diskdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
}
}
- if (i == num_dumpfiles)
+ if (i == num_dumpfiles) {
+ if (CRASHDEBUG(8))
+ error(INFO, "Address is beyond last dumpfile.\n");
return SEEK_ERROR;
+ }
}
curpaddr = paddr & ~((physaddr_t)(dd->block_size-1));
page_offset = paddr & ((physaddr_t)(dd->block_size-1));
- if ((pfn >= dd->header->max_mapnr) || !page_is_ram(pfn))
+ if ((pfn >= dd->header->max_mapnr) || !page_is_ram(pfn)) {
+ if (CRASHDEBUG(8) && (pfn >= dd->header->max_mapnr))
+ error(INFO, "pfn (%lx) is >= maximum map number (%lx)\n",
+ pfn, dd->header->max_mapnr);
+ if (CRASHDEBUG(8) && !page_is_ram(pfn))
+ error(INFO, "pfn (%lx) is not in ram\n", pfn);
return SEEK_ERROR;
+ }
if (!page_is_dumpable(pfn)) {
if ((dd->flags & (ZERO_EXCLUDED|ERROR_EXCLUDED)) ==
- ERROR_EXCLUDED)
+ ERROR_EXCLUDED) {
+ if (CRASHDEBUG(8))
+ error(INFO, "pfn (%lx) is excluded\n", pfn);
return PAGE_EXCLUDED;
+ }
+ if (CRASHDEBUG(8))
+ error(INFO, "Zero-filling page with pfn=%lx\n", pfn);
memset(bufptr, 0, cnt);
return cnt;
}
- if (!page_is_cached(curpaddr))
- if ((ret = cache_page(curpaddr)) < 0)
+ if (!page_is_cached(curpaddr)) {
+ if (CRASHDEBUG(8))
+ error(INFO, "caching page with current physaddr=%llx\n",
+ curpaddr);
+ if ((ret = cache_page(curpaddr)) < 0) {
+ if (CRASHDEBUG(8))
+ error(INFO, "Failed with err=%d to cache page "
+ "with current physaddr=%llx\n",
+ ret, curpaddr);
return ret;
+ }
+ }
+ if (CRASHDEBUG(8))
+ error(INFO, "Buffering page with pfn=%lx and current "
+ "physaddr=%llx\n",
+ pfn, curpaddr);
memcpy(bufptr, dd->curbufptr + page_offset, cnt);
return cnt;
diff --git a/a/filesys.c b/b/filesys.c
index 6994fb0..7a8ec3d 100755
--- a/a/filesys.c
+++ b/b/filesys.c
@@ -163,6 +163,8 @@ memory_source_init(void)
error(INFO, "using /dev/mem\n\n");
pc->flags &= ~MEMMOD;
pc->flags |= DEVMEM;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_dev_mem\n");
pc->readmem = read_dev_mem;
pc->writemem = write_dev_mem;
pc->live_memsrc = "/dev/mem";
@@ -3382,6 +3384,8 @@ get_live_memory_source(void)
if (use_module) {
pc->flags &= ~DEVMEM;
pc->flags |= MEMMOD;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_memory_device\n");
pc->readmem = read_memory_device;
pc->writemem = write_memory_device;
pc->live_memsrc = pc->memory_device;
@@ -3390,6 +3394,9 @@ get_live_memory_source(void)
if (crashbuiltin) {
pc->flags &= ~DEVMEM;
pc->flags |= CRASHBUILTIN;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_memory_device/builtin\n");
pc->readmem = read_memory_device;
pc->writemem = write_memory_device;
pc->live_memsrc = pc->memory_device;
diff --git a/a/main.c b/b/main.c
index ae8d933..5440c72 100755
--- a/a/main.c
+++ b/b/main.c
@@ -431,6 +431,9 @@ main(int argc, char **argv)
}
pc->flags |= DEVMEM;
pc->dumpfile = NULL;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_dev_mem\n");
pc->readmem = read_dev_mem;
pc->writemem = write_dev_mem;
pc->live_memsrc = argv[optind];
@@ -443,6 +446,9 @@ main(int argc, char **argv)
}
pc->flags |= PROC_KCORE;
pc->dumpfile = NULL;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_proc_kcore\n");
pc->readmem = read_proc_kcore;
pc->writemem = write_proc_kcore;
pc->live_memsrc = argv[optind];
@@ -457,9 +463,15 @@ main(int argc, char **argv)
pc->dumpfile = argv[optind];
if (is_sadump_xen()) {
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_kdump\n");
pc->readmem = read_kdump;
pc->writemem = write_kdump;
} else {
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_netdump\n");
pc->readmem = read_netdump;
pc->writemem = write_netdump;
}
@@ -472,6 +484,9 @@ main(int argc, char **argv)
}
pc->flags |= KDUMP;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_kdump for KDUMP_LOCAL\n");
pc->readmem = read_kdump;
pc->writemem = write_kdump;
@@ -483,6 +498,9 @@ main(int argc, char **argv)
}
pc->flags |= KVMDUMP;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_kvmdump\n");
pc->readmem = read_kvmdump;
pc->writemem = write_kvmdump;
@@ -502,6 +520,9 @@ main(int argc, char **argv)
}
pc->flags |= XENDUMP;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_xendump\n");
pc->readmem = read_xendump;
pc->writemem = write_xendump;
@@ -518,6 +539,9 @@ main(int argc, char **argv)
}
pc->flags |= DISKDUMP;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_diskdump\n");
pc->readmem = read_diskdump;
pc->writemem = write_diskdump;
@@ -529,6 +553,9 @@ main(int argc, char **argv)
}
pc->flags |= LKCD;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_lkcddump\n");
pc->readmem = read_lkcd_dumpfile;
pc->writemem = write_lkcd_dumpfile;
@@ -540,6 +567,9 @@ main(int argc, char **argv)
}
pc->flags |= MCLXCD;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_mclxdump\n");
pc->readmem = read_mclx_dumpfile;
pc->writemem = write_mclx_dumpfile;
@@ -551,6 +581,9 @@ main(int argc, char **argv)
}
pc->flags |= S390D;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_s390_dumpfile\n");
pc->readmem = read_s390_dumpfile;
pc->writemem = write_s390_dumpfile;
@@ -563,6 +596,9 @@ main(int argc, char **argv)
}
pc->flags |= SADUMP;
pc->dumpfile = argv[optind];
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to "
+ "read_sadump\n");
pc->readmem = read_sadump;
pc->writemem = write_sadump;
@@ -950,6 +986,8 @@ setup_environment(int argc, char **argv)
pc->flags |= DATADEBUG; /* default until unnecessary */
pc->confd = -2;
pc->machine_type = MACHINE_TYPE;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to default read_dev_mem\n");
pc->readmem = read_dev_mem; /* defaults until argv[] is parsed */
pc->writemem = write_dev_mem;
pc->memory_module = NULL;
@@ -1600,8 +1638,11 @@ check_xen_hyper(void)
#ifdef XEN_HYPERVISOR_ARCH
pc->cmd_table = xen_hyper_command_table;
- if (pc->flags & XENDUMP)
+ if (pc->flags & XENDUMP) {
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_xendump_hyper\n");
pc->readmem = read_xendump_hyper;
+ }
#else
error(FATAL, XEN_HYPERVISOR_NOT_SUPPORTED);
#endif
diff --git a/a/memory.c b/b/memory.c
index 95eefc9..ac64767 100755
--- a/a/memory.c
+++ b/b/memory.c
@@ -2215,6 +2215,8 @@ switch_to_proc_kcore(void)
pc->flags &= ~DEVMEM;
pc->flags |= PROC_KCORE;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_proc_kcore for memory.c\n");
pc->readmem = read_proc_kcore;
pc->writemem = write_proc_kcore;
pc->live_memsrc = "/proc/kcore";
diff --git a/a/netdump.c b/b/netdump.c
index 4011f36..28989c9 100644
--- a/a/netdump.c
+++ b/b/netdump.c
@@ -495,6 +495,10 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
off_t offset;
struct pt_load_segment *pls;
int i;
+
+ if (CRASHDEBUG(8))
+ error(INFO, "read_netdump(%d, %llx, %d, %lx, %llx)\n",
+ fd, (ulonglong)bufptr, cnt, addr, (ulonglong)paddr);
offset = 0;
@@ -509,6 +513,9 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
{
case NETDUMP_ELF32:
offset = (off_t)paddr + (off_t)nd->header_size;
+ if (CRASHDEBUG(8))
+ error(INFO, "read NETDUMP_ELF32 for offset: %llx\n",
+ (ulonglong)offset);
break;
case NETDUMP_ELF64:
@@ -517,6 +524,10 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
if (nd->num_pt_load_segments == 1) {
offset = (off_t)paddr + (off_t)nd->header_size -
(off_t)nd->pt_load_segments[0].phys_start;
+ if (CRASHDEBUG(8))
+ error(INFO, "read KDUMP or NETDUMP_ELF64 for "
+ "single segment: %llx\n",
+ (ulonglong)offset);
break;
}
@@ -526,11 +537,18 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
(paddr < pls->phys_end)) {
offset = (off_t)(paddr - pls->phys_start) +
pls->file_offset;
+ if (CRASHDEBUG(8))
+ error(INFO, "read KDUMP or NETDUMP_ELF64 "
+ "for multi-segment: %llx\n",
+ (ulonglong)offset);
break;
}
if (pls->zero_fill && (paddr >= pls->phys_end) &&
(paddr < pls->zero_fill)) {
memset(bufptr, 0, cnt);
+ if (CRASHDEBUG(8))
+ error(INFO, "read KDUMP or NETDUMP_ELF64 "
+ "for zero-fill\n");
return cnt;
}
}
@@ -542,9 +560,15 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
}
if (FLAT_FORMAT()) {
+ if (CRASHDEBUG(8))
+ error(INFO, "read flat-format offset: %llx\n",
+ (ulonglong)offset);
if (!read_flattened_format(nd->ndfd, offset, bufptr, cnt))
return READ_ERROR;
} else {
+ if (CRASHDEBUG(8))
+ error(INFO, "seek and read offset: %llx\n",
+ (ulonglong)offset);
if (lseek(nd->ndfd, offset, SEEK_SET) == -1)
return SEEK_ERROR;
if (read(nd->ndfd, bufptr, cnt) != cnt)
@@ -2618,6 +2642,9 @@ get_kdump_panic_task(void)
int
read_kdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
{
+ if (CRASHDEBUG(8))
+ error(INFO, "read_kdump for: virt=%lx phys=%llx\n",
+ addr, (ulonglong)paddr);
if (XEN_CORE_DUMPFILE() && !XEN_HYPER_MODE()) {
if (!(nd->xen_kdump_data->flags & KDUMP_P2M_INIT)) {
if (!machdep->xen_kdump_p2m_create)
@@ -2640,6 +2667,10 @@ read_kdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
return READ_ERROR;
}
+ if (CRASHDEBUG(8))
+ error(INFO, "read_kdump trying read_netdump for: virt=%lx "
+ "phys=%llx\n",
+ addr, (ulonglong)paddr);
return read_netdump(fd, bufptr, cnt, addr, paddr);
}
diff --git a/a/remote.c b/b/remote.c
index a06c14b..d84d556 100755
--- a/a/remote.c
+++ b/b/remote.c
@@ -2244,6 +2244,8 @@ remote_fd_init(void)
* if no remote dumpfile name was entered. If it is /dev/mem,
* then also go get the remote /proc/version.
*/
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_daemon\n");
pc->readmem = read_daemon;
if (!pc->server_memsrc)
diff --git a/a/x86.c b/b/x86.c
index df91110..f166a02 100755
--- a/a/x86.c
+++ b/b/x86.c
@@ -4390,6 +4390,8 @@ x86_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
* Temporarily read physical (machine) addresses from vmcore by
* going directly to read_netdump() instead of via read_kdump().
*/
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_netdump for x86\n");
pc->readmem = read_netdump;
if (xkd->flags & KDUMP_CR3)
@@ -4467,6 +4469,8 @@ x86_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
fprintf(fp, "\n");
}
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_kdump for x86\n");
pc->readmem = read_kdump;
return TRUE;
@@ -4553,6 +4557,9 @@ use_cr3:
machdep->last_ptbl_read = 0;
machdep->last_pmd_read = 0;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_kdump for x86 and "
+ "use cr3\n");
pc->readmem = read_kdump;
return TRUE;
diff --git a/a/x86_64.c b/b/x86_64.c
index 689317f..26fb397 100755
--- a/a/x86_64.c
+++ b/b/x86_64.c
@@ -5398,6 +5398,8 @@ x86_64_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
* Temporarily read physical (machine) addresses from vmcore by
* going directly to read_netdump() instead of via read_kdump().
*/
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_netdump for x86_64\n");
pc->readmem = read_netdump;
if (xkd->flags & KDUMP_CR3)
@@ -5458,6 +5460,8 @@ x86_64_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
fprintf(fp, "\n");
}
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_kdump for x86_64\n");
pc->readmem = read_kdump;
return TRUE;
@@ -5524,6 +5528,9 @@ use_cr3:
machdep->last_pgd_read = 0;
machdep->last_ptbl_read = 0;
machdep->last_pmd_read = 0;
+ if (CRASHDEBUG(8))
+ error(INFO, "Setting readmem to read_kdump for x86_64 and "
+ "using cr3\n");
pc->readmem = read_kdump;
return TRUE;
12 years, 11 months
[ANNOUNCE] crash version 6.0.2 is available
by Dave Anderson
Download from: http://people.redhat.com/anderson
Changelog:
- Implemention of a new "arguments-input-file" feature, where an input
file containing crash command arguments may be iteratively fed to
a crash command. For each line of arguments in an input file, the
selected crash command will be executed. Taking a simple example,
consider an a file named "input" which contains several task_struct
addresses:
crash> cat input
ffff88022bdc2080
ffff88012ae78ac0
ffff88012c334b00
ffff88012c335540
crash>
Each line in the input file may be passed to a crash command by
entering the redirection character followed by the filename:
crash> ps < input
PID PPID CPU TASK ST %MEM VSZ RSS COMM
5752 624 5 ffff88022bdc2080 IN 0.0 12340 2584 udevd
PID PPID CPU TASK ST %MEM VSZ RSS COMM
5779 4927 1 ffff88012ae78ac0 IN 0.0 97820 3916 sshd
PID PPID CPU TASK ST %MEM VSZ RSS COMM
5956 1 3 ffff88012c334b00 IN 0.0 27712 868 auditd
PID PPID CPU TASK ST %MEM VSZ RSS COMM
5784 5779 2 ffff88012c335540 IN 0.0 108392 1856 bash
crash> struct task_struct.pid,mm < input
pid = 5752
mm = 0xffff88022ab65100
pid = 5779
mm = 0xffff88012c272180
pid = 5956
mm = 0xffff88012b00f7c0
pid = 5784
mm = 0xffff88012ae30800
crash>
The input file may contain data containing anything that can be
inserted into a given crash command line. There is no restriction
on the number of arguments in each line; essentially the data in
each input file line will be inserted into the command line starting
where the "<" character is located, and any intervening whitespace
and the filename will be removed. However, because pipes and output
redirection are set up prior to the insertion of input file data,
pipe or redirection should not be put on input file lines. If that
is attempted, the arguments will just be passed to the command, with
unpredictable results. However, output can be piped or redirected
the same way as can be done with normal commands:
crash> set < input | grep -e COMMAND -e CPU
COMMAND: "udevd"
CPU: 5
COMMAND: "sshd"
CPU: 1
COMMAND: "auditd"
CPU: 3
COMMAND: "bash"
CPU: 2
crash>
Many thanks to Josef Bacik for proposing this feature.
(anderson(a)redhat.com)
- Fix for the "runq" command for kernels configured with
CONFIG_FAIR_GROUP_SCHED. Without the patch, it is possible
that a task may be listed twice in a cpu's CFS runqueue.
(d.hatayama(a)jp.fujitsu.com)
- Fix for the internal parse_line() function to properly handle the
case where the first argument in a line is a string argument that is
encapulated with quotation marks.
(anderson(a)redhat.com)
- Fix for the usage of gzip'd vmlinux file that was compressed with
"gzip -n" or "gzip --no-name" without using "-f" on the command line.
Without the patch, the crash session fails with an error message that
indicates "crash: <string-containing-garbage>: compressed file name
does not start with vmlinux". With the patch, if such a file is used
without "-f", it will be accepted with a message that indicates that
the original filename is unknown, and a suggestion that "-f" be used
to prevent the message.
(anderson(a)redhat.com)
- Added a new "mod -g" option that enhances the symbol display for
kernel modules. After loading a module's debuginfo data, the module
object's section addresses will be shown as pseudo-symbols, like this
simple example using the crash memory driver module:
crash> mod -g -s crash
... [cut] ...
crash> sym -m crash
ffffffff88edb000 MODULE START: crash
ffffffff88edb000 [.text]: section start
ffffffff88edb000 (t) crash_llseek
ffffffff88edb01d (t) crash_read
ffffffff88edb18c [.text]: section end
ffffffff88edb18c [.exit.text]: section start
ffffffff88edb18c (T) cleanup_module
ffffffff88edb18c (t) crash_cleanup_module
ffffffff88edb198 [.exit.text]: section end
ffffffff88edb2a0 [__versions]: section start
ffffffff88edb2a0 (r) ____versions
ffffffff88edb2a0 (r) __versions
ffffffff88edb4a0 [__versions]: section end
ffffffff88edb920 [.data]: section start
ffffffff88edb920 (d) crash_dev
ffffffff88edb960 (d) crash_fops
ffffffff88edba48 [.data]: section end
ffffffff88edba80 [.gnu.linkonce.this_module]: section start
ffffffff88edba80 (D) __this_module
ffffffff88ee3c80 [.gnu.linkonce.this_module]: section end
ffffffff88ee3cc1 MODULE END: crash
crash>
The option may also be used in conjunction with "mod -S".
(nakayama.ts(a)ncos.nec.co.jp)
- Fix for the "gdb" command to prevent the option handling of command
lines. Without the patch, a gdb command string that contained a
"-<character>" pair preceded by whitespace, would fail with the
error message "gdb: gdb: invalid option -- <character>".
(anderson(a)redhat.com)
- Fix for the panic-task determination if a dumpfile is taken on a
system that actually has a cpu count that is equal to its per-arch
NR_CPUS value. Without the patch, the task running on the cpu
whose number is equal to NR_CPUS-1 would be selected.
(d.hatayama(a)jp.fujitsu.com)
- Fix for the x86_64 "bt" command to handle a recursive entry into
the NMI exception stack. While this should normally never happen,
it is possible if, for example, a kprope is entered into a function
that gets executed during NMI handling, and a second NMI is received
after the initial one, corrupting the original exception frame at
the top of the NMI stack. Without the patch, the NMI stack backtrace
and exception frame would be displayed repeatedly; with the patch,
the backtrace and exception frame are followed by the warning message
"NMI exception stack recursion: prior stack location overwritten".
(anderson(a)redhat.com)
- Support dumpfiles that are created by the PPC64 Firmware Assisted
Dump facility, also known as "fadump" or "FAD". Without the patch,
the panic task cannot be determined from a fadump vmcore which was
subsequently compressed with makedumpfile, and therefore a proper
backtrace of the panic task cannot be generated.
(mahesh(a)linux.vnet.ibm.com)
- Preparation for new s390x kernels that will increase MAX_PHYSMEM_BITS
from 42 to 46.
(mahesh(a)linux.vnet.ibm.com, holzheu(a)linux.vnet.ibm.com,
anderson(a)redhat.com)
12 years, 11 months
freeing of uninitialised variable in reg_callback()
by Lachlan McIlroy
I'm using crash 6.0.2 and I'm regularly seeing this segfault from sial when unloading a sial script:
crash> extend ./sial.so
Core LINUX_RELEASE == '2.6.18-238.12.1.el5'
< Sial interpreter version 3.0 >
Loading sial commands from /usr/share/sial/crash:/home/lmcilroy/.sial .... Done.
./sial.so: shared object loaded
crash> load script.sial
crash> unload script.sial
*** glibc detected *** crash: double free or corruption (!prev): 0x00000000071999b0 ***
Segmentation fault
Program received signal SIGSEGV, Segmentation fault.
0x0000003b61c74f32 in malloc_consolidate () from /lib64/libc.so.6
(gdb) bt
#0 0x0000003b61c74f32 in malloc_consolidate () from /lib64/libc.so.6
#1 0x0000003b61c77bd2 in _int_malloc () from /lib64/libc.so.6
#2 0x0000003b61c78c88 in calloc () from /lib64/libc.so.6
#3 0x0000003b6180a98f in _dl_new_object () from /lib64/ld-linux-x86-64.so.2
#4 0x0000003b61805e4f in _dl_map_object_from_fd () from /lib64/ld-linux-x86-64.so.2
#5 0x0000003b61807bd2 in _dl_map_object () from /lib64/ld-linux-x86-64.so.2
#6 0x0000003b61812530 in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#7 0x0000003b6180dd76 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#8 0x0000003b61811fb7 in _dl_open () from /lib64/ld-linux-x86-64.so.2
#9 0x0000003b61d1afb0 in do_dlopen () from /lib64/libc.so.6
#10 0x0000003b6180dd76 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#11 0x0000003b61d1b107 in __libc_dlopen_mode () from /lib64/libc.so.6
#12 0x0000003b61cf3cc1 in backtrace () from /lib64/libc.so.6
#13 0x0000003b61c6f147 in __libc_message () from /lib64/libc.so.6
#14 0x0000003b61c74ac6 in malloc_printerr () from /lib64/libc.so.6
#15 0x00007f85babefe7a in sial_deletefile (name=0x462bf78 "script.sial") at sial_func.c:320
#16 0x00007f85babf5d36 in sial_loadunload (load=0, name=<value optimized out>, silent=0) at sial_api.c:1289
#17 0x00007f85babec77d in unload_cmd () at sial.c:775
#18 0x000000000045d4df in exec_command () at main.c:751
#19 0x000000000045d6ea in main_loop () at main.c:699
#20 0x0000000000557019 in captured_command_loop (data=<value optimized out>) at ./main.c:228
#21 0x00000000005552eb in catch_errors (func=<value optimized out>, func_args=<value optimized out>, errstring=<value optimized out>, mask=<value optimized out>) at exceptions.c:531
#22 0x0000000000556d26 in captured_main (data=<value optimized out>) at ./main.c:958
#23 0x00000000005552eb in catch_errors (func=<value optimized out>, func_args=<value optimized out>, errstring=<value optimized out>, mask=<value optimized out>) at exceptions.c:531
#24 0x0000000000555ee4 in gdb_main (args=0x98) at ./main.c:973
#25 0x0000000000555f1e in gdb_main_entry (argc=<value optimized out>, argv=<value optimized out>) at ./main.c:993
#26 0x000000000045e24f in main (argc=<value optimized out>, argv=<value optimized out>) at main.c:603
I've traced the fault to extensions/sial.c:reg_callback() where it is freeing 'help_str' without it being initialised first.
void
reg_callback(char *name, int load)
{
char fname[MAX_SYMNAMELEN+sizeof("_usage")+1];
char *help_str, *opt_str;
char **help=malloc(sizeof *help * 5);
if(!help) return;
snprintf(fname, sizeof(fname), "%s_help", name);
if(sial_chkfname(fname, 0)) {
snprintf(fname, sizeof(fname), "%s_usage", name);
if(sial_chkfname(fname, 0)) {
if(load) {
opt_str=sial_strdup((char*)(unsigned long)sial_exefunc(fname, 0));
snprintf(fname, sizeof(fname), "%s_help", name);
help_str=sial_strdup((char*)(unsigned long)sial_exefunc(fname, 0));
help[0]=sial_strdup(name);
help[1]="";
help[2]=sial_strdup(opt_str);
help[3]=sial_strdup(help_str);
help[4]=0;
add_sial_cmd(name, run_callback, help, 0);
sial_free(help_str);
sial_free(opt_str);
return;
}
else rm_sial_cmd(name);
}
sial_free(help_str); <--- segfaults here.
}
free(help);
return;
}
I don't see how 'help_str' should be initialised at this point and removing the 'sial_free(help_str)' prevents the problem - is that the right thing to do here?
Lachlan
12 years, 11 months
[PATCH v2 0/3] Kdump core analysis support for PPC32
by Suzuki K. Poulose
The following series implements the kdump core analysis support
for PPC32. I have posted the KDUMP kernel support patches for PPC440x
here :
http://lists.ozlabs.org/pipermail/linuxppc-dev/2011-December/094994.html
You need upstream git snapshot of kexec-tools for kdump support on PPC440x.
These patches are based on crash-6.0.2
---
Suzuki K. Poulose (3):
[ppc] Enable stack trace display for KDUMP cores
[ppc][netdump] Read register set from ELF Note
[ppc] Support PPC32 Core analysis on PPC64 host
configure.c | 14 ++++++++
netdump.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
ppc.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 178 insertions(+), 14 deletions(-)
--
Suzuki Poulose
12 years, 11 months