[FEATURE] add network probes
[platform/core/system/swap-probe.git] / include / daprobe.h
1 /*
2  *  DA probe
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: 
7  *
8  * Jaewon Lim <jaewon81.lim@samsung.com>
9  * Woojin Jung <woojin2.jung@samsung.com>
10  * Juyoung Kim <j0.kim@samsung.com>
11  * Anastasia Lyupa <a.lyupa@samsung.com>
12  * 
13  * This library is free software; you can redistribute it and/or modify it under
14  * the terms of the GNU Lesser General Public License as published by the
15  * Free Software Foundation; either version 2.1 of the License, or (at your option)
16  * any later version.
17  * 
18  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
19  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
21  * License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with this library; if not, write to the Free Software Foundation, Inc., 51
25  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26  *
27  * Contributors:
28  * - S-Core Co., Ltd
29  * - Samsung RnD Institute Russia
30  * 
31  */
32
33 #ifndef __DAPROBE_H__
34 #define __DAPROBE_H__
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <stdbool.h>
39 #include <dlfcn.h>
40 #include <stdint.h>
41 #include "probeinfo.h"
42
43 #ifdef __cplusplus
44 extern "C"{
45 #endif
46
47 #ifndef likely
48 #define likely(x)       __builtin_expect((x),1)
49 #define unlikely(x)     __builtin_expect((x),0)
50 #endif
51
52 #define NUM_OF_MONITOR          3
53 #define DA_LOG_MAX                      4096
54 #define PERROR_MSG_MAX          128
55
56 #define DEFAULT_TOKEN   "`,"
57
58 #define CALLER_ADDRESS  \
59         ((void*) __builtin_extract_return_addr(__builtin_return_address(0)))
60
61 #define BACKTRACE_SYMBOLS cached_backtrace_symbols
62
63 typedef enum
64 {
65         MT_MEMORY,
66         MT_FILE,
67         MT_SOCKET,
68 } MonitorType;
69
70 enum BlockLocation
71 {
72         BL_PRE,
73         BL_POST,
74 };
75
76 typedef struct
77 {
78         int type;
79         int length;
80         char data[DA_LOG_MAX];
81 } log_t;
82
83 typedef struct
84 {
85         int                             eventIndex;
86         int                             pID;
87         int                             tID;
88         unsigned long   currentTime;
89         unsigned int    callDepth;
90 } probeInfo_t;
91
92 extern __thread int     gProbeBlockCount;
93 extern __thread int     gProbeDepth;
94
95 #define probeBlockStart()       (gProbeBlockCount++)
96 #define probeBlockEnd()         (gProbeBlockCount--)
97 #define probingStart()          (gProbeDepth++)
98 #define probingEnd()            (gProbeDepth--)
99
100 /***************************************************************************
101  * helper apis
102  ***************************************************************************/
103
104 int preBlockBegin(void* caller, bool bFiltering, enum DaOptions);
105 void preBlockEnd();
106
107 int postBlockBegin(int preresult);
108 void postBlockEnd();
109
110 unsigned int getCurrentEventIndex();
111 unsigned long getCurrentTime();
112 uint64_t get_current_nsec(void);
113 bool setProbePoint(probeInfo_t * iProbe);
114 int update_heap_memory_size(bool isAdd, size_t size);
115
116 bool printLogStr(const char* str, int msgType);
117 bool printLog(log_t* log, int msgType);
118 int __appendTypeLog(log_t* log, int nInput, char* token, ...);
119 int getBacktraceString(log_t* log, int bufsize);
120
121 //char* captureScreenShotX(int* width, int* height);
122 //void releaseScreenShotX();
123
124 //int printSamplingLog(void);
125
126 //bool captureScreen(unsigned int logNum);
127 //void captureProbe();
128 //int registeScreenChange(int renderID);
129 //void detectTouchEvent(int touchID);
130 //int getTouchState();
131 //int isPossibleCapture();
132
133
134 /***************************************************************************
135  * helper macros
136  ***************************************************************************/
137
138 // ========================= print log =====================================
139 #define PRINTMSG(msg)   printLogStr(msg, MSG_MSG)
140
141 // =========================== declare variables ===========================
142 // local variable is faster than heap allocated variable
143 // array variable initialization with declare is expensive than memset
144
145 // declare variable for standard api (not tizen related api)
146 #define DECLARE_VARIABLE_STANDARD               \
147                 probeInfo_t     probeInfo;                      \
148                 int blockresult = 0;                            \
149                 bool bfiltering = true;                 \
150                 int olderrno, newerrno;                 \
151                 int __attribute__((unused)) ret
152
153 // declare variable for standard api (not tizen related api) without ret
154 #define DECLARE_VARIABLE_STANDARD_NORET         \
155                 probeInfo_t     probeInfo;                      \
156                 int blockresult;                                \
157                 bool bfiltering = true;                 \
158                 int olderrno, newerrno;                 \
159
160 // ========================== get function pointer =========================
161
162 #define GET_REAL_FUNCP(FUNCNAME, SONAME, FUNCTIONPOINTER)                       \
163         GET_REAL_FUNCP_STR(#FUNCNAME, SONAME, FUNCTIONPOINTER)
164
165 #define GET_REAL_FUNCP_STR(FUNCNAME, SONAME, FUNCTIONPOINTER)                   \
166                 do {                                                                                                            \
167                         if (!FUNCTIONPOINTER) {                                                                 \
168                                 probeBlockStart();                                                                      \
169                                 if (lib_handle[SONAME] == NULL) {                                       \
170                                         lib_handle[SONAME] = dlopen(lib_string[SONAME], RTLD_LAZY);                     \
171                                         if (lib_handle[SONAME] == NULL) {                               \
172                                                 fprintf(stderr, "dlopen failed : %s\n", lib_string[SONAME]);    \
173                                                 exit(0);                                                                        \
174                                         } \
175                                 }                                                                                                       \
176                                 FUNCTIONPOINTER = dlsym(lib_handle[SONAME], FUNCNAME);          \
177                                 if (FUNCTIONPOINTER == NULL || dlerror() != NULL) {             \
178                                         fprintf(stderr, "dlsym failed : <" FUNCNAME ">\n");                     \
179                                         exit(0);                                                                                \
180                                 }                                                                                                       \
181                                 probeBlockEnd();                                                                        \
182                         }                                                                                                               \
183                 } while(0)
184
185 #define GET_REAL_FUNC(FUNCNAME, SONAME)         \
186         GET_REAL_FUNCP(FUNCNAME, SONAME, FUNCNAME##p)
187
188 #define GET_REAL_FUNCP_RTLD_NEXT(FUNCNAME, FUNCTIONPOINTER)                     \
189                 do {                                                                                                            \
190                         if(!FUNCTIONPOINTER) {                                                                  \
191                                 probeBlockStart();                                                                      \
192                                 FUNCTIONPOINTER = dlsym(RTLD_NEXT, #FUNCNAME);          \
193                                 if(FUNCTIONPOINTER == NULL || dlerror() != NULL) {      \
194                                         fprintf(stderr, "dlsym failed <%s>\n", #FUNCNAME);                                                      \
195                                         exit(0);                                                                                \
196                                 }                                                                                                       \
197                                 probeBlockEnd();                                                                        \
198                         }                                                                                                               \
199                 } while(0)
200
201 #define GET_REAL_FUNC_RTLD_NEXT(FUNCNAME)       \
202                 GET_REAL_FUNCP_RTLD_NEXT(FUNCNAME, FUNCNAME##p)
203
204 #define GET_REAL_FUNCP_RTLD_NEXT_CPP(FUNCNAME, FUNCTIONPOINTER)         \
205                 do {                                                                                                            \
206                         if(!FUNCTIONPOINTER) {                                                                  \
207                                 probeBlockStart();                                                                      \
208                                 void* funcp = dlsym(RTLD_NEXT, #FUNCNAME);                      \
209                                 if(funcp == NULL || dlerror() != NULL) {                        \
210                                         fprintf(stderr, "dlsym failed <%s>\n", #FUNCNAME);                                                      \
211                                         exit(0);                                                                                \
212                                 }                                                                                                       \
213                                 memcpy(&FUNCTIONPOINTER, &funcp, sizeof(void*));        \
214                                 probeBlockEnd();                                                                        \
215                         }                                                                                                               \
216                 } while(0)
217
218 #define GET_REAL_FUNC_RTLD_NEXT_CPP(FUNCNAME)   \
219                 GET_REAL_FUNCP_RTLD_NEXT_CPP(FUNCNAME, FUNCNAME##p)
220
221 // ======================= pre block macro ================================
222
223 #define PRE_PROBEBLOCK_BEGIN()                                                                                                  \
224         if((blockresult = preBlockBegin(CALLER_ADDRESS, bfiltering, _sopt)) != 0) {     \
225                 setProbePoint(&probeInfo)
226
227 #define PRE_PROBEBLOCK_END()    \
228                 preBlockEnd();                  \
229         }                                                       \
230         olderrno = errno;                       \
231         errno = 0
232
233 #define PRE_PROBEBLOCK() \
234                 PRE_PROBEBLOCK_BEGIN(); \
235                 PRE_PROBEBLOCK_END()
236
237 // ===================== unconditional probe block ========================
238
239 #define PRE_UNCONDITIONAL_BLOCK_BEGIN() \
240         do {                                                            \
241                 probeBlockStart();                              \
242                 setProbePoint(&probeInfo)
243
244 #define PRE_UNCONDITIONAL_BLOCK_END()   \
245                 probeBlockEnd();                                \
246         } while(0)
247
248 // =========================== post block macro ===========================
249
250 #define POST_PROBEBLOCK_BEGIN(LCTYPE, RETTYPE, RETVALUE, INPUTFORMAT, ...)      \
251         newerrno = errno;                                                                                                               \
252         if(postBlockBegin(blockresult)) {                                                                               \
253                 PREPARE_LOCAL_BUF(); \
254                 PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
255                 PACK_COMMON_END(RETVALUE, errno, blockresult);
256
257 #define POST_PROBEBLOCK_END()                                           \
258                 FLUSH_LOCAL_BUF();                                              \
259                 postBlockEnd();                                                         \
260         }                                                                                               \
261         errno = (newerrno != 0) ? newerrno : olderrno
262
263 // ========================= simplify macro ================================
264
265 #define BEFORE_ORIGINAL(FUNCNAME, LIBNAME)      \
266         DECLARE_VARIABLE_STANDARD;                              \
267         GET_REAL_FUNC(FUNCNAME, LIBNAME);               \
268         PRE_PROBEBLOCK()
269
270 #define BEFORE_ORIGINAL_NOFILTER(FUNCNAME, LIBNAME)     \
271         DECLARE_VARIABLE_STANDARD;                                              \
272         GET_REAL_FUNC(FUNCNAME, LIBNAME);                               \
273         bfiltering = false;                                                             \
274         PRE_PROBEBLOCK()
275
276 #ifdef __cplusplus
277 }
278 #endif
279
280 #endif