#include <Windows.h>
#include<process.h>
#include<conio.h>
#include <direct.h>
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
//#include <unistd.h>
#include <fcntl.h>
#define BUFSIZE 1024
#define N 200
#define M 5000
HANDLE g_Mutex = NULL;
/***************************************************主调函数节点和被调函数节点结构体,两个一样***********************************************/
typedef struct node_st//node 节点
{
int frame_size; //有的链表存放函数名和栈空间大小,要用到,不用则保留
char func_name[N]; //数据域 文件名
struct node_st* next[N]; //最多有200个被调函数
}link_node_st;
/**************************/
typedef struct node
{
FILE* fp;
link_node_st* p;
}node;
/*******************************************************主调函数节点创建*****************************************************************/
link_node_st* Caller_create(int frame_size, char* func_name)
{
link_node_st* pcaller = NULL;//用来保存新创建的主调函数的节点
//2.创建一个新的节点,保存即将插入的数据
pcaller = (link_node_st*)malloc(sizeof(link_node_st));
if (NULL == pcaller)
{
perror("pcaller malloc failed");
exit(1);
}
//该指针数组用来连接被调函数,暂时不用,置空
for (int i = 0; i < N; i++)
{
pcaller->next[i] = NULL;
}
//将新节点装上数据
pcaller->frame_size = frame_size; //创建主调节点时,就将栈空间和主调函数名填上
strcpy_s(pcaller->func_name,strlen(func_name)+1, func_name);
return pcaller; //将主调函数节点返回
}
/*******************************************************被调函数节点创建*****************************************************************/
//每找到一个被调函数,则调用该函数,创建一个被函数节点。
//2.创建新的被调函数节点,并连接到主调函数上
//被调函数传的是pcaller,是主调函数,
int Callee_create(link_node_st** pcaller, int frame_size, char* func_name)
{
//1.容错处理
if (NULL == (*pcaller))
{
printf("pcaller is empty!!\n");
return -1;//失败
}
link_node_st* pcallee = NULL;//用来保存新创建的被调函数的节点
//2.创建一个新的节点,保存即将插入的数据
pcallee = (link_node_st*)malloc(sizeof(link_node_st));
if (NULL == pcallee)
{
perror("pcallee malloc failed");
return -1;
}
//将新节点装上数据
pcallee->frame_size = frame_size; //创建被调节点时,就将栈空间和主调函数名填上
strcpy_s(pcallee->func_name, strlen(func_name) + 1, func_name);
//被调函数的指针数组用来连接其他被该函数调用的函数,暂时不用,置空
for (int i = 0; i < N; i++)
{
pcallee->next[i] = NULL;
}
//准备好被调函数节点,循环着去找主调函数的指针数组里面哪个还没有被使用,找到后,将被调函数连接上去,然后退出,遵循最小未用原则
for (int i = 0; i < N; i++)
{
if ((*pcaller)->next[i] == NULL)
{
(*pcaller)->next[i] = pcallee; //pcaller连接pcallee
break;
}
}
return 0;
}
/**************************************************1.su链表***********************************************************/
//该链表部分需要将object目录下所有的.su文件连接起来,而且在后面进行读取文件时也需要用到此链表
//链表在设计时需要设计一个数据域(文件名),一个指针域。
//1.定义一个节点
typedef struct node_t//node 节点
{
int frame_size; //有的链表存放函数名和栈空间大小,要用到,不用则保留
char data[N]; //数据域 文件名
struct node_t* next; //指针域
}link_node_t;
/********************************2.创建一个空的单向链表(有头单向链表),返回链表的头指针*******************************/
link_node_t* createEmptyLinkList()
{
//思想:创建一个节点,作为链表的头结点
link_node_t* p_head = (link_node_t*)malloc(sizeof(link_node_t));
if (NULL == p_head)
{
perror("createEmptyLinkList malloc failed");
return NULL;
}
p_head->next = NULL;
return p_head;
}
/**********************************3.向单向链表的指定位置插入数据 ->.su文件******************************/
//向单向链表的指定位置插入数据 ->文件链表
p保存链表的头指针 post 插入的位置 data插入的数据
int insertInto_file(link_node_t* p, int post, char *data)
{
int i;
link_node_t* pnew = NULL;//用来保存新创建的节点
//2.将头指针,指向插入位置的前一个节点
for (i = 0; i < post; i++)
p = p->next;
//3.创建一个新的节点,保存即将插入的数据
pnew = (link_node_t*)malloc(sizeof(link_node_t));
if (NULL == pnew)
{
perror("pnew malloc failed");
return -1;
}
int len = strlen(data);
strcpy_s(pnew->data,len+1,data); //将函数名
pnew->next = NULL;
//4.将新节点插入到链表中,先连后面(pnew->next),再连前面(p->next)
pnew->next = p->next;//连后面
p->next = pnew;//连前面
return 0;
}
/*****************************4.向单向链表的指定位置插入数据 ->.su文件里面的函数**************************/
p保存链表的头指针 post 插入的位置 data插入的数据
int insertInto_func(link_node_t* p, int post, int frame_size, char data[])
{
int i;
link_node_t* pnew = NULL;//用来保存新创建的节点
//2.将头指针,指向插入位置的前一个节点
for (i = 0; i < post; i++)
p = p->next;
//3.创建一个新的节点,保存即将插入的数据
pnew = (link_node_t*)malloc(sizeof(link_node_t));
if (NULL == pnew)
{
perror("pnew malloc failed");
return -1;
}
int len = strlen(data);
strcpy_s(pnew->data, len + 1, data); //将函数名
pnew->frame_size = frame_size; //装栈空间大小
pnew->next = NULL;
//4.将新节点插入到链表中,先连后面(pnew->next),再连前面(p->next)
pnew->next = p->next;//连后面
p->next = pnew;//连前面
return 0;
}
/***********************************************3.求单向链表长度的函数*********************************************************************/
int lengthLinkList(link_node_t* p)
{
int len = 0;
while (p->next != NULL)
{
p = p->next;
len++;
}
return len;
}
/*******************************************************获得链表头************************************************************************/
link_node_t* get_list_head(link_node_t* p)
{
return p;
}
/******************************************************打开文件**************************************************************************/
FILE* Fopen(const char* pathname, const char* mode)
{
FILE* fp = NULL;
fopen_s(&fp, pathname, mode);
if (NULL == fp)
{
printf("fopen failed\n");
exit(1);
}
return fp;
}
/********************************************字符串长度计算**********************************************************************************/
int cal_str(char* q)
{
int num = 0;
while ((*q) != '\0')
{
num++;
q++;
}
return num;
}
/********************************************5.遍历单向链表->文件链表**********************************************/
void show_file(link_node_t* p)
{
link_node_t* p1 = get_list_head(p);
while (p->next != NULL)
{
p = p->next;
printf("%s->\n", p->data);
}
printf("\n----------------------\n");
FILE* fp = Fopen( "..\\..\\output_information\\su.txt","wb");
#if 1
while (p1->next != NULL)
{
p1 = p1->next;
fprintf(fp, "%s->\n", p1->data);
}
#endif
}
/**********************************************3.遍历单向链表->函数链表*******************************************/
void show_func(link_node_t* p,char arr[])
{
link_node_t* p1 = get_list_head(p);
while (p->next != NULL)
{
p = p->next;
printf("(%s:%d)--->\n", p->data, p->frame_size);
}
printf("\n----------------------\n");
FILE* fp = Fopen(arr, "wb");
while (p1->next != NULL)
{
p1 = p1->next;
fprintf(fp, "(%s:%d)--->\n", p1->data,p1->frame_size);
}
}
/********************6.扫描指定目录,得到指定类型文件,即.su文件,将所有的.su文件用psu_head链表存起来*****************/
void Scandir(const char* dir,link_node_t** psu_head)
{
struct _finddata_t data; //定义一个结构体变量,该结构体包含文件的信息,比如data.name
long hnd = _findfirst(dir, &data); //获取要访问类型的第一个文件。hnd为句柄,后面 _findnext要使用到。
insertInto_file(*psu_head, 0, data.name);
if (hnd < 0)
{
printf("the first file operation is error\n");
exit(1);
}
while (_findnext(hnd, &data) >= 0)
{
insertInto_file(*psu_head, 0, data.name);
}
_findclose(hnd); // 关闭当前句柄
}
/******************************************************获取栈空间大小**********************************************************************/
//获取函数链表中栈空间的函数
//参数:链表头;函数名
int get_stackSize(link_node_t* p, char* func_name)
{
while ((p = p->next) != NULL)
{
if (0 == strcmp(p->data, func_name))
{
return (p->frame_size);
}
}
return 0;
}
/********************************************************排序***************************************************************************/
void swapI(int* a, int* b)
{
int temp = 0;
temp = *a;
*a = *b;
*b = temp;
}
void swapS(char* arr, char* brr)
{
char temp[N] = {0};
strcpy_s(temp,strlen(arr)+1,arr);
strcpy_s(arr,strlen(brr)+1,brr);
strcpy_s(brr, strlen(temp)+1,temp);
}
link_node_t* bubblesort(link_node_t* head)
{
head = head->next;
if (head == NULL) return NULL;
//定义一个尾,初值为空,以后为每次的最大值
link_node_t* end = NULL;
while (end != head)
{
link_node_t* p = head; //p在前,pnext在后
link_node_t* pnext = head->next;
while (pnext != end)
{
if (p->frame_size < pnext->frame_size)
{
#if 0
datatype temp[N];
strcpy_s(temp,strlen(p->data)+1,p->data);
strcpy_s(p->data,strlen(pnext->data)+1,pnext->data);
strcpy_s(pnext->data,strlen(temp)+1,temp);
#endif
swapS(p->data, pnext->data); //交换函数名
swapI(&p->frame_size, &pnext->frame_size); //交换栈空间大小
}
p = p->next;
pnext = pnext->next;
}
end = p;
}
return head;
}
/*********************************************************动态申请char*类型***************************************************************************/
char* Malloc_c(int size)
{
char* head = (char*)malloc(sizeof(char) * size);
if (NULL == head)
{
perror("malloc");
exit(1);
}
return head;
}
/*********************************************************动态申请char**类型***************************************************************************/
char** Malloc_cc(int size)
{
char** head = (char**)malloc(sizeof(char*) * size);
if (NULL == head)
{
perror("malloc char** error");
exit(1);
}
for (int i = 0; i < size; i++)
{
head[i] = (char*)malloc(sizeof(char)*100);
if(NULL == head[i])
{
perror("malloc char** error");
exit(1);
}
}
return head;
}
/*********************************************************动态申请link_node_st*类型***************************************************************************/
link_node_st* Malloc_l(int size)
{
link_node_st* head = (link_node_st*)malloc(sizeof(link_node_st) * size);
if (NULL == head)
{
perror("malloc");
exit(1);
}
return head;
}
/*********************************************************动态申请link_node_st**类型***************************************************************************/
link_node_st** Malloc_ll(int size)
{
link_node_st** head = (link_node_st**)malloc(sizeof(link_node_st*) * size);
if (NULL == head)
{
perror("malloc link_node_st** error");
exit(1);
}
for (int i = 0; i < size; i++)
{
head[i] = (link_node_st*)malloc(sizeof(link_node_st) * 100);
if (NULL == head[i])
{
perror("malloc link_node_st* error");
exit(1);
}
}
return head;
}
/******************************************************释放链表.su************************************************************************/
int destory_suFunc_list(link_node_t* p)
{
if (NULL == p)
{
puts("p is null.");
return 0;
}
if (NULL != p->next)
{
free(p->next);
p->next = NULL;
}
free(p);
p = NULL;
return 0;
}
/*******************************************************7.文件读写***************************************************************************/
void openFgets_file(link_node_t** pfunc_head, link_node_t** psu_head)
{
int n = 0;
int i = 0;
int k = 0;
int j = 0;
int m = 0;
int tmp = 0;
char *buf = Malloc_c(BUFSIZE);
char *str = Malloc_c(N); //存放函数名
char *arr = Malloc_c(N); //存放栈空间值
int integer = 0;
char pr1[N] ="..\\lcl.object\\";
char pr2[N] ="..\\lcl.object\\";
//循环打开链表中的文件
while (NULL != ((*psu_head) = (*psu_head)->next))
{
strcat_s(pr1, sizeof(pr1), (*psu_head)->data); // "..\\lcl.object\\AfwCo.o"
//打开文件
FILE* fp = Fopen(pr1, "r");
//按行获取文件内容
while (NULL != fgets(buf, BUFSIZE, fp))
{
//在这个while(1)里面找函数名
while (1)
{
if (buf[i] == ')') break;
if (buf[i++] == ' ') //这里是空格
{
while (buf[i] != '(')
{
str[k] = buf[i];
i++;
k++;
}
str[k] = '\0';
k = 0;
i = 0;
break;
}
}
//在这个while(1)里面找栈值
while (1)
{
if (buf[j++] == 9) //这里是table
{
while (buf[j] != 9) //这里是table
{
arr[m] = buf[j];
j++;
m++;
}
j = 0;
m = 0;
integer = atoi(arr);
insertInto_func(*pfunc_head, 0, integer, str);
memset(str, 0, sizeof(str));
break;
}
}
}
memset(buf,0,sizeof(buf));
memset(pr1,0,sizeof(pr1));
strcpy_s(pr1, strlen(pr2)+1, pr2);
fclose(fp);
}
}
#if 1
/******************************************************树的路径打印***********************************************************************/
/****栈部分**************************************/
typedef struct linkstack
{
int frame_size;
char data[N]; //数据域
struct linkstack* next; //指针域
}linkstack_t;
linkstack_t* top; //top定义成全局变量,指向栈结构体的指针,此时是野指针(当作无头链表的头指针)
//1.创建一个空的栈,采用二级指针是为了改变栈针的位置
void createEmptyLinkStack(linkstack_t** ptop)
{
*ptop = NULL; //此时赋值为空
}
//2.入栈操作
int push(linkstack_t** ptop, char *data, int frame_size) //
{
//1.入栈先创建一个节点,装入数据
linkstack_t* pnew = (linkstack_t*)malloc(sizeof(linkstack_t));
if (NULL == pnew)
{
perror("pnew malloc failed!!");
return -1;
}
//2.数据拷贝
strcpy_s(pnew->data,strlen(data)+1, data); //数据是字符串
pnew->frame_size = frame_size; //栈空间
//3.让新的节点连接上栈的头,指向顺序是向下的,
pnew->next = *ptop;
//4.栈针永远指向栈的头
*ptop = pnew; //新节点就是链栈的头,他是一个无头链表
return 0;
}
//3.判断栈是否为空
int isEmptyLinkStack(linkstack_t* top)
{
return (top == NULL);
}
//4.出栈(需要用临时变量保存栈针,和数据)
int pop(linkstack_t** ptop)
{
linkstack_t* pdel = NULL; //指向被删除的节点
if (isEmptyLinkStack(*ptop)) //如果栈已经为空,则不应该再继续删除
{
printf("stack is empty!\n");
return -1;
}
pdel = *ptop; //保存栈针
(*ptop) = (*ptop)->next;
free(pdel);
pdel = NULL;
// return temp;
}
/*****************************************************转置链表*******************************************************************/
// 将头节点与当前链表断开,断开前保存下头节点的下一个节点,保证后面链表能找得到,定义一个q保存头节点的下一个节点,断开后前面相当于一个空的链表,后面是一个无头的单向链表
// 遍历无头链表的所有节点,将每一个节点当做新节点插入空链表头节点的下一个节点(每次插入的头节点的下一个节点位置)
// 等于就是头部插入,先插入的节点,会在最后,这样就是为了将正确打印栈的顺序
linkstack_t* reverseLinkList(linkstack_t* top)
{
//top链表是无头链表
linkstack_t* ph = (linkstack_t*)malloc(sizeof(linkstack_t));
if (NULL == ph)
{
perror("ph malloc failed!!");
exit(1);
}
ph->next = NULL;
while (top != NULL)
{
linkstack_t* pnew = (linkstack_t*)malloc(sizeof(linkstack_t));
if (NULL == pnew)
{
perror("pnew malloc failed!!");
exit(1);
}
strcpy_s(pnew->data,strlen(top->data)+1,top->data);
pnew->frame_size = top->frame_size;
top = top->next;
pnew->next = ph->next;
ph->next = pnew;
}
return ph;
}
#endif
#if 1
//比较链表中是否有相同的函数名,有则判断其为循环
int iscirclelink_func(linkstack_t* p, FILE* fp)
{
linkstack_t* head1 = p->next;
linkstack_t* head2 = p->next;
linkstack_t* q = NULL;
while (p->next != NULL)
{
p = p->next; //此时p指向链表中第1个有效节点
q = p->next; //此时q指向链表中第2个有效节点
// printf("p->data=%s\n", p->data);
while (q != NULL)
{
if (0 == strcmp(q->data, p->data)) //如果有相同的函数名
{
fprintf(fp, "/********this is a circle link!!!***********/\n");
fprintf(fp, "start->\n");
while (head1 != p)
{
fprintf(fp, "(%s:%d)->\n", head1->data, head1->frame_size);
head1 = head1->next;
}
fprintf(fp, "(%s:%d)->\n", p->data, p->frame_size);
fprintf(fp, "->end \n");
fprintf(fp, "\n");
fprintf(fp, "the function of <%s> is a entrance of this tree named <%s>!!!\n", p->data, head2->data);
fprintf(fp, "entrance->");
while (0 != strcmp(p->data, head1->next->data))
{
fprintf(fp, "(%s:%d)->", head1->data, head1->frame_size);
head1 = head1->next;
}
fprintf(fp, "(%s:%d)->...\n", p->data, p->frame_size);
//exit(1); //找到就退出
ExitThread(0);
ReleaseMutex(g_Mutex);
_endthreadex(0);
}
//printf("q->data=%s\n", q->data);
q = q->next;
}
}
return 0;
}
#endif
/********数据打印部分*********************/
void display(linkstack_t* top, FILE* fp) //这里使用一级指针,因为不用改变栈针的实际位置
{
static int i = 0;
int len = 0;
int linksize = 0;
linkstack_t* ph = reverseLinkList(top);
//int key = iscirclelink_ptr(ph); //判断链表中是否存在回路
int key = iscirclelink_func(ph, fp); //判断链表中是否存在回路
if (0 == key) //该链表中不存在环路
{
fprintf(fp, "start<%d>->\n",i++);
while (ph->next != NULL)
{
ph = ph->next;
len++;
linksize = linksize + ph->frame_size;
fprintf(fp, "(%s:%d)->\n", ph->data, ph->frame_size);
}
}
fprintf(fp, "->end \n");
fprintf(fp, "len = %d\n", len);
fprintf(fp, "linksize = %d\n", linksize);
fprintf(fp, "\n");
}
/********路径遍历部分*********************/
void path(link_node_st* r, FILE* fp)
{
int j = 0;
if (NULL != r) //如果该节点不为空
{
push(&top, r->func_name, r->frame_size); //压栈他的数据
for (int i = 0; NULL != r->next[i]; i++) //寻找r不为空的子节点
{
j++;
}
if (0 == j) //说明没有子节点,则打印出当前的路径,他保存在栈中
{
display(top, fp);
}
else //有子节点,则继续追踪他的子节点
{
for (int i = 0; NULL != r->next[i]; i++)
{
path(r->next[i], fp); //pop完了,退到这里了;
}
}
pop(&top);
}
}
FILE* fptree = NULL;
unsigned int _stdcall FunProc(void *p)
{
WaitForSingleObject(g_Mutex, INFINITE);//等待互斥量
path((link_node_st*)p, fptree);
ReleaseMutex(g_Mutex);
_endthreadex(0);
return;
}
int main()
{
g_Mutex = CreateMutex(NULL, FALSE, NULL);
//1.先创建一个空的链表,(无效|p_head),返回一个头指针,该头指针作为.su文件链表的头指针
link_node_t* psu_head = createEmptyLinkList();
//2.在指定目录下获取指定类型的文件
Scandir("..\\lcl.object\\*.su",&psu_head);
show_file(psu_head);
// printf("psu_head's length = %d\n",lengthLinkList(psu_head));
//3.创建一个空链表,返回一个头指针,该头指针作为.o函数名链表的头指针。
link_node_t* pfunc_head = createEmptyLinkList();
//4.循环打开读取文件内容,(open一个,fgets一个)
openFgets_file(&pfunc_head, &psu_head);
int func_num = lengthLinkList(pfunc_head);
// printf("pfunc_head's length = %d\n",lengthLinkList(pfunc_head));
//打印函数链表及其栈空间
show_func(pfunc_head,"..\\..\\output_information\\func.txt");
link_node_t* ph1 = get_list_head(pfunc_head);
/******栈空间大小排序************/
link_node_t* psort = bubblesort(ph1);
show_func(psort, "..\\..\\output_information\\stackSize_sort.txt");
#if 1
/*****************************************.txt文件内容***********************************************/
puts("Data in transit,wait for a moment,please.....");
//用来存放所有的主调函数
link_node_st** h_caller = Malloc_ll(M);
//存放被调函数名
char** callee = Malloc_cc(M*3);
system("arm-none-eabi-objdump.exe -dr ..\\lcl.object\\*.o >..\\1.txt"); //将所有的.o文件反汇编到1.txt中去
FILE* fpasm = Fopen("..\\1.txt", "r");
int i = 0;
int j = 0;
int k = -1;
int y = 0;
int n = 0;
int mainCall_num = 0;
int callee_num = 0;
//char buf[BUFSIZE];
char* buf = Malloc_c(BUFSIZE);
char *brr = Malloc_c(N);
char *crr = Malloc_c(N);
int flager = 0;
int flager_1 = 0;
int flager_2 = 0;
int flagee = 0;
int flagee_1 = 0;
int flagee_2 = 0;
while (fgets(buf, BUFSIZE, fpasm) != NULL)
{
//1.主调函数标志,">:"表示找到主调函数
if (strstr(buf, ">:") != NULL)
{
//2.在while(1)中提取<>中的内容,保存到brr中
while (1)
{
if (buf[i++] == '<')
{
while (buf[i] != '>')
{
brr[y++] = buf[i++];
}
brr[y] = '\0';
y = 0;
i = 0;
break;
}
}
link_node_t* ph = get_list_head(pfunc_head);
while ((ph = ph->next) != NULL) //链表头不能动,
{
//在函数链表中去查找,是否有函数名存在于buf中,存在则进一步区分,是前后缀,还是别的
if (NULL != strstr(brr, ph->data))
{
flager = 1;
}
}
//如果存在
if (1 == flager)
{
//清空标志位
flager = 0;
//获取栈空间大小 参数:函数名链表头节点,要查找的函数,没有找到返回-1;
int arr = get_stackSize(pfunc_head, brr);
//创建主调函数节点, 参数:主调函数的栈空间和函数名;将主调函数地址放入h_caller指针数组中保存
k++;
h_caller[k] = Caller_create(arr, brr);
//打印主调函数名及其栈空间大小,确定其正确
// printf("%d %s %d \n",k,h_caller[k]->func_name,h_caller[k]->frame_size);
//主调函数个数
mainCall_num++;
i = 0;
j = 0;
}
}
#if 1
//1.判断该行是否是被调函数行,
if (NULL != strstr(buf, "R_ARM_THM_CALL"))
{
// printf("buf=%s\n",buf);
//2.提取被调函数
while (1)
{
if (buf[j++] == 'L')
{
if (buf[j++] == 'L')
{
if (buf[j++] == 9)
{
while (buf[j] != '\n')
{
crr[n++] = buf[j++];
}
crr[n] = '\0';
// printf("crr=%s\n", crr);
n = 0;
j = 0;
break;
}
}
}
}
link_node_t* ph = get_list_head(pfunc_head); //链表头不能动,
//在函数链表中去查找被调函数是否存在,去掉系统调用、库函数等
while ((ph = ph->next) != NULL)
{
if (!strcmp(crr, ph->data)) // R_ARM_THM_CALL __Trace __Trace
{
// printf("ph->data=%s\n",ph->data);
// printf("crr=%s\n", crr);
flagee = 1;
}
}
if (flagee == 1)
{
flagee = 0;
//将所有的被调函数装入callee中去
strcpy_s(callee[callee_num],strlen(crr)+1,crr);
// printf("callee[callee_num]1=%s\n",callee[callee_num]);
callee_num++;
//找到之后获取栈空间大小
int arr = get_stackSize(pfunc_head, crr);
// printf("arr=%d\n",arr);
//参数:主调函数节点,被调函数栈空间、函数名
//将被调函数插入对应的主调函数中去
Callee_create(&h_caller[k], arr, crr);
}
}
#endif
memset(brr, 0, sizeof(brr));
memset(buf, 0, sizeof(buf));
memset(crr, 0, sizeof(crr));
}
#endif
#if 0
/**********************************************************主调函数和被调函数关系测试**************************************************/
for (int i = 0; i < mainCall_num; i++)
{
printf("(%d) %s %d->\n", i, h_caller[i]->func_name, h_caller[i]->frame_size);
for (int j = 0; h_caller[i]->next[j] != NULL; j++)
{
printf("(%d) %s %d\n", j, h_caller[i]->next[j]->func_name, h_caller[j]->frame_size);
}
}
printf("okay\n");
printf("mainCall_num=%d\n", mainCall_num);
/**************************************************************链表整合**************************************************************/
#endif
#if 1
for (int i = 0; i < mainCall_num; i++) //这一层循环用来进行主调函数的循环
{
for (int j = 0; h_caller[i]->next[j] != NULL; j++) //这一层循环用来进行i层的被调函数的循环
{
for (int n = 0; n < mainCall_num; n++) //这一层用来为被调函数匹配主调函数
{
if (0 == strcmp(h_caller[i]->next[j]->func_name, h_caller[n]->func_name))
{
h_caller[i]->next[j] = NULL;
h_caller[i]->next[j] = h_caller[n];
}
}
}
}
printf("combine ok!!!\n");
#endif
/***************************************************************找寻入口**************************************************************/
#if 1
int w = 0;
int q = 0;
char **start_func_next = Malloc_cc(6000); //存放调用了别人,但没有被别人调用的函数
link_node_st** startPosition = Malloc_ll(6000); //存放入口地址
link_node_st** startPosition_next = Malloc_ll(6000);
for (int i = 0; i < mainCall_num; i++) //主调函数 //这一步出项的问题是指针数组设置太小了。
{
for (int j = 0; j< callee_num; j++) //被调函数
{
if (0 == strcmp(h_caller[i]->func_name, callee[j]))
{
w++;
}
}
if (0 == w)
{
startPosition[q] = h_caller[i];
// printf("%s\n", startPosition[q]->func_name);
q++;
}
w = 0;
}
#endif
#if 1
int c = 0;
for (int i = 0; i < q; i++)
{
if (NULL == startPosition[i])
{
printf("%s\n", startPosition[i]->func_name);
continue;
}
//调用了别人
if (NULL != startPosition[i]->next[0])
{
startPosition_next[c] = startPosition[i];
c++;
// printf("%s\n",startPosition[i]->func_name);
// show_multree(startPosition[i]);
}
}
#endif
/******************************************栈部分*************************************************************************************/
#if 0
FILE* fp = Fopen("..\\..\\output_information\\onetree.txt", "w");
//1.定义一个栈针
// linkstack_t* top; //指向栈结构体的指针,此时是野指针(当作无头链表的头指针)
createEmptyLinkStack(&top);
// printf("startPosition_next[10]=%s\n", startPosition_next[10]->func_name);
// for(int i = 0; i<c; i++)
{
path(startPosition_next[7], fp);
// fprintf(fp,"*************现在的树根是(%s)*************\n",startPosition_next[i]);
}
#endif
#if 1
// FILE* fp = Fopen("..\\..\\output_information\\onetree.txt", "w");
createEmptyLinkStack(&top); //创建一个空栈
printf("c = %d\n",c);
fptree = Fopen("..\\..\\output_information\\onetree.txt", "a+");
HANDLE hThread[1000] = { 0 };
int l = 0;
for (int i = 0; i < c; i++)
{
hThread[l++] = (HANDLE)_beginthreadex(NULL, 0, FunProc,(void*)startPosition_next[i], 0, NULL);
// _beginthread(FunProc, 0, (void*)startPosition_next[i]);
}
for (int i = 0; i < c; i++)
{
WaitForSingleObject(hThread[i], INFINITY);
CloseHandle(hThread[i]);
}
printf("l == %d\n",l);
#endif
printf("The data transfer is ready\n");
free(buf);
buf = NULL;
free(brr);
brr = NULL;
free(crr);
crr = NULL;
free(h_caller);
h_caller = NULL;
free(callee);
callee = NULL;
// destory_suFunc_list(psu_head);
destory_suFunc_list(pfunc_head);
fclose(fptree);
return 0;
}
函数的栈信息打印(windows下)
最新推荐文章于 2022-11-08 21:19:30 发布