函数的栈信息打印(windows下)

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

<( ̄︶ ̄)Okay.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值