#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
typedef unsighed long int uint64;
#define MAX 100
//定义类型:线程或者是资源
enum Type{PROCESS, RESOURCE};
//定义源类型
struct source_type{
uint64 id;
enum Type type;
uint64 lock_id;
int degress;
};
//定义图中的一个顶点
struct vertex{
struct source_type s;
struct vertex *next;
};
//定义任务图
struct task_graph{
struct vertex list[MAX];
int num;
struct source_type locklist[MAX];
int lockidx;
pthread_mutex_t mutex;
};
struct task_graph *tg = NULL;
int path[MAX+1];
int visited[MAX];
int k = 0;
int deadlock = 0;
//创建一个新的顶点
struct vertex *create_vertex(struct source_type type){
struct vertex *tex = (struct vertex *)mallco(sizeof(struct vertex));
tex->s = type;
tex->next = NULL;
return tex;
}
//在任务图中搜索一个顶点
int search_vertex(struct source_type type){
int i = 0;
for(i = 0;i < tg->num ;i++){
if(tg->list[i].s.type == type.type && tg->list[i].s.id == type.id){
return i;
}
}
return -1;
}
//添加一个顶点到任务图
void add_vertex(struct source_type type){
if(search_vertex(type) == -1){
tg->list[tg->num].s = type;
tg->list[tg->num].next = NULL;
tg->num ++;
}
}
//在任务图中添加一条边
int add_edge(struct source_type from, struct source_type to){
add_vertex(from);
add_vertex(to);
struct vertex *v = &(tg->list[search_vertex(from)]);
while(v->next !=NULL){
v = v->next;
}
v->next = create_vertex(to);
}
//验证任务图中是否存在一条边
int verify_edge(struct source_type i, struct source_type j){
if(tg->num ==0) return 0;
int idx = search_vertex(i);
if(idx == -1)return 0;
struct vertex *v = &(tg->list[idx]);
while(v != NULL){
if(v->s.id == j.id)return 1;
v = v->next;
}
return 0;
}
//从任务图中删除一条边
int remove_edge(struct source_type from, struct source_type to){
int idxi = search_vertex(from);
int idxj = search_vertex(to);
if(idxi != -1 && idxj != -1){
struct *v = &tg->list[idxi];
struct vertex *remove;
while(v->next !=NULL){
if(v->s.id == to.id){
remove = v->next;
v->next = v->next->next;
free(remove);
break;
}
v = v->next;
}
}
}
//打印死锁循环
void print_deadlock(void){
int i = 0;
printf("cycle :");
for(i = 0;i< k-1;i ++){
printf("%ld --> ", tg->list[path[i]].s.id);
}
printf("%ld\n", tg->list[path[i]].s.id);
}
//深度优先搜索
int DFS(int idx){
struct vertex *ver = &tg->list[idx];
if(visited[idx] ==1){
path[k++] = idx;
print_deadlock();
deadlock =1;
return 0;
}
visited[idx] = 1;
path[k++] = idx;
while(ver->next != NULL){
DFS(search_vertex(ver->next->s));
k --;
ver = ver->next;
}
return 1;
}
//搜索任务图中的循环
int search_for_cycle(int idx){
struct vertex *ver = &tg->list[idx];
visited[idx] = 1;
k = 0;
path[k++] = idx;
while(ver->next != NULL){
int i = 0;
for(i = 0; i < tg->num; i++){
if(i == idx)continue;
visited[i] = 0;
}
for(i = 1; i<=MAX; i++){
path[i] = -1;
}
k = 1;
DFS(search_vertex(ver->next->s));
ver = ver->next;
}
}
//搜索锁
int search_lock(uint64 lock){
int i = 0;
for(i = 0; i< tg->lockidx; i++){
if(tg->locklist[i].lock_id = lock){
return i;
}
}
return -1;
}
//搜索空锁
int search_empty_lock(uint64 lock){
int i = 0;
for(i =0; i< tg->lockidx; i++){
if(tg->locklist[i].lock_id == 0){
return i;
}
}
return tg->lockidx;
}
//锁之前调用
void lock_before(uint64_t tid, uint64_t lockaddr){
int idx = 0;
for(idx = 0; idx < tg->lockidx; idx ++){
if(tg->locklist[idx].lock_id == lockaddr){
struct source_type from;
from.id = tid;
from.type = PROCESS;
add_vertex(from);
struct source_type to;
to.id = tg->locklist[idx].id;
to.type = PROCESS;
add_vertex(to);
tg->locklist[idx].degress ++;
if(!verify_edge(from,to))add_edge(from, to);
}
}
}
//锁之后调用
void lock_after(uint64_t tid, uint64_t lockaddr){
int idx = 0;
if(-1 == (idx = search_lock(lockaddr))){
int eidx = search_empty_lock(lockaddr);
tg->locklist[eidx].id = tid;
tg->locklist[eidx].lock_id = lockaddr;
tg->lockidx ++;
}else{
struct source_type from;
from.id = tid;
from.type = PROCESS;
add_vertex(from);
struct source_type to;
to.id = tg->locklist[idx].id;
to.type = PROCESS;
add_vertex(to);
tg->locklist[idx].degress --;
if (verify_edge(from, to))remove_edge(from, to);
tg->locklist[idx].id = tid;
}
}
//解锁之前调用
void unlock_after(uint64_t tid, uint64_t lockaddr){
int idx = search_lock(lockaddr);
if (tg->locklist[idx].degress == 0) {
tg->locklist[idx].id = 0;
tg->locklist[idx].lock_id = 0;
}
}
//检查当前是否有死锁
void check_dead_lock(void){
int i = 0;
deadlock = 0;
for (i = 0;i < tg->num;i ++) {
if (deadlock == 1) break;
search_for_cycle(i);
}
if (deadlock == 0) {
printf("no deadlock\n");
}
}
//定期调用检查死锁
static void *thread_routine(void *args) {
while (1) {
sleep(5);
check_dead_lock();
}
}
//初始化任务图并启动检查线程
void start_check(void) {
tg = (struct task_graph*)malloc(sizeof(struct task_graph));
tg->num = 0;
tg->lockidx = 0;
pthread_t tid;
pthread_create(&tid, NULL, thread_routine, NULL);
}
//hook 定义自己的互斥锁
typedef int (*pthread_mutex_lock_t)(pthread_mutex_t *mutex);
pthread_mutex_lock_t pthread_mutex_lock_f = NULL;
typedef int (*pthread_mutex_unlock_t)(pthread_mutex_t *mutex);
pthread_mutex_unlock_t pthread_mutex_unlock_f = NULL;
// implement
int pthread_mutex_lock(pthread_mutex_t *mutex) {
pthread_t selfid = pthread_self();
lock_before((uint64_t)selfid, (uint64_t)mutex);
pthread_mutex_lock_f(mutex);
lock_after((uint64_t)selfid, (uint64_t)mutex);
}
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
pthread_mutex_unlock_f(mutex);
pthread_t selfid = pthread_self();
unlock_after((uint64_t)selfid, (uint64_t)mutex);
}
// init
void init_hook(void) {
if (!pthread_mutex_lock_f)
pthread_mutex_lock_f = dlsym(RTLD_NEXT, "pthread_mutex_lock");
if (!pthread_mutex_unlock_f)
pthread_mutex_unlock_f = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
}
手撕死锁检测
最新推荐文章于 2025-08-25 11:00:41 发布