#include <sys/uio.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <dirent.h>
+#include <sys/syscall.h>
static siginfo_t __siginfo;
static FILE *outputfile = NULL; ///< global output stream
static void __print_callstack(Callstack *callstack, Dwfl *dwfl, Elf *core, pid_t pid,
Elf_Data *notes)
{
- fprintf(outputfile, "Call stack");
- if (pid > 1) fprintf(outputfile, " for PID %d", pid);
- fprintf(outputfile, ":\n");
+ fprintf(outputfile, "\nCallstack Information");
+ if (pid > 1) fprintf(outputfile, " (PID:%d)", pid);
+ fprintf(outputfile, "\n");
+ fprintf(outputfile, "Call Stack Count: %d\n", (int)callstack->elems);
char *dem_buffer = NULL;
size_t it;
fprintf(outputfile, "unknown function\n");
}
}
+ fprintf(outputfile, "End of Call Stack\n");
+}
+
+/**
+ * @brief Print thread information
+ *
+ * @param outputfile File handle for printing report.
+ * @param pid PID of the inspected process
+ * @param tid TID of the inspected thread
+ */
+static void __crash_stack_print_threads(FILE* outputfile, pid_t pid, pid_t tid)
+{
+ int threadnum=1;
+ DIR *dir;
+ struct dirent entry;
+ struct dirent *dentry=NULL;
+ char task_path[PATH_MAX];
+ struct stat sb;
+
+
+ snprintf(task_path, PATH_MAX, "/proc/%d/task", pid);
+ if (stat(task_path, &sb) == -1) {
+ return;
+ }
+
+ threadnum = sb.st_nlink - 2;
+
+ if (threadnum > 1) {
+ fprintf(outputfile, "\nThreads Information\n");
+ fprintf(outputfile,
+ "Threads: %d\nPID = %d TID = %d\n",
+ threadnum, pid, tid);
+ /* print thread */
+ dir = opendir(task_path);
+ if (!dir) {
+ fprintf(stderr, "[crash-stack] cannot open %s\n", task_path);
+ } else {
+ while (readdir_r(dir, &entry, &dentry) == 0 && dentry) {
+ if (strcmp(dentry->d_name, ".") == 0 ||
+ strcmp(dentry->d_name, "..") == 0)
+ continue;
+ fprintf(outputfile, "%s ", dentry->d_name);
+ }
+ closedir(dir);
+ fprintf(outputfile, "\n");
+ }
+ }
+
}
/**
{
int c, i;
pid_t pid = 0;
- /* pid_t tid = 0; */
+ pid_t tid = 0;
const char *core_file_name;
pid = atoi(optarg);
break;
case OPT_TID:
- /* tid = atoi(optarg); */
+ tid = atoi(optarg);
break;
case OPT_OUTPUTFILE:
outputfile = fopen(optarg, "w");
/* Print registers */
_crash_stack_print_regs(outputfile);
+ /* Threads */
+ __crash_stack_print_threads(outputfile, pid, tid);
+
/* Print the results */
__print_callstack(&callstack, dwfl, core, pid, notes);