#include "config.h"
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <assert.h>
#include <sys/time.h>
#include "common.h"
#ifdef __powerpc__
#include <sys/ptrace.h>
#endif
static void handle_signal(Event *event);
static void handle_exit(Event *event);
static void handle_exit_signal(Event *event);
static void handle_syscall(Event *event);
static void handle_arch_syscall(Event *event);
static void handle_sysret(Event *event);
static void handle_arch_sysret(Event *event);
static void handle_clone(Event *event);
static void handle_exec(Event *event);
static void handle_breakpoint(Event *event);
static void handle_new(Event *event);
static void remove_proc(Process *proc);
static void callstack_push_syscall(Process *proc, int sysnum);
static void callstack_push_symfunc(Process *proc,
struct library_symbol *sym);
static void callstack_pop(Process *proc);
static char * shortsignal(Process *proc, int signum);
static char * sysname(Process *proc, int sysnum);
static char * arch_sysname(Process *proc, int sysnum);
void
handle_event(Event *event) {
debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", event->proc ? event->proc->pid : -1, event->type);
switch (event->type) {
case EVENT_NONE:
debug(1, "event: none");
return;
case EVENT_SIGNAL:
debug(1, "event: signal (%s [%d])",
shortsignal(event->proc, event->e_un.signum),
event->e_un.signum);
handle_signal(event);
return;
case EVENT_EXIT:
debug(1, "event: exit (%d)", event->e_un.ret_val);
handle_exit(event);
return;
case EVENT_EXIT_SIGNAL:
debug(1, "event: exit signal (%s [%d])",
shortsignal(event->proc, event->e_un.signum),
event->e_un.signum);
handle_exit_signal(event);
return;
case EVENT_SYSCALL:
debug(1, "event: syscall (%s [%d])",
sysname(event->proc, event->e_un.sysnum),
event->e_un.sysnum);
handle_syscall(event);
return;
case EVENT_SYSRET:
debug(1, "event: sysret (%s [%d])",
sysname(event->proc, event->e_un.sysnum),
event->e_un.sysnum);
handle_sysret(event);
return;
case EVENT_ARCH_SYSCALL:
debug(1, "event: arch_syscall (%s [%d])",
arch_sysname(event->proc, event->e_un.sysnum),
event->e_un.sysnum);
handle_arch_syscall(event);
return;
case EVENT_ARCH_SYSRET:
debug(1, "event: arch_sysret (%s [%d])",
arch_sysname(event->proc, event->e_un.sysnum),
event->e_un.sysnum);
handle_arch_sysret(event);
return;
case EVENT_CLONE:
debug(1, "event: clone (%u)", event->e_un.newpid);
handle_clone(event);
return;
case EVENT_EXEC:
debug(1, "event: exec()");
handle_exec(event);
return;
case EVENT_BREAKPOINT:
debug(1, "event: breakpoint");
handle_breakpoint(event);
return;
case EVENT_NEW:
debug(1, "event: new process");
handle_new(event);
return;
default:
fprintf(stderr, "Error! unknown event?\n");
exit(1);
}
}
/* TODO */
static void *
address_clone(void * addr) {
debug(DEBUG_FUNCTION, "address_clone(%p)", addr);
return addr;
}
static void *
breakpoint_clone(void * bp) {
Breakpoint * b;
debug(DEBUG_FUNCTION, "breakpoint_clone(%p)", bp);
b = malloc(sizeof(Breakpoint));
if (!b) {
perror("malloc()");
exit(1);
}
memcpy(b, bp, sizeof(Breakpoint));
return b;
}
typedef struct Pending_New Pending_New;
struct Pending_New {
pid_t pid;
Pending_New * next;
};
static Pending_New * pending_news = NULL;
static int
pending_new(pid_t pid) {
Pending_New * p;
debug(DEBUG_FUNCTION, "pending_new(%d)", pid);
p = pending_news;
while (p) {
if (p->pid == pid) {
return 1;
}
p = p->next;
}
return 0;
}
static void
pending_new_insert(pid_t pid) {
Pending_New * p;
debug(DEBUG_FUNCTION, "pending_new_insert(%d)", pid);
p = malloc(sizeof(Pending_New));
if (!p) {
perror("malloc()");
exit(1);
}
p->pid = pid;
p->next = pending_news;
pending_news = p;
}
static void
pending_new_remove(pid_t pid) {
Pending_New *p, *pred;
debug(DEBUG_FUNCTION, "pending_new_remove(%d)", pid);
p = pending_news;
if (p->pid == pid) {
pending_news = p->next;
free(p);
} else {
while (p) {
if (p->pid == pid) {
pred->next = p->next;
free(p);
}
pred = p;
p = p->next;
}
}
}
static void
handle_clone(Event * event) {
Process *p;
debug(DEBUG_FUNCTION, "handle_clone(pid=%d)", event->proc->pid);
p = malloc(sizeof(Process));
if (!p) {
perror("malloc()");
exit(1);
}
memcpy(p, event->proc, sizeof(Process));
p->breakpoints = dict_clone(event->proc->breakpoints, address_clone, breakpoint_clone);
p->pid = event->e_un.newpid;
p->parent = event->proc;
if (pending_new(p->pid)) {
pending_new_remove(p->pid);
if (p->breakpoint_being_enabled) {
enable_breakpoint(p->pid, p->breakpoint_being_enabled);
p->breakpoint_being_enabled = NULL;
}
if (event->proc->state == STATE_ATTACHED && options.follow) {
p->state = STATE_ATTACHED;
} else {
p->state = STATE_IGNORED;
}
continue_process(p->pid);
p->next = list_of_processes;
list_of_processes = p;
} else {
p->state = STATE_BEING_CREATED;
p->next = list_of_processes;
list_of_processes = p;
}
continue_process(event->proc->pid);
}
static void
handle_new(Event * event) {
Process * proc;
debug(DEBUG_FUNCTION, "handle_new(pid=%d)", event->e_un.newpid);
proc = pid2proc(event->e_un.newpid);
if (!proc) {
pending_new_insert(event->e_un.newpid);
} else {
assert(proc->state == STATE_BEING_CREATED);
if (proc->breakpoint_being_enabled) {
enable_breakpoint(proc->pid, proc->breakpoint_being_enabled);
proc->breakpoint_being_enabled = NULL;
}
if (options.follow) {
proc->state = STATE_ATTACHED;
} else {
proc->state = STATE_IGNORED;
}
continue_process(proc->pid);
}
}
static char *
shortsignal(Process *proc, int signum) {
static char *signalent0[] = {
#include "signalent.h"
};
static char *signalent1[] = {
#include "signalent1.h"
};
static char **signalents[] = { signalent0, signalent1 };
int nsignals[] = { sizeof signalent0 / sizeof signalent0[0],
sizeof signalent1 / sizeof signalent1[0]
};
debug(DEBUG_FUNCTION, "shortsignal(pid=%d, signum=%d)", proc->pid, signum);
if (proc->personality > sizeof signalents / sizeof signalents[0])
abort();
if (signum < 0 || signum >= nsignals[proc->personality]) {
return "UNKNOWN_SIGNAL";
} else {
return signalents[proc->personality][signum];
}
}
static char *
sysname(Process *proc, int sysnum) {
static char result[128];
static char *syscalent0[] = {
#include "syscallent.h"
};
static char *syscalent1[] = {
#include "syscallent1.h"
};
static char **syscalents[] = { syscalent0, syscalent1 };
int nsyscals[] = { sizeof syscalent0 / sizeof syscalent0[0],
sizeof syscalent1 / sizeof syscalent1[0]
};
debug(DEBUG_FUNCTION, "sysname(pid=%d, sysnum=%d)", proc->pid, sysnum);
if (proc->personality > sizeof syscalents / sizeof syscalents[0])
abort();
if (sysnum < 0 || sysnum >= nsyscals[proc->personality]) {
sprintf(result, "SYS_%d", sysnum);
return result;
} else {
sprintf(result, "SYS_%s",
syscalents[proc->personality][sysnum]);
return result;
}
}
static char *
arch_sysname(Process *proc, int sysnum) {
static char result[128];
static char *arch_syscalent[] = {
#include "arch_syscallent.h"
};
int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0];
debug(DEBUG_FUNCTION, "arch_sysname(pid=%d, sysnum=%d)", proc->pid, sysnum);
if (sysnum < 0 || sysnum >= nsyscals) {
sprintf(result, "ARCH_%d", sysnum);
return result;
} else {
sprintf(result, "ARCH_%s",
arch_syscalent[sysnum]);
return result;
}
}
static void
handle_signal(Event *event) {
debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
if (exiting && event->e_un.signum == SIGSTOP) {
pid_t pid = event->proc->pid;
disable_all_breakpoints(event->proc);
untrace_pid(pid);
remove_proc(event->proc);
return;
}
if (event->proc->state != STATE_IGNORED) {
output_line(eve
ltrace_0.5.3.orig.tar.gz
4星 · 超过85%的资源 需积分: 20 12 浏览量
2012-05-08
17:10:57
上传
评论
收藏 144KB GZ 举报
hame0245
- 粉丝: 0
- 资源: 24
最新资源
- 基于Vue+Echarts实现风力发电机中传感器的数据展示监控可视化系统+源代码+文档说明(高分课程设计)
- 基于单片机的风力发电机转速控制源码
- 基于C++实现的风力发电气动平衡监测系统+源代码+测量数据(高分课程设计)
- 毕业设计- 基于STM32F103C8T6 单片机,物联网技术的太阳能发电装置+源代码+文档说明+架构图+界面截图
- 基于 LSTM(长短期记忆)(即改进的循环神经网络)预测风力发电厂中风力涡轮机产生的功率+源代码+文档说明
- 基于stm32f103+空心杯电机+oled按键+运动算法
- 《CKA/CKAD应试指南/从docker到kubernetes 完全攻略》学习笔记 第1章docker基础(1.1-1.4)
- 基于python实现的水下压缩空气储能互补系统建模仿真与经济效益分析+源代码+论文
- 华中科技大学-自然语言处理实验,Bi-LSTM+CRF的中文分词框架,并且利用基于深度学习的方法进行中文命名实体识别++源码报告
- 基于动态罚函数的铁路车流分配与径路优化模型python源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈