ret = snprintf(prstatus_name, NAME_MAX, "/%s.prstatus", crash_info.pid_info);
if (ret < 0) {
+ _E("Failed to snprintf for prstatus path");
goto close_fd;
}
crash_info.prstatus_fd = shm_open(prstatus_name, O_RDWR | O_CREAT, 0600);
if (crash_info.prstatus_fd < 0) {
+ _E("shm_open: %s", strerror(errno));
goto close_fd;
}
ret = shm_unlink(prstatus_name);
if (ret < 0) {
+ _E("shm_unlink: %s", strerror(errno));
goto close_fd;
}
ret = fcntl(crash_info.prstatus_fd, F_GETFD);
if (ret < 0) {
+ _E("fcntl(): %s", strerror(errno));
goto close_fd;
}
ret = fcntl(crash_info.prstatus_fd, F_SETFD, ret & ~FD_CLOEXEC);
if (ret < 0) {
+ _E("fcntl(): %s", strerror(errno));
goto close_fd;
}
ret = ftruncate(crash_info.prstatus_fd, sizeof(struct elf_prstatus));
if (ret < 0) {
+ _E("ftruncate(): %s", strerror(errno));
goto close_fd;
}
set(CRASH_STACK_BIN "crash-stack")
# Common source code files
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
set(CRASH_STACK_SRCS crash-stack.c crash-stack-libunw.c unwind.c proc.c mem_map.c)
# Add architecture dependent source files
include(FindPkgConfig)
pkg_check_modules(LIBUNWIND REQUIRED libunwind-generic)
-set_property(TARGET ${CRASH_STACK_BIN} APPEND_STRING PROPERTY COMPILE_FLAGS ${LIBUNWIND_CFLAGS_OTHER})
+pkg_check_modules(DLOG REQUIRED dlog)
+set_property(TARGET ${CRASH_STACK_BIN} APPEND_STRING PROPERTY COMPILE_FLAGS ${LIBUNWIND_CFLAGS} ${DLOG_CFLAGS})
# Linking
-target_link_libraries(${CRASH_STACK_BIN} ${LIBUNWIND_LIBRARIES} ${EBL_LIBRARY} elf dl stdc++)
+target_link_libraries(${CRASH_STACK_BIN} ${DLOG_LIBRARIES} ${LIBUNWIND_LIBRARIES} ${EBL_LIBRARY} elf dl stdc++)
# Installing
install(TARGETS ${CRASH_STACK_BIN} DESTINATION libexec)
#include "crash-stack.h"
+#define LOG_TAG "CRASH_STACK"
+#include "shared/log.h"
+
#define MAXPROCNAMELEN 1024
void _create_crash_stack(Dwfl *dwfl, pid_t pid, Callstack *callstack, elf_gregset_t *regs)
#include "crash-stack.h"
+#define LOG_TAG "CRASH_STACK"
+#include "shared/log.h"
#define BUF_SIZE (BUFSIZ)
#define HEXA 16
char *registers = _crash_stack_get_memory_for_registers(&size);
if (NULL == registers) {
- fprintf(errfile, "Cannot get memory for registers (not implemented for this architecture\n");
+ _E("Cannot get memory for registers (not implemented for this architecture");
return -1;
}
#undef DEF_STR
if (SIGHUP > signo || signo > SIGSYS) {
- fprintf(errfile, "Invalid signal number: %d\n", signo);
+ _E("Invalid signal number: %d", signo);
return;
}
/* print thread */
dir = opendir(task_path);
if (!dir) {
- fprintf(errfile, "[crash-stack] cannot open %s\n", task_path);
+ _E("opendir(%s): %s", task_path, strerror(errno));
} else {
while ((dentry = readdir(dir))) {
if (strcmp(dentry->d_name, ".") == 0 ||
snprintf(file_path, PATH_MAX, "/proc/%d/maps", pid);
if ((fd = open(file_path, O_RDONLY)) < 0) {
- fprintf(errfile, "[crash-stack] cannot open %s\n", file_path);
+ _E("open(%s): %s", file_path, strerror(errno));
} else {
/* parsing the maps to get code segment address*/
head = get_addr_list_from_maps(fd);
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (t_node == NULL) {
- fprintf(errfile, "error : mmap\n");
+ _E("mmap(): %s", strerror(errno));
return NULL;
}
memcpy(t_node->perm, perm, PERM_LEN+1);
fprintf(outputfile, "\nMemory information\n");
if ((fd = open("/proc/meminfo", O_RDONLY)) < 0) {
- fprintf(errfile, "[crash-stack] cannot open /proc/meminfo\n");
+ _E("open(/proc/meminfo): %s", strerror(errno));
} else {
while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) {
sscanf(linebuf, "%16s %16s %*s", infoname, memsize);
snprintf(file_path, PATH_MAX, "/proc/%d/status", pid);
if ((fd = open(file_path, O_RDONLY)) < 0) {
- fprintf(errfile, "[crash-stack] cannot open %s\n", file_path);
+ _E("open(%s): %s", file_path, strerror(errno));
} else {
while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) {
sscanf(linebuf, "%16s %16s %*s", infoname, memsize);
char buf[1024];
if (fseek(bufferfile, 0, SEEK_SET) < 0) {
- fprintf(errfile, "Failed to fseek\n");
+ _E("fseek(): %s", strerror(errno));
return;
}
while (!(feof(bufferfile) || ferror(bufferfile)) && (cnt = fread(buf, sizeof(char), sizeof(buf), bufferfile)) != 0) {
snprintf(path, PATH_MAX, "/proc/%d/task/%d/wchan", pid, tid);
fd = open(path, O_RDONLY);
if (fd == -1) {
- fprintf(errfile, "[crash-stack] cannot open %s\n", path);
+ _E("open(%s): %s", path, strerror(errno));
return -errno;
}
cnt = read(fd, buf, sizeof(buf));
if (cnt == -1 || cnt == sizeof(buf)) {
- fprintf(errfile, "[crash-stack] read %s error\n", path);
+ _E("read(%s): %s", path, strerror(errno));
close(fd);
return -errno;
}
if (threadnum > 1) {
dir = opendir(task_path);
if (!dir) {
- fprintf(errfile, "[crash-stack] cannot open %s\n", task_path);
+ _E("opendir(%s): %s", task_path, strerror(errno));
return -1;
} else {
while ((entry = readdir(dir)) != NULL) {
break;
case OPT_ERRFILE:
errfile = fopen(optarg, "w");
+ _W("--erroutput is deprecated");
break;
case OPT_PRSTATUS_FD:
prstatus_fd = strtol(optarg, &p, 10);
mode_t oldmode = umask(0077);
if (mkstemp(bufferfile_path) < 0) {
- fprintf(errfile, "Failed to create buffer file.\n");
+ _E("mkstemp(%s): %s", bufferfile_path, strerror(errno));
return errno;
}
umask(oldmode);
if ((bufferfile = fopen(bufferfile_path, "w+")) == NULL) {
- fprintf(errfile, "Failed to open buffer file.\n");
+ _E("fopen(%s): %s", bufferfile_path, strerror(errno));
return errno;
}
unlink(bufferfile_path);
__crash_stack_print_maps(bufferfile, pid);
if (pid <= 1) {
- fprintf(errfile,
- "Usage: %s [--output file] [--erroutput file] [--pid <pid> [--tid <tid>]]\n",
+ _E( "Usage: %s [--output file] [--erroutput file] [--pid <pid> [--tid <tid>]]",
argv[0]);
+
return 1;
}
* DAMAGE.
*/
+#define LOG_TAG "CRASH_STACK"
+#include "shared/log.h"
#include "mem_map.h"
#include "proc.h"
for (i = 0; i < region->num_data_chunks; ++i) {
if (in(chunk->start, (*cur)->start, (*cur)->length) ||
- fprintf(stderr, "error: overlapping chunks: existing: %p-%p "
- "new: %p-%p\n",
- (*cur)->start,
- (*cur)->start + (*cur)->length,
- chunk->start,
- chunk_ceil);
in(chunk_ceil, (*cur)->start, (*cur)->length)) {
+ _E("Overlapping chunks: existing: %p-%p "
+ "new: %p-%p",
+ (*cur)->start,
+ (*cur)->start + (*cur)->length,
+ chunk->start,
+ chunk_ceil);
return -1;
}
if ((*cur)->start > chunk->start)
chunk->length = (size_t)end - (size_t)start;
rc = posix_memalign((void **)&chunk->data, align, chunk->length);
if (rc < 0) {
- perror("posix_memalign");
int err = errno;
free(chunk);
+ _E("posix_memalign:%s", strerror(err));
return NULL;
}
region->data_index[i++] = cur;
if (i > (int)region->num_data_chunks) {
- fprintf(stderr, "region %p: num_data_chunks=%zd but cur != NULL\n",
- region, region->num_data_chunks);
+ _E("region %p: num_data_chunks=%zd but cur != NULL",
+ region, region->num_data_chunks);
mem_region_print(region);
return -1;
}
size_t length = region->length;
if (region->path == NULL || *region->path == '\0') {
- fprintf(stderr, "trying to map file for region %p-%p "
- "with empty path\n",
- region->start, region->start + region->length);
+ _E("Trying to map file for region %p-%p with an empty path",
+ region->start, region->start + region->length);
return -1;
}
if (region->fd < 0) {
int err = errno;
mem_region_print(region);
+ _E("open(%s):%s", region->path, strerror(err));
return -1;
}
if (fstat(region->fd, &stat_buf) < 0) {
int err = errno;
- fprintf(stderr, "failed to stat file %s: %s\n", region->path, strerror(err));
+ _E("Unable to stat file %s: %s", region->path, strerror(err));
return -1;
}
if (data == MAP_FAILED) {
int err = errno;
- fprintf(stderr, "failed to mmap file %s (length 0x%zx, read, offset "
- "0x%zx): %s\n", region->path, region->length, region->offset,
- strerror(err));
+ _E("Unable to mmap file %s (length 0x%zx, read, offset 0x%zx): %s",
+ region->path, region->length, region->offset,
+ strerror(err));
return -1;
}
region->data_head = malloc(sizeof(struct mem_data_chunk));
if (region->data_head == NULL) {
int err = errno;
+ _E("Unable to allocate memory:%s", strerror(err));
munmap(data, length);
return -1;
}
region->data_index = malloc(sizeof(struct mem_data_chunk**));
if (region->data_index == NULL){
int err = errno;
+ _E("Unable to allocate memory:%s", strerror(err));
free(region->data_head);
munmap(data, length);
return -1;
region->data_index = malloc(sizeof(struct mem_data_chunk**));
if (region->data_index == NULL) {
int err = errno;
+ _E("Unable to allocate memory:%s", strerror(err));
return -1;
}
*region->data_index = region->data_head;
region->data_head = malloc(sizeof(struct mem_data_chunk));
if (region->data_head == NULL) {
int err = errno;
+ _E("Unable to allocate memory:%s", strerror(err));
return -1;
}
mem_data_chunk_init(region->data_head);
region->data_index = malloc(sizeof(struct mem_data_chunk**));
if (region->data_index == NULL) {
int err = errno;
+ _E("Unable to allocate memory:%s", strerror(err));
return -1;
}
*region->data_index = region->data_head;
if (region->data_index == NULL) {
if (region->num_data_chunks) {
- fprintf(stderr,
- "error: region %p-%p is not indexed but "
- "attempting to read word\n",
- region->start,
- region->start + region->length);
+ _E("Region %p-%p is not indexed but attempting to read word",
+ region->start,
+ region->start + region->length);
}
return NULL;
}
switch (region->type) {
case MEM_REGION_TYPE_EMPTY:
- fprintf(stderr,
- "error: trying to read word from empty region %p-%p\n",
- region->start,
- region->start + region->length);
+ _E("Trying to read word from empty region %p-%p",
+ region->start,
+ region->start + region->length);
return -1;
case MEM_REGION_TYPE_DELETED:
if (!opt_verbose)
return -1;
- fprintf(stderr,
- "no chunk of memory containing %p at region %p-%p\n",
- addr, region->start, region->start + region->length);
+ _E("No chunk of memory containing %p at region %p-%p",
+ addr, region->start, region->start + region->length);
mem_region_print(region);
for (i = 0; i < region->num_data_chunks; ++i) {
struct mem_data_chunk *chunk = region->data_index[i];
- fprintf(stderr, "chunk %zd: start %p length 0x%zx data %p\n",
- i, chunk->start, chunk->length, chunk->data);
+ _E("Chunk %zd: start %p length 0x%zx data %p",
+ i, chunk->start, chunk->length, chunk->data);
}
return -1;
}
if (in(region->start, (*cur)->start, (*cur)->length) ||
in(region_ceil, (*cur)->start, (*cur)->length))
{
- fprintf(stderr, "error: overlapping regions: existing: %p-%p "
- "new: %p-%p\n",
- (*cur)->start,
- (*cur)->start+(*cur)->length,
- region->start,
- region_ceil);
+ _E("Overlapping regions: existing: %p-%p "
+ "new: %p-%p",
+ (*cur)->start,
+ (*cur)->start+(*cur)->length,
+ region->start,
+ region_ceil);
return -1;
}
if ((*cur)->start > region->start)
if (map->list_index == NULL) {
if (map->num_regions) {
- fprintf(stderr,
- "error: map is not indexed but attempting to find region\n");
+ _E("map is not indexed but attempting to find region");
}
return NULL;
}
addr_region_compar);
if (region_ptr == NULL) {
- fprintf(stderr,
- "cannot find region of memory containing %p\n",
- addr);
+ _E("cannot find region of memory containing %p", addr);
region = NULL;
} else {
region = *region_ptr;
struct mem_region *region;
if ((region = mem_map_find_region(map, addr)) == NULL) {
- fprintf(stderr, "cannot get file region\n");
+ _E("Unable to get file region");
return NULL;
}
region->type != MEM_REGION_TYPE_DELETED &&
region->type != MEM_REGION_TYPE_VDSO &&
region->type != MEM_REGION_TYPE_VSYSCALL) {
- fprintf(stderr, "get file region: unexpected region type %s\n",
- str_mem_region_type(region->type));
+ _E("Unexpected region type %s",
+ str_mem_region_type(region->type));
mem_region_print(region);
return NULL;
}
{
struct mem_region *region;
- fprintf(stderr, "mem map with %zd regions\n", map->num_regions);
region = map->list_head;
for (; region != NULL; region = region->next)
mem_region_print(region);
#include <sys/wait.h>
#include <unistd.h>
+#define LOG_TAG "CRASH_STACK"
+#include "shared/log.h"
+
#ifndef SYS_process_vm_readv
#if defined(__i386)
#define SYS_process_vm_readv 365
snprintf(buf, sizeof(buf), "/proc/%d/status", pid);
if ((f = fopen(buf, "r")) == NULL) {
- fprintf(stderr, "cannot open %s: %s\n", buf, strerror(errno));
+ _E("Cannot open %s: %s", buf, strerror(errno));
return -1;
}
capacity = 0x100000;
buf = calloc(1, capacity);
if (buf == NULL) {
+ _E("Unable to allocate memory: %s", strerror(errno));
return NULL;
}
snprintf(buf, capacity, "/proc/%d/maps", pid);
if ((f = fopen(buf, "r")) == NULL) {
- fprintf(stderr, "cannot open %s: %s\n", buf, strerror(errno));
+ _E("Cannot open %s: %s", buf, strerror(errno));
goto create_maps_end;
}
map = malloc(sizeof(struct mem_map));
if (map == NULL){
+ _E("Unable to allocate memory: %s", strerror(errno));
goto create_maps_end;
}
mem_map_init(map);
capacity *= 2;
buf = realloc(buf, capacity);
if (buf == NULL) {
+ _E("Unable to reallocate memory: %s", strerror(errno));
mem_map_destroy(map);
map = NULL;
goto create_maps_end;
path);
if (scan < 10) {
- fprintf(stderr, "warning: unable to parse maps "
- "entry '%s' (read %d)\n", str, scan);
+ _W("Unable to parse maps "
+ "entry '%s' (read %d)", str, scan);
break;
}
region = malloc(sizeof(struct mem_region));
if (region == NULL) {
+ _E("Unable to allocate memory: %s", strerror(errno));
mem_map_destroy(map);
map = NULL;
break;
for (i = 0; i < n; ++i) {
int state = proc_state(tids[i]);
if (state < 0) {
- fprintf(stderr, "warning: could not get state of thread %d\n",
+ _W("Could not get state of thread %d",
tids[i]);
res[i] = '?';
continue;
}
if (!found) {
if (n || (user_tids[i] > nr_tids) || (user_tids[i] <= 0)) {
- fprintf(stderr, "unexpected thread %d\n", user_tids[i]);
+ _E("Unexpected thread %d", user_tids[i]);
return -1;
}
} else {
if (errno == ENOSYS)
rc = ENOSYS;
else
- perror("process_vm_readv");
+ _E("process_vm_readv: %s", strerror(errno));
goto process_vm_readv_end;
}
}
if (seg_count < 0) {
- fprintf(stderr, "unknown number of bytes returned by "
+ _E("Unknown number of bytes returned by "
"process_vm_readv: bytes_read=%zd "
- "bytes_total=%zd seg_count=%d\n",
+ "bytes_total=%zd seg_count=%d",
bytes_read, bytes_total, seg_count);
goto process_vm_readv_end;
}
snprintf(fname, sizeof(fname), "/proc/%d/mem", pid);
if ((fd = open(fname, O_RDONLY)) == -1) {
- fprintf(stderr, "cannot open %s\n", fname);
- perror(fname);
+ _E("Cannot open %s: %s", fname, strerror(errno));
return -1;
}
ssize_t rd = pread(fd, to, count, from);
if (rd == -1) {
- fprintf(stderr, "pread() at %s:0x%lx (#%d) failed: %s [%d]\n",
- fname, from, i, strerror(errno), errno);
+ _E("pread() at %s:0x%lx (#%d) failed: %s [%d]",
+ fname, from, i, strerror(errno), errno);
goto proc_mem_end;
}
int rc = copy_memory_process_vm_readv(pid, frames, n_frames);
if (rc == ENOSYS) {
if (opt_verbose) {
- fprintf(stderr, "process_vm_readv is not supported, falling "
- "back to /proc/pid/mem\n");
+ _E("process_vm_readv is not supported, falling "
+ "back to /proc/pid/mem");
}
} else {
return rc;
#include "proc.h"
#include "crash-stack.h"
+#define LOG_TAG "CRASH_STACK"
+#include "shared/log.h"
+
size_t stack_size = 0xa00000;
/*
if (fd > 0) {
if ((elf = elf_begin(fd, TBSTACK_ELF_C_READ, NULL)) == NULL)
- fprintf(stderr, "error:elf_begin: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_begin: %s", elf_errmsg(elf_errno()));
} else {
if ((elf = elf_memory(image, size)) == NULL)
- fprintf(stderr, "error:elf_memory: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_memory: %s", elf_errmsg(elf_errno()));
}
return elf;
return -1;
if (gelf_getehdr(elf, &ehdr) == NULL) {
- fprintf(stderr, "error:elf_getehdr: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_getehdr: %s", elf_errmsg(elf_errno()));
goto find_exidx_end;
}
while ((scn = elf_nextscn(elf, scn)) != NULL) {
if (gelf_getshdr(scn, &shdr) == NULL) {
- fprintf(stderr, "error:elf_getshdr: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_getshdr: %s", elf_errmsg(elf_errno()));
break;
}
Elf_Data *data = NULL;
if ((data = elf_getdata(scn, data)) == NULL) {
- fprintf(stderr, "error:elf_getdata: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_getdata: %s", elf_errmsg(elf_errno()));
break;
}
break;
default:
- fprintf(stderr, "unsupported encoding in "
- ".eh_frame_hdr: %d\n", (int)enc);
+ _E("unsupported encoding in "
+ ".eh_frame_hdr: %d", (int)enc);
return -1;
}
pos += 4;
if (version != 1) {
- fprintf(stderr, "error:unknown .ehf_frame_hdr version %d\n", version);
+ _E("unknown .ehf_frame_hdr version %d", version);
return -1;
}
return -1;
if (gelf_getehdr(elf, &ehdr) == NULL) {
- fprintf(stderr, "elf_getehdr: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_getehdr: %s", elf_errmsg(elf_errno()));
goto elf_section_offset_end;
}
char *str;
if (gelf_getshdr(scn, &shdr) == NULL) {
- fprintf(stderr, "elf_nextscn: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_getshdr: %s", elf_errmsg(elf_errno()));
break;
}
Elf_Data *data = NULL;
if ((data = elf_getdata(scn, data)) == NULL) {
- fprintf(stderr, "elf_getdata: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_getdata: %s", elf_errmsg(elf_errno()));
break;
}
array->s_cap <<= 1;
new_data = malloc(sizeof(GElf_Sym) * array->s_cap);
if (new_data == NULL) {
+ _E("malloc(): %s", strerror(errno));
return -1;
}
memcpy(new_data, array->s_data, sizeof(GElf_Sym) * (array->s_size-1));
GElf_Shdr shdr;
if (gelf_getshdr(scn, &shdr) == NULL) {
- fprintf(stderr, "elf_nextscn: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_nextscn: %s", elf_errmsg(elf_errno()));
goto proc_name_end;
}
int symbol_count;
if ((data = elf_getdata(scn, data)) == NULL) {
- fprintf(stderr, "elf_getdata: %s\n", elf_errmsg(elf_errno()));
+ _E("elf_getdata: %s", elf_errmsg(elf_errno()));
goto proc_name_end;
}
GElf_Sym s;
if (gelf_getsym(data, i, &s) == NULL) {
- fprintf(stderr, "elf_getsym: %s\n",
+ _E("elf_getsym: %s",
elf_errmsg(elf_errno()));
rc = -1;
goto proc_name_end;
if (addr >= s.st_value && addr < (s.st_value + s.st_size)) {
str = elf_strptr(elf, shdr.sh_link, s.st_name);
if (str == NULL) {
- fprintf(stderr, "elf_strptr #1: %s\n",
+ _E("elf_strptr #1: %s",
elf_errmsg(elf_errno()));
rc = -1;
goto proc_name_end;
if (cur->st_value <= addr && addr < next->st_value) {
str = elf_strptr(elf, cur->st_shndx, cur->st_name);
if (str == NULL) {
- fprintf(stderr, "elf_strptr #2: %s\n",
+ _E("elf_strptr #2: %s",
elf_errmsg(elf_errno()));
rc = -1;
goto proc_name_end;
(void) as;
(void) pip;
(void) arg;
- fprintf(debug, "%s is not supported\n", __func__);
}
/*
(void) as;
(void) dilap;
(void) arg;
- fprintf(debug, "%s is not supported\n", __func__);
return -UNW_ENOINFO;
}
(void) arg;
if (write) {
- fprintf(stderr, "access_mem: requested write, rejecting\n");
+ _E("access_mem: requested write, rejecting");
return -UNW_EINVAL;
}
(void) write;
(void) arg;
- fprintf(debug, "debug: requested register %d\n", reg);
- fflush(debug);
if (write) {
- fprintf(debug, "requested to write into register\n");
+ _E("requested to write into register");
return -UNW_EINVAL;
}
(void) write;
(void) arg;
- fprintf(debug, "access_fpreg is not supported\n");
- fflush(debug);
+ _D("access_fpreg is not supported");
return -UNW_ENOINFO;
}
(void) cp;
(void) arg;
- fprintf(debug, "resume is not supported\n");
- fflush(debug);
+ _D("resume is not supported");
return -UNW_ENOINFO;
}
long label;
if ((page = sysconf(_SC_PAGESIZE)) < 0) {
- perror("get pagesize");
+ _E("sysconf(_SC_PAGESIZE): %s", strerror(errno));
return NULL;
}
--page;