tizen 2.3 release
[framework/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 #define __unused __attribute__((unused))
52
53 #define NUM_OF_MONITOR          3
54 #define DA_LOG_MAX                      4096
55 #define PERROR_MSG_MAX          128
56
57 #define DEFAULT_TOKEN   "`,"
58
59 #define CALLER_ADDRESS  \
60         ((void*) __builtin_extract_return_addr(__builtin_return_address(0)))
61
62 #define BACKTRACE_SYMBOLS cached_backtrace_symbols
63
64 typedef enum
65 {
66         MT_MEMORY,
67         MT_FILE,
68         MT_SOCKET,
69 } MonitorType;
70
71 enum BlockLocation
72 {
73         BL_PRE,
74         BL_POST,
75 };
76
77 typedef struct
78 {
79         int type;
80         int length;
81         char data[DA_LOG_MAX];
82 } log_t;
83
84 typedef struct
85 {
86         int                             eventIndex;
87         int                             pID;
88         int                             tID;
89         unsigned long   currentTime;
90         unsigned int    callDepth;
91 } probeInfo_t;
92
93 extern __thread int     gProbeBlockCount;
94 extern __thread int     gProbeDepth;
95
96 #define probeBlockStart()       (gProbeBlockCount++)
97 #define probeBlockEnd()         (gProbeBlockCount--)
98 #define probingStart()          (gProbeDepth++)
99 #define probingEnd()            (gProbeDepth--)
100
101 /***************************************************************************
102  * helper apis
103  ***************************************************************************/
104
105 int preBlockBegin(const void *caller, bool bFiltering, enum DaOptions);
106 void preBlockEnd();
107
108 int postBlockBegin(int preresult);
109 void postBlockEnd();
110
111 unsigned int getCurrentEventIndex();
112 unsigned long getCurrentTime();
113 uint64_t get_current_nsec(void);
114 bool setProbePoint(probeInfo_t * iProbe);
115 int update_heap_memory_size(bool isAdd, size_t size);
116
117 bool print_log_fmt(int msgType, const char *func_name, int line, ...);
118 bool print_log_str(int msgType, char *st);
119 bool printLog(log_t* log, int msgType);
120
121 int __appendTypeLog(log_t* log, int nInput, char* token, ...);
122 int getBacktraceString(log_t* log, int bufsize);
123
124 void *rtdl_next(const char *symname);
125
126 //char* captureScreenShotX(int* width, int* height);
127 //void releaseScreenShotX();
128
129 //int printSamplingLog(void);
130
131 //bool captureScreen(unsigned int logNum);
132 //void captureProbe();
133 //int registeScreenChange(int renderID);
134 //void detectTouchEvent(int touchID);
135 //int getTouchState();
136 //int isPossibleCapture();
137
138
139 /***************************************************************************
140  * helper macros
141  ***************************************************************************/
142
143 // ============================ rtdl ===============================
144
145 #define rtdl_next_set_once(symbol, sname)               \
146         do {                                            \
147                 if (symbol == NULL)                     \
148                         symbol = rtdl_next(sname);      \
149         } while (0)
150
151 #define rtdl_next_current_set_once(symbol)      \
152         rtdl_next_set_once(symbol, __func__)
153
154 // ========================= print log =====================================
155 #define PRINTMSG(...)   print_log_fmt(MSG_MSG, __FUNCTION__, __LINE__, __VA_ARGS__)
156 #define PRINTWRN(...)   print_log_fmt(MSG_WARNING, __FUNCTION__, __LINE__, __VA_ARGS__)
157 #define PRINTERR(...)   print_log_fmt(MSG_ERROR, __FUNCTION__, __LINE__, __VA_ARGS__)
158
159 #define INIT_INFO                                               \
160                 info.host_ip = 0;                               \
161                 info.host_port = 0;                             \
162                 info.msg_total_size = 0;                        \
163                 info.msg_pack_size = 0;                         \
164                 info.sock = NULL;                               \
165                 info.msg_buf = (char *)""
166
167 typedef struct {
168         uint32_t host_port;
169         uint32_t host_ip;
170         struct sockaddr *sock;
171
172         uint64_t msg_total_size;
173         uint32_t msg_pack_size;
174         char *msg_buf;
175
176 } info_t;
177
178 // =========================== declare variables ===========================
179 // local variable is faster than heap allocated variable
180 // array variable initialization with declare is expensive than memset
181 #define DECLARE_ERRNO_VARS              \
182         int olderrno = 0;               \
183         int newerrno = 0;
184
185 // declare variable for standard api (not tizen related api)
186 #define DECLARE_VARIABLE_STANDARD       \
187         probeInfo_t probeInfo;          \
188         int blockresult = 0;            \
189         bool bfiltering = true;         \
190         DECLARE_ERRNO_VARS;             \
191         int __attribute__((unused)) ret = 0
192
193 // declare variable for standard api (not tizen related api) without ret
194 #define DECLARE_VARIABLE_STANDARD_NORET         \
195                 probeInfo_t     probeInfo;                      \
196                 int blockresult;                                \
197                 bool bfiltering = true;                 \
198                 int olderrno, newerrno;                 \
199
200 // ========================== get function pointer =========================
201
202 #define GET_REAL_FUNCP(FUNCNAME, SONAME, FUNCTIONPOINTER)                       \
203         GET_REAL_FUNCP_STR(#FUNCNAME, SONAME, FUNCTIONPOINTER)
204
205 #define GET_REAL_FUNCP_STR(FUNCNAME, SONAME, FUNCTIONPOINTER)                   \
206                 do {                                                                                                            \
207                         if (!FUNCTIONPOINTER) {                                                                 \
208                                 probeBlockStart();                                                                      \
209                                 if (lib_handle[SONAME] == NULL) {                                       \
210                                         lib_handle[SONAME] = dlopen(lib_string[SONAME], RTLD_LAZY);                     \
211                                         if (lib_handle[SONAME] == NULL) {                               \
212                                                 fprintf(stderr, "dlopen failed : %s\n", lib_string[SONAME]);    \
213                                                 PRINTMSG("dlopen failed : %s\n", lib_string[SONAME]);   \
214                                                 exit(0);                                                                        \
215                                         } \
216                                 }                                                                                                       \
217                                 FUNCTIONPOINTER = dlsym(lib_handle[SONAME], FUNCNAME);          \
218                                 if (FUNCTIONPOINTER == NULL || dlerror() != NULL) {             \
219                                         fprintf(stderr, "dlsym failed : <" FUNCNAME ">\n");                     \
220                                         PRINTMSG("dlsym failed : <" FUNCNAME ">\n");                    \
221                                         exit(0);                                                                                \
222                                 }                                                                                                       \
223                                 probeBlockEnd();                                                                        \
224                         }                                                                                                               \
225                 } while(0)
226
227 #define GET_REAL_FUNC(FUNCNAME, SONAME)         \
228         GET_REAL_FUNCP(FUNCNAME, SONAME, FUNCNAME##p)
229
230 #define GET_REAL_FUNCP_RTLD_NEXT(FUNCNAME, FUNCTIONPOINTER)                     \
231                 do {                                                                                                            \
232                         if(!FUNCTIONPOINTER) {                                                                  \
233                                 probeBlockStart();                                                                      \
234                                 FUNCTIONPOINTER = dlsym(RTLD_NEXT, #FUNCNAME);          \
235                                 if(FUNCTIONPOINTER == NULL || dlerror() != NULL)        \
236                                         probe_terminate_with_err("function not found", #FUNCNAME, LIB_NO);              \
237                                 probeBlockEnd();                                                                        \
238                         }                                                                                                               \
239                 } while(0)
240
241 #define GET_REAL_FUNC_RTLD_NEXT(FUNCNAME)       \
242                 GET_REAL_FUNCP_RTLD_NEXT(FUNCNAME, FUNCNAME##p)
243
244 #define GET_REAL_FUNCP_RTLD_NEXT_CPP(FUNCNAME, FUNCTIONPOINTER)         \
245                 do {                                                                                                            \
246                         if(!FUNCTIONPOINTER) {                                                                  \
247                                 probeBlockStart();                                                                      \
248                                 void* funcp = dlsym(RTLD_NEXT, #FUNCNAME);                      \
249                                 if(funcp == NULL || dlerror() != NULL) {                        \
250                                         fprintf(stderr, "dlsym failed <%s>\n", #FUNCNAME);                                                      \
251                                         exit(0);                                                                                \
252                                 }                                                                                                       \
253                                 memcpy(&FUNCTIONPOINTER, &funcp, sizeof(void*));        \
254                                 probeBlockEnd();                                                                        \
255                         }                                                                                                               \
256                 } while(0)
257
258 #define GET_REAL_FUNC_RTLD_NEXT_CPP(FUNCNAME)   \
259                 GET_REAL_FUNCP_RTLD_NEXT_CPP(FUNCNAME, FUNCNAME##p)
260
261 // ======================= pre block macro ================================
262
263 #define PRE_PROBEBLOCK_BEGIN()                                                                                                  \
264         if((blockresult = preBlockBegin(CALLER_ADDRESS, bfiltering, _sopt)) != 0) {     \
265                 setProbePoint(&probeInfo)
266
267 #define PRE_PROBEBLOCK_END()                                                    \
268                 preBlockEnd();                                                  \
269         }                                                                       \
270         olderrno = errno;                                                       \
271         errno = 0
272
273 #define PRE_PROBEBLOCK() \
274                 PRE_PROBEBLOCK_BEGIN(); \
275                 PRE_PROBEBLOCK_END()
276
277 // ===================== unconditional probe block ========================
278
279 #define PRE_UNCONDITIONAL_BLOCK_BEGIN() \
280         do {                                                            \
281                 probeBlockStart();                              \
282                 setProbePoint(&probeInfo)
283
284 #define PRE_UNCONDITIONAL_BLOCK_END()   \
285                 probeBlockEnd();                                \
286         } while(0)
287
288 // =========================== post block macro ===========================
289
290 #define POST_PROBEBLOCK_BEGIN(LCTYPE, RETTYPE, RETVALUE, INPUTFORMAT, ...)      \
291         newerrno = errno;                                                                                                               \
292         if(postBlockBegin(blockresult)) {                                                                               \
293                 PREPARE_LOCAL_BUF(); \
294                 PACK_COMMON_BEGIN(MSG_PROBE_NETWORK, vAPI_ID, INPUTFORMAT, __VA_ARGS__);\
295                 PACK_COMMON_END(RETTYPE, RETVALUE, errno, blockresult);
296
297 #define POST_PROBEBLOCK_END()                                           \
298                 FLUSH_LOCAL_BUF();                                              \
299                 postBlockEnd();                                                         \
300         }                                                                                               \
301         errno = (newerrno != 0) ? newerrno : olderrno
302
303 // ========================= simplify macro ================================
304
305 #define BEFORE_ORIGINAL(FUNCNAME, LIBNAME)      \
306         DECLARE_VARIABLE_STANDARD;                              \
307         GET_REAL_FUNC(FUNCNAME, LIBNAME);               \
308         PRE_PROBEBLOCK()
309
310 #define BEFORE_ORIGINAL_NOFILTER(FUNCNAME, LIBNAME)     \
311         DECLARE_VARIABLE_STANDARD;                                              \
312         GET_REAL_FUNC(FUNCNAME, LIBNAME);                               \
313         bfiltering = false;                                                             \
314         PRE_PROBEBLOCK()
315
316 #ifdef __cplusplus
317 }
318 #endif
319
320 #endif