2011-09-23 12:00:45 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
2012-02-29 16:07:11 +03:00
|
|
|
#include <ctype.h>
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
#include "list.h"
|
2012-01-26 15:27:00 +04:00
|
|
|
#include "namespaces.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
#include "compiler.h"
|
|
|
|
#include "crtools.h"
|
|
|
|
#include "util.h"
|
2011-12-26 22:12:03 +04:00
|
|
|
#include "sockets.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
#include "image.h"
|
2012-01-31 11:29:23 +03:00
|
|
|
#include "uts_ns.h"
|
2012-01-31 22:29:11 +04:00
|
|
|
#include "ipc_ns.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-11-21 20:27:47 +04:00
|
|
|
#define DEF_PAGES_PER_LINE 6
|
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
#ifndef CONFIG_X86_64
|
|
|
|
# error No x86-32 support yet
|
|
|
|
#endif
|
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
#define PR_SYMBOL(sym) \
|
2012-02-29 16:07:11 +03:00
|
|
|
(isprint(sym) ? sym : '.')
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
#define pr_regs4(s, n1, n2, n3, n4) \
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%8s: %16lx " \
|
|
|
|
"%8s: %16lx " \
|
|
|
|
"%8s: %16lx " \
|
|
|
|
"%8s: %16lx\n", \
|
|
|
|
#n1, s.n1, \
|
|
|
|
#n2, s.n2, \
|
|
|
|
#n3, s.n3, \
|
|
|
|
#n4, s.n4)
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
#define pr_regs3(s, n1, n2, n3) \
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%8s: %16lx " \
|
|
|
|
"%8s: %16lx " \
|
|
|
|
"%8s: %16lx\n", \
|
|
|
|
#n1, s.n1, \
|
|
|
|
#n2, s.n2, \
|
|
|
|
#n3, s.n3)
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
static char local_buf[PAGE_SIZE];
|
|
|
|
static LIST_HEAD(pstree_list);
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
static void show_files(int fd_files)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
2011-12-05 15:57:47 +04:00
|
|
|
struct fdinfo_entry e;
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_head(CR_FD_FDINFO);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
while (1) {
|
2012-01-22 20:20:40 +04:00
|
|
|
int ret;
|
2012-01-30 17:06:09 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
ret = read_img_eof(fd_files, &e);
|
|
|
|
if (ret <= 0)
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
2012-01-12 21:54:38 +04:00
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("type: %02x len: %02x flags: %4x pos: %8x "
|
|
|
|
"addr: %16lx id: %16lx",
|
|
|
|
e.type, e.len, e.flags, e.pos, e.addr, e.id);
|
2012-01-12 21:54:38 +04:00
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
if (e.len) {
|
|
|
|
int ret = read(fd_files, local_buf, e.len);
|
|
|
|
if (ret != e.len) {
|
2012-01-31 15:13:05 +04:00
|
|
|
pr_perror("Can't read %d bytes", e.len);
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
local_buf[e.len] = 0;
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg(" --> %s", local_buf);
|
2012-01-12 21:54:38 +04:00
|
|
|
}
|
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n");
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_tail(CR_FD_FDINFO);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
static void show_pipes(int fd_pipes)
|
2011-12-05 15:57:47 +04:00
|
|
|
{
|
|
|
|
struct pipe_entry e;
|
|
|
|
int ret;
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_head(CR_FD_PIPES);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
|
|
|
while (1) {
|
2012-01-22 20:20:40 +04:00
|
|
|
int ret;
|
2012-01-30 17:06:09 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
ret = read_img_eof(fd_pipes, &e);
|
|
|
|
if (ret <= 0)
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("fd: %8x pipeid: %8x flags: %8x bytes: %8x\n",
|
|
|
|
e.fd, e.pipeid, e.flags, e.bytes);
|
2011-12-05 15:57:47 +04:00
|
|
|
if (e.bytes)
|
|
|
|
lseek(fd_pipes, e.bytes, SEEK_CUR);
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_tail(CR_FD_PIPES);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
2012-03-21 14:22:00 +04:00
|
|
|
static void show_vmas(int fd_vma)
|
2011-12-05 15:57:47 +04:00
|
|
|
{
|
|
|
|
struct vma_area vma_area = {};
|
|
|
|
struct vma_entry ve;
|
|
|
|
|
2012-03-21 14:22:00 +04:00
|
|
|
pr_img_head(CR_FD_VMAS);
|
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
while (1) {
|
2012-03-21 14:22:00 +04:00
|
|
|
int ret;
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2012-03-21 14:22:00 +04:00
|
|
|
ret = read_img_eof(fd_vma, &ve);
|
|
|
|
if (ret <= 0)
|
2011-12-05 15:57:47 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
/* Simply in a sake of fancy printing */
|
|
|
|
vma_area.vma = ve;
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg_vma(&vma_area);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
2012-03-21 14:22:00 +04:00
|
|
|
|
|
|
|
pr_img_tail(CR_FD_VMAS);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
2012-02-29 16:07:11 +03:00
|
|
|
void print_data(unsigned long addr, unsigned char *data, size_t size)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < size; i+= 16) {
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%16lx: ", addr + i);
|
2012-02-29 16:07:11 +03:00
|
|
|
for (j = 0; j < 8; j++)
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%02x ", data[i + j]);
|
|
|
|
pr_msg(" ");
|
2012-02-29 16:07:11 +03:00
|
|
|
for (j = 8; j < 16; j++)
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%02x ", data[i + j]);
|
2012-02-29 16:07:11 +03:00
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg(" |");
|
2012-02-29 16:07:11 +03:00
|
|
|
for (j = 0; j < 8; j++)
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%c ", PR_SYMBOL(data[i + j]));
|
|
|
|
pr_msg(" ");
|
2012-02-29 16:07:11 +03:00
|
|
|
for (j = 8; j < 16; j++)
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%c ", PR_SYMBOL(data[i + j]));
|
2012-02-29 16:07:11 +03:00
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("|\n");
|
2012-02-29 16:07:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
static void show_pages(int fd_pages, bool show_content)
|
2011-12-05 15:57:47 +04:00
|
|
|
{
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_head(CR_FD_PAGES);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
|
|
|
if (show_content) {
|
|
|
|
while (1) {
|
|
|
|
struct page_entry e;
|
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
if (read_img(fd_pages, &e) < 0)
|
|
|
|
break;
|
2011-12-05 15:57:47 +04:00
|
|
|
if (final_page_entry(&e))
|
|
|
|
break;
|
|
|
|
|
2012-02-29 16:07:11 +03:00
|
|
|
print_data(e.va, e.data, PAGE_IMAGE_SIZE);
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n --- End of page ---\n\n");
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
while (1) {
|
|
|
|
struct page_entry e;
|
|
|
|
int i, j;
|
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\t");
|
2011-12-05 15:57:47 +04:00
|
|
|
for (i = 0; i < DEF_PAGES_PER_LINE; i++) {
|
2012-01-22 20:20:40 +04:00
|
|
|
if (read_img(fd_pages, &e) < 0)
|
|
|
|
goto out;
|
2011-12-05 15:57:47 +04:00
|
|
|
if (final_page_entry(&e)) {
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n");
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
|
|
|
}
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%16lx ", e.va);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n");
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_tail(CR_FD_PAGES);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
static void show_sigacts(int fd_sigacts)
|
2011-12-05 15:57:47 +04:00
|
|
|
{
|
|
|
|
struct sa_entry e;
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_head(CR_FD_SIGACT);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
|
|
|
while (1) {
|
2012-01-22 20:20:40 +04:00
|
|
|
int ret;
|
2012-01-30 17:06:09 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
ret = read_img_eof(fd_sigacts, &e);
|
|
|
|
if (ret <= 0)
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("sigaction: %016lx mask: %08lx "
|
|
|
|
"flags: %016lx restorer: %016lx\n",
|
|
|
|
(long)e.sigaction,
|
|
|
|
(long)e.mask,
|
|
|
|
(long)e.flags,
|
|
|
|
(long)e.restorer);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_tail(CR_FD_SIGACT);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
2012-01-24 16:45:19 +04:00
|
|
|
static void show_itimer(char *n, struct itimer_entry *ie)
|
|
|
|
{
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%s: int %lu.%lu val %lu.%lu\n", n,
|
|
|
|
(unsigned long)ie->isec, (unsigned long)ie->iusec,
|
|
|
|
(unsigned long)ie->vsec, (unsigned long)ie->vusec);
|
2012-01-24 16:45:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void show_itimers(int fd)
|
|
|
|
{
|
|
|
|
struct itimer_entry ie[3];
|
|
|
|
|
|
|
|
pr_img_head(CR_FD_ITIMERS);
|
|
|
|
if (read_img_buf(fd, ie, sizeof(ie)) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
show_itimer("real", &ie[0]);
|
|
|
|
show_itimer("real", &ie[1]);
|
|
|
|
show_itimer("real", &ie[2]);
|
|
|
|
out:
|
|
|
|
pr_img_tail(CR_FD_ITIMERS);
|
|
|
|
}
|
|
|
|
|
2012-01-27 21:43:32 +04:00
|
|
|
static void show_cap(char *name, u32 *v)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%s: ", name);
|
2012-01-27 21:43:32 +04:00
|
|
|
for (i = CR_CAP_SIZE - 1; i >= 0; i--)
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("%08x", v[i]);
|
|
|
|
pr_msg("\n");
|
2012-01-27 21:43:32 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void show_creds(int fd)
|
|
|
|
{
|
|
|
|
struct creds_entry ce;
|
|
|
|
|
|
|
|
pr_img_head(CR_FD_CREDS);
|
|
|
|
if (read_img(fd, &ce) < 0)
|
|
|
|
goto out;
|
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("uid %u euid %u suid %u fsuid %u\n",
|
|
|
|
ce.uid, ce.euid, ce.suid, ce.fsuid);
|
|
|
|
pr_msg("gid %u egid %u sgid %u fsgid %u\n",
|
|
|
|
ce.gid, ce.egid, ce.sgid, ce.fsgid);
|
2012-01-27 21:43:32 +04:00
|
|
|
|
|
|
|
show_cap("Inh", ce.cap_inh);
|
|
|
|
show_cap("Eff", ce.cap_eff);
|
|
|
|
show_cap("Prm", ce.cap_prm);
|
|
|
|
show_cap("Bnd", ce.cap_bnd);
|
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("secbits: %x\n", ce.secbits);
|
2012-01-27 21:43:32 +04:00
|
|
|
out:
|
|
|
|
pr_img_tail(CR_FD_CREDS);
|
|
|
|
}
|
|
|
|
|
2012-01-12 21:53:46 +04:00
|
|
|
static int show_pstree(int fd_pstree, struct list_head *collect)
|
2011-12-05 15:57:47 +04:00
|
|
|
{
|
|
|
|
struct pstree_entry e;
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_head(CR_FD_PSTREE);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
u32 pid;
|
|
|
|
int ret;
|
2012-01-12 21:53:46 +04:00
|
|
|
struct pstree_item *item = NULL;
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
ret = read_img_eof(fd_pstree, &e);
|
|
|
|
if (ret <= 0)
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("pid: %8d nr_children: %8d nr_threads: %8d\n",
|
|
|
|
e.pid, e.nr_children, e.nr_threads);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2012-01-12 21:53:46 +04:00
|
|
|
if (collect) {
|
|
|
|
item = xzalloc(sizeof(struct pstree_item));
|
|
|
|
if (!item)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
item->pid = e.pid;
|
|
|
|
item->nr_threads = e.nr_threads;
|
|
|
|
item->threads = xzalloc(sizeof(u32) * e.nr_threads);
|
|
|
|
if (!item->threads) {
|
|
|
|
xfree(item);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
list_add_tail(&item->list, collect);
|
|
|
|
}
|
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
if (e.nr_children) {
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\\\n");
|
|
|
|
pr_msg(" +--- children: ");
|
2011-12-05 15:57:47 +04:00
|
|
|
while (e.nr_children--) {
|
2012-01-22 20:20:40 +04:00
|
|
|
ret = read_img_eof(fd_pstree, &pid);
|
|
|
|
if (ret <= 0)
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg(" %6d", pid);
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n");
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (e.nr_threads) {
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg(" \\\n");
|
|
|
|
pr_msg(" --- threads: ");
|
2011-12-05 15:57:47 +04:00
|
|
|
while (e.nr_threads--) {
|
2012-01-22 20:20:40 +04:00
|
|
|
ret = read_img_eof(fd_pstree, &pid);
|
|
|
|
if (ret <= 0)
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg(" %6d", pid);
|
2012-01-12 21:53:46 +04:00
|
|
|
if (item)
|
|
|
|
item->threads[e.nr_threads] = pid;
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n");
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_tail(CR_FD_PSTREE);
|
2012-01-12 21:53:46 +04:00
|
|
|
return 0;
|
2011-12-05 15:57:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void show_core_regs(int fd_core)
|
|
|
|
{
|
|
|
|
struct user_regs_entry regs;
|
|
|
|
struct desc_struct tls;
|
|
|
|
int i;
|
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n\t---[GP registers set]---\n");
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-22 20:16:33 +04:00
|
|
|
lseek(fd_core, GET_FILE_OFF(struct core_entry, arch.gpregs), SEEK_SET);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
if (read_img(fd_core, ®s) < 0)
|
|
|
|
goto err;
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
pr_regs4(regs, cs, ip, ds, es);
|
|
|
|
pr_regs4(regs, ss, sp, fs, gs);
|
|
|
|
pr_regs4(regs, di, si, dx, cx);
|
|
|
|
pr_regs4(regs, ax, r8, r9, r10);
|
|
|
|
pr_regs4(regs, r11, r12, r13, r14);
|
|
|
|
pr_regs3(regs, r15, bp, bx);
|
|
|
|
pr_regs4(regs, orig_ax, flags, fs_base, gs_base);
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n");
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
err:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-22 20:24:04 +04:00
|
|
|
static inline char *task_state_str(int state)
|
|
|
|
{
|
|
|
|
switch (state) {
|
|
|
|
case TASK_ALIVE:
|
|
|
|
return "running/sleeping";
|
|
|
|
case TASK_DEAD:
|
|
|
|
return "zombie";
|
|
|
|
default:
|
|
|
|
return "UNKNOWN";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
static void show_core_rest(int fd_core)
|
2011-10-01 13:24:34 +04:00
|
|
|
{
|
2012-01-22 20:20:40 +04:00
|
|
|
struct task_core_entry tc;
|
2011-12-05 15:57:47 +04:00
|
|
|
int i;
|
2011-10-01 13:24:34 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc), SEEK_SET);
|
|
|
|
if (read_img(fd_core, &tc) < 0)
|
|
|
|
goto err;
|
2011-10-12 18:05:07 +04:00
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n\t---[Task parameters]---\n");
|
|
|
|
pr_msg("\tPersonality: %x\n", tc.personality);
|
|
|
|
pr_msg("\tCommand: %s\n", tc.comm);
|
|
|
|
pr_msg("\tState: %d (%s)\n",
|
|
|
|
(int)tc.task_state,
|
|
|
|
task_state_str((int)tc.task_state));
|
|
|
|
|
|
|
|
pr_msg("\t Exit code: %u\n",
|
|
|
|
(unsigned int)tc.exit_code);
|
|
|
|
|
|
|
|
pr_msg("\tBrk: %lx\n", tc.mm_brk);
|
|
|
|
pr_msg("\tStart code: %lx\n", tc.mm_start_code);
|
|
|
|
pr_msg("\tEnd code: %lx\n", tc.mm_end_code);
|
|
|
|
pr_msg("\tStart stack: %lx\n", tc.mm_start_stack);
|
|
|
|
pr_msg("\tStart data: %lx\n", tc.mm_start_data);
|
|
|
|
pr_msg("\tEnd data: %lx\n", tc.mm_end_data);
|
|
|
|
pr_msg("\tStart brk: %lx\n", tc.mm_start_brk);
|
|
|
|
pr_msg("\tArg start: %lx\n", tc.mm_arg_start);
|
|
|
|
pr_msg("\tArg end: %lx\n", tc.mm_arg_end);
|
|
|
|
pr_msg("\tEnv start: %lx\n", tc.mm_env_start);
|
|
|
|
pr_msg("\tEnv end: %lx\n", tc.mm_env_end);
|
|
|
|
pr_msg("\n\tBlkSig: %lx\n", tc.blk_sigset);
|
|
|
|
pr_msg("\n");
|
2011-11-21 20:19:35 +04:00
|
|
|
|
|
|
|
err:
|
2011-12-05 15:57:47 +04:00
|
|
|
return;
|
2011-11-21 20:19:35 +04:00
|
|
|
}
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
static void show_core(int fd_core, bool show_content)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
2011-12-05 15:57:47 +04:00
|
|
|
struct stat stat;
|
|
|
|
bool is_thread;
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
if (fstat(fd_core, &stat)) {
|
2012-01-31 15:13:05 +04:00
|
|
|
pr_perror("Can't get stat on core file");
|
2011-12-05 15:57:47 +04:00
|
|
|
goto out;
|
2011-09-23 12:00:45 +04:00
|
|
|
}
|
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
is_thread = (stat.st_size == GET_FILE_OFF_AFTER(struct core_entry));
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
if (is_thread)
|
|
|
|
pr_img_head(CR_FD_CORE, " (thread)");
|
|
|
|
else
|
|
|
|
pr_img_head(CR_FD_CORE);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
show_core_regs(fd_core);
|
|
|
|
show_core_rest(fd_core);
|
2011-09-23 12:00:45 +04:00
|
|
|
out:
|
2012-01-12 15:16:33 +04:00
|
|
|
pr_img_tail(CR_FD_CORE);
|
2011-09-23 12:00:45 +04:00
|
|
|
}
|
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
static int cr_parse_file(struct cr_options *opts)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
2011-12-05 15:57:47 +04:00
|
|
|
u32 magic;
|
|
|
|
int fd = -1;
|
|
|
|
int ret = -1;
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
fd = open(opts->show_dump_file, O_RDONLY);
|
|
|
|
if (fd < 0) {
|
2012-01-31 15:13:05 +04:00
|
|
|
pr_perror("Can't open %s", opts->show_dump_file);
|
2011-12-05 15:57:47 +04:00
|
|
|
goto err;
|
2011-09-23 12:00:45 +04:00
|
|
|
}
|
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
if (read_img(fd, &magic) < 0)
|
|
|
|
goto err;
|
2011-12-05 15:57:47 +04:00
|
|
|
|
|
|
|
switch (magic) {
|
|
|
|
case FDINFO_MAGIC:
|
2012-01-12 15:16:33 +04:00
|
|
|
show_files(fd);
|
2011-12-05 15:57:47 +04:00
|
|
|
break;
|
|
|
|
case PAGES_MAGIC:
|
2012-01-12 15:16:33 +04:00
|
|
|
show_pages(fd, opts->show_pages_content);
|
2011-12-05 15:57:47 +04:00
|
|
|
break;
|
|
|
|
case CORE_MAGIC:
|
2012-01-12 15:16:33 +04:00
|
|
|
show_core(fd, opts->show_pages_content);
|
2011-12-05 15:57:47 +04:00
|
|
|
break;
|
2012-03-21 14:22:00 +04:00
|
|
|
case VMAS_MAGIC:
|
|
|
|
show_vmas(fd);
|
|
|
|
break;
|
2011-12-05 15:57:47 +04:00
|
|
|
case PSTREE_MAGIC:
|
2012-01-12 21:53:46 +04:00
|
|
|
show_pstree(fd, NULL);
|
2011-12-05 15:57:47 +04:00
|
|
|
break;
|
|
|
|
case PIPES_MAGIC:
|
2012-01-12 15:16:33 +04:00
|
|
|
show_pipes(fd);
|
2011-12-05 15:57:47 +04:00
|
|
|
break;
|
|
|
|
case SIGACT_MAGIC:
|
2012-01-12 15:16:33 +04:00
|
|
|
show_sigacts(fd);
|
2011-12-05 15:57:47 +04:00
|
|
|
break;
|
2011-12-26 22:12:03 +04:00
|
|
|
case UNIXSK_MAGIC:
|
2012-01-12 15:16:33 +04:00
|
|
|
show_unixsk(fd);
|
2011-12-26 22:12:03 +04:00
|
|
|
break;
|
2012-01-17 16:28:35 +03:00
|
|
|
case INETSK_MAGIC:
|
|
|
|
show_inetsk(fd);
|
|
|
|
break;
|
2012-02-29 16:07:11 +03:00
|
|
|
case SK_QUEUES_MAGIC:
|
|
|
|
show_sk_queues(fd);
|
|
|
|
break;
|
2012-01-24 16:45:19 +04:00
|
|
|
case ITIMERS_MAGIC:
|
|
|
|
show_itimers(fd);
|
|
|
|
break;
|
2012-01-26 15:28:00 +04:00
|
|
|
case UTSNS_MAGIC:
|
|
|
|
show_utsns(fd);
|
|
|
|
break;
|
2012-01-27 21:43:32 +04:00
|
|
|
case CREDS_MAGIC:
|
|
|
|
show_creds(fd);
|
|
|
|
break;
|
2012-02-08 12:13:38 +03:00
|
|
|
case IPCNS_VAR_MAGIC:
|
|
|
|
show_ipc_var(fd);
|
2012-01-31 22:29:11 +04:00
|
|
|
break;
|
2012-02-09 12:09:48 +03:00
|
|
|
case IPCNS_SHM_MAGIC:
|
|
|
|
show_ipc_shm(fd);
|
|
|
|
break;
|
2012-02-13 20:27:42 +03:00
|
|
|
case IPCNS_MSG_MAGIC:
|
|
|
|
show_ipc_msg(fd);
|
|
|
|
break;
|
2012-02-14 19:54:13 +03:00
|
|
|
case IPCNS_SEM_MAGIC:
|
|
|
|
show_ipc_sem(fd);
|
|
|
|
break;
|
2011-12-05 15:57:47 +04:00
|
|
|
default:
|
2011-12-28 20:34:00 +04:00
|
|
|
pr_err("Unknown magic %x on %s\n", magic, opts->show_dump_file);
|
2011-12-05 15:57:47 +04:00
|
|
|
goto err;
|
2011-09-23 12:00:45 +04:00
|
|
|
}
|
2011-12-05 15:57:47 +04:00
|
|
|
ret = 0;
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
err:
|
|
|
|
close_safe(&fd);
|
|
|
|
return ret;
|
2011-09-23 12:00:45 +04:00
|
|
|
}
|
|
|
|
|
2011-12-05 15:57:47 +04:00
|
|
|
static int cr_show_all(unsigned long pid, struct cr_options *opts)
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
2011-12-05 15:57:47 +04:00
|
|
|
struct cr_fdset *cr_fdset = NULL;
|
|
|
|
struct pstree_item *item = NULL;
|
|
|
|
LIST_HEAD(pstree_list);
|
2011-09-23 12:00:45 +04:00
|
|
|
int i, ret = -1;
|
|
|
|
|
2012-03-02 11:09:39 +04:00
|
|
|
cr_fdset = cr_show_fdset_open(pid, CR_FD_DESC_PSTREE | CR_FD_DESC_SK_QUEUES);
|
2011-09-23 12:00:45 +04:00
|
|
|
if (!cr_fdset)
|
|
|
|
goto out;
|
|
|
|
|
2012-01-12 21:53:46 +04:00
|
|
|
ret = show_pstree(cr_fdset->fds[CR_FD_PSTREE], &pstree_list);
|
2011-09-23 12:00:45 +04:00
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
2012-02-29 16:07:11 +03:00
|
|
|
ret = show_sk_queues(cr_fdset->fds[CR_FD_SK_QUEUES]);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
2012-01-12 21:25:19 +04:00
|
|
|
close_cr_fdset(&cr_fdset);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-26 15:27:00 +04:00
|
|
|
ret = try_show_namespaces(pid);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
list_for_each_entry(item, &pstree_list, list) {
|
|
|
|
|
2012-02-08 20:19:39 +03:00
|
|
|
cr_fdset = cr_show_fdset_open(item->pid, CR_FD_DESC_TASK);
|
2011-09-23 12:00:45 +04:00
|
|
|
if (!cr_fdset)
|
|
|
|
goto out;
|
|
|
|
|
2012-01-12 15:17:51 +04:00
|
|
|
show_core(cr_fdset->fds[CR_FD_CORE], opts->show_pages_content);
|
2011-10-20 23:11:31 +04:00
|
|
|
|
|
|
|
if (item->nr_threads > 1) {
|
|
|
|
struct cr_fdset *cr_fdset_th;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < item->nr_threads; i++) {
|
|
|
|
|
|
|
|
if (item->threads[i] == item->pid)
|
|
|
|
continue;
|
|
|
|
|
2012-02-08 20:19:39 +03:00
|
|
|
cr_fdset_th = cr_show_fdset_open(item->threads[i], CR_FD_DESC_CORE);
|
2012-01-12 15:18:32 +04:00
|
|
|
if (!cr_fdset_th)
|
2011-10-20 23:11:31 +04:00
|
|
|
goto out;
|
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("\n");
|
|
|
|
pr_msg("Thread: %d\n", item->threads[i]);
|
|
|
|
pr_msg("----------------------------------------\n");
|
2011-10-20 23:11:31 +04:00
|
|
|
|
2012-01-12 15:17:51 +04:00
|
|
|
show_core(cr_fdset_th->fds[CR_FD_CORE], opts->show_pages_content);
|
2011-10-20 23:11:31 +04:00
|
|
|
|
2012-03-02 00:59:59 +04:00
|
|
|
pr_msg("----------------------------------------\n");
|
2011-10-20 23:11:31 +04:00
|
|
|
|
2012-01-12 21:25:19 +04:00
|
|
|
close_cr_fdset(&cr_fdset_th);
|
2011-10-20 23:11:31 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-21 14:22:00 +04:00
|
|
|
show_vmas(cr_fdset->fds[CR_FD_VMAS]);
|
|
|
|
|
2012-01-12 15:17:51 +04:00
|
|
|
show_pipes(cr_fdset->fds[CR_FD_PIPES]);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2012-01-12 15:17:51 +04:00
|
|
|
show_files(cr_fdset->fds[CR_FD_FDINFO]);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2012-01-12 15:17:51 +04:00
|
|
|
show_sigacts(cr_fdset->fds[CR_FD_SIGACT]);
|
2011-12-05 15:57:47 +04:00
|
|
|
|
2012-01-12 15:17:51 +04:00
|
|
|
show_unixsk(cr_fdset->fds[CR_FD_UNIXSK]);
|
2011-12-26 22:12:03 +04:00
|
|
|
|
2012-01-17 16:28:35 +03:00
|
|
|
show_inetsk(cr_fdset->fds[CR_FD_INETSK]);
|
|
|
|
|
2012-01-24 16:45:19 +04:00
|
|
|
show_itimers(cr_fdset->fds[CR_FD_ITIMERS]);
|
|
|
|
|
2012-01-27 21:43:32 +04:00
|
|
|
show_creds(cr_fdset->fds[CR_FD_CREDS]);
|
|
|
|
|
2012-01-12 21:25:19 +04:00
|
|
|
close_cr_fdset(&cr_fdset);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-10-04 01:50:19 +04:00
|
|
|
if (opts->leader_only)
|
2011-09-23 12:00:45 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2011-12-05 15:57:47 +04:00
|
|
|
free_pstree(&pstree_list);
|
2012-01-12 21:25:19 +04:00
|
|
|
close_cr_fdset(&cr_fdset);
|
2011-09-23 12:00:45 +04:00
|
|
|
return ret;
|
|
|
|
}
|
2011-12-05 15:57:47 +04:00
|
|
|
|
|
|
|
int cr_show(unsigned long pid, struct cr_options *opts)
|
|
|
|
{
|
2011-12-28 20:38:00 +04:00
|
|
|
if (opts->show_dump_file)
|
2011-12-05 15:57:47 +04:00
|
|
|
return cr_parse_file(opts);
|
|
|
|
|
|
|
|
return cr_show_all(pid, opts);
|
|
|
|
}
|