Today is July 22, October 13. I don't know why I live so fast. It is probably because of my vacation. After the National Day of the 11 S, I had a three-day class and a holiday... I feel that the life of graduate students is getting worse and worse... the teacher arranged a task for me a long time ago, asking me to finish the video display on the arm board and the early JPEG display. I think this problem is not a big problem. I know too little about such things, and it is very difficult to get started with such things.
The video itself is composed of a frame of data. A frame can actually be regarded as an image. To put it bluntly, a lot of images are displayed one by one in one second, due to the temporary visual feature of human eyes, dynamic effects can be formed at a frequency. If the data is saved in this way, the data volume of a large number of videos is also large, so we need to compress the video. The task assigned by the teacher turned out to be video playback. Is it a player or video compression? My God, I suddenly felt a lot of pressure on my team...
The importance of work, just like many programmers, is that they believe in their own capabilities and are relatively independent. Many things do not like to be done by others, or, if you don't believe what others do, you can do everything yourself. Of course, the same is true for me. Many things I like to do by myself, what you do can make you feel right. However, when there are a lot of things in the project, you will feel that you are powerless, and you will feel that you really don't want to do it when you look at there are so many things to write. This makes it easy to give up! Many Daniel wrote a lot of things and thought they really admired them, or they found something they really liked. After playing the video for a while, I talked to him about his thoughts when the teacher came to view my progress. He gave me the opinion that he didn't need me to make any player or decoder, as long as I can use the ready-made items, I am very lazy to get a library online. This is a very famous library (FFMPEG) and I spent a lot of time porting it, it seems that this thing is actually very difficult. Many things are wrong, and many things are different from what others say. I feel that this thing must be done in a calm situation, with the support of my great EQ, I finally completed the porting. The program uses his own example, the only thing I do is to link up my previous display functions on framebuffer... it took me a lot of time. The teacher looked at the results this afternoon and seemed quite satisfied. I want to transplant the facial recognition of an undergraduate student, but I am not in a hurry, because the undergraduate student is not written yet... you can spend a lot of time in your spare time. This afternoon, you have made soy sauce for one afternoon.
After talking about so many recent things, it seems that it has nothing to do with the question. Haha, I saw this question in a programming challenge question of <C expert programming>. In fact, I didn't even have any idea when I first saw this question, and I felt quite tender. I am not clear about many things about C. I know that they also know that they do not necessarily know the situation ..... so I am very sad...
Let's talk about a written test question recently published by Netease. One of my classmates told me that NetEase is my favorite company. According to my understanding, some friends have introduced it, compared with other companies of the same level, Netease has a good corporate culture. Of course, I have not been there yet, and I am not clear about it... in addition, it only targets Zhejiang University and makes me look forward to this company. Haha .... I ran the question again. It seems like this. Let you write a program, how do you output his line number, function name, and file name? In fact, people you know about this problem are actually very simple, you don't know how to beat a person to death. This is just a few macros, __line __,__ function __,__ file. So I think there must be a kind of curiosity in the way of programming, so that you can learn more and learn more widely... as someone said,"Details determine everything".
I met the answer to the above question last month, but it seems that this time has not aroused my interest, so he was ignored by me... sorry... haha... this will not happen in the future! I was surprised to hear that NetEase had taken this test, and I was very curious to know what macros the compiler defined. I Googled and found two functions, it also gave me the impulse to complete the questions in the book.
The two functions are:
Void _ cyg_profile_func_enter (void * funaddr, void * callsite) _ attribute _ (no_instrument_function ));
Void _ cyg_profile_func_exit (void * funaddr, void * callsite) _ attribute _ (no_instrument_function ));
These two functions are used automatically when you call a function._ Cyg_profile_func_enter,When the program leaves the function, it calls_ Cyg_profile_func_exitThis function. In fact, when you encounter a question in a book, The only difficulty is how to identify the function call. If you write input and output to every function you have written, this is a very huge change, and you have to change your source code. So the difficulty is how to identify the function call process, are these two functions exactly the same ??? So when I saw these two functions, I was very excited !! Let me introduce these two functions first.
This phenomenon belongs to the GCC function instrumentation mechanism, which appears in gcc2.x and is proposed by Cygnus. To use these functions, you must add the-finstrument-functions option during compilation. We all know that C language calls are implemented through callback, so we call the process record in the function call process as call frame, and the above two functions are called when the function is started and exited. I am not very clear about this _ attribute _. I will study it tomorrow.No_instrument_functionTo prevent the function from calling the _ cyg_profile_func_enter function again, and then enters the infinite recursion state.
The problem is solved in half, so now we can automatically identify the call of the function, but we need to output the function name, as if there is still a problem. I thought we could use the macros described above, but now we mainly_ Cyg_profile_func_enterSo these macros are invalid. However, you still don't know the specific meaning of the function parameters. funaddr is the start address of the function, while callsite is the return address, I don't know if there is anything that can turn these things into a specific row number. Haha... I think I am lucky. I saw a GCC tool a few days ago. It is the addr2line tool which can change the address to the corresponding row number, however, some special addresses cannot be converted. However, this is a specific command. I don't know how to use the program. It is still a problem. I would have output first, and then shell the output file.
Script Processing. However, it seems lucky to have met the popen function on the Internet.
File * popen (const char * command, const char * type );
The benefit of this function is that it creates a pipe and calls shell. There are two types of Type: "R" and "W ", the difference between the two is that R is a read pipeline and W is a write pipeline. However, only one of the two can be selected. The key is that shell is called, and let the shell execute your command, isn't that very suitable for the function I want... Hahaha
I forgot to talk about one thing, that is, a dladdr function, which is actually not very clear to me, so let me know more about it later, however, this function can be used to know a struct of dl_info through a function address,
Typedef struct {
const char *dli_fname; /* Pathname of shared object that contains address */ void *dli_fbase; /* Address at which shared object is loaded */ const char *dli_sname; /* Name of nearest symbol with address lower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info;
For the dladdr function, I have translated the specific meaning of this function parameter in my next article.
As I said yesterday, the following function seems to be not supported by dynamic and static libraries, the finstrument-funtions statement can be used to compile the library files, however, the problem is that we cannot add this option to the library of our system during compilation, so we cannot access it. In fact, this is not a dladdr error. The error should be because the above red function is not called, so we should continue to study and see if it can continue to improve. However, the dladdr can display messages in the dynamic library, a very powerful function.
The following is the code. It seems that you can manually call the tracing function.
#define _GNU_SOURCE#include <stdio.h>#include <dlfcn.h>#include <stdlib.h>#include <unistd.h>#include <string.h>//this func is called when your program has func is called//thiz is enter func address//callsite is func back address void __cyg_profile_func_enter(void *thiz, void *callsite)__attribute__((no_instrument_function));void __cyg_profile_func_exit(void *thiz, void *callsite)__attribute__((no_instrument_function));void display(void *enter, void *callsite, int flag)__attribute__((no_instrument_function));void display(void *enter, void *callsite, int flag){ Dl_info info; char cmd[1024] = "addr2line -e "; char *ptr = cmd + strlen(cmd); int strsize = readlink("/proc/self/exe",ptr,sizeof(cmd) - (ptr - cmd) - 1); if(strsize == -1) {fprintf(stderr,"readlink is failure!\n");exit(-1); } FILE *fp = popen(cmd,"w"); if(!fp) {perror("popen\n");exit(-1); } if(dladdr(enter,&info) == 0) {fprintf(stderr,"addr to funcname is failure\n");exit(-1); } //flag=1,enter or flag=0,exit if(flag) {char address[256];printf("\n-------------------------------------------\n");printf("your program has entered a function!\n");printf("this run filename is %s\n",info.dli_fname);printf("this function name is %s\n",info.dli_sname);printf("this function's address is %p\n",enter);printf("this function back row is \n");sprintf(address,"%p\0",callsite);fwrite(address,1,strlen(address) + 1,fp); } else {printf("\n-------------------------------------------\n");printf("your program will leave this function %s\n",info.dli_sname);printf("-------------------------------------------\n"); } pclose(fp);}void __cyg_profile_func_enter(void *thiz, void *callsite){ display(thiz,callsite,1);} void __cyg_profile_func_exit(void *thiz, void *callsite){ display(thiz,callsite,0);}
You must add the-rdynamic-finstrument-functions command to the compiled command.