show the dump path on the console.
[platform/core/uifw/wayland-tbm.git] / src / wayland-tbm-util.c
1 /*
2 Copyright (C) 2015 Samsung Electronics co., Ltd. All Rights Reserved.
3
4 Contact:
5       SooChan Lim <sc1.lim@samsung.com>,
6       Sangjin Lee <lsj119@samsung.com>,
7       Boram Park <boram1288.park@samsung.com>,
8       Changyeon Lee <cyeon.lee@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the "Software"),
12 to deal in the Software without restriction, including without limitation
13 the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 and/or sell copies of the Software, and to permit persons to whom the
15 Software is furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice (including the next
18 paragraph) shall be included in all copies or substantial portions of the
19 Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 DEALINGS IN THE SOFTWARE.
28 */
29
30 #include "config.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36 #include <limits.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <tbm_surface.h>
41 #include <tbm_surface_internal.h>
42 #include "wayland-tbm-int.h"
43
44 #ifdef HAVE_DLOG
45 int bDlog;
46 #endif
47
48 int bTrace = 1;
49 int bDump = 0;
50
51 int
52 _str_to_pid(char * pid_str)
53 {
54         int pid = 0;
55         int d;
56
57         if (pid_str == NULL)
58                 return -1;
59
60         do {
61                 d = *pid_str - '0';
62                 if (d >= 0 && d <= 9)
63                         pid = pid*10 + d;
64                 else
65                         return -1;
66                 pid_str++;
67         } while (*pid_str);
68
69         return pid;
70 }
71
72 int
73 _waylend_tbm_util_target_parse(char * target_str, struct wayland_tbm_monitor_target *target)
74 {
75         char *t = NULL;
76         char *end = target_str;
77         int i = 0;
78         int pid = 0;
79         int server = 0;
80         int all = 0;
81
82         if (!target)
83                 return 0;
84
85         if (target_str == NULL || !strncmp(target_str, "all", 3)) {
86                 all = 1;
87                 server = 1;
88         } else {
89                 while ((t = strtok_r(NULL, ",", &end)) != NULL) {
90                         if (!strncmp(t, "server", 6))
91                                 server = 1;
92                         else if ((pid = _str_to_pid(t)) >= 0)
93                                 target->pid[i++] = pid;
94                         else
95                                 return 0;
96                 }
97         }
98
99         target->server = server;
100         target->all = all;
101
102         return 1;
103 }
104
105
106 int
107 _waylend_tbm_util_scale_parse(char * scale_str, double *scale)
108 {
109         if (!scale_str)
110                 return 1;
111
112         if (sscanf(scale_str, "scale=%lf", scale) == 1)
113                 if (*scale >= 0 && *scale <= 1)
114                         return 1;
115
116         return 0;
117 }
118
119 WL_TBM_MONITOR_PROC_STATE
120 _waylend_tbm_util_proc_state_parse(char *str)
121 {
122         if (str == NULL)
123                 return WL_TBM_MONITOR_PROC_STATE_UNKNOWN;
124         if (!strncmp(str, "on", 2))
125                 return WL_TBM_MONITOR_PROC_STATE_ON;
126         if (!strncmp(str, "off", 3))
127                 return WL_TBM_MONITOR_PROC_STATE_OFF;
128         if (!strncmp(str, "status", 6))
129                 return WL_TBM_MONITOR_PROC_STATE_STATUS;
130         return WL_TBM_MONITOR_PROC_STATE_UNKNOWN;
131 }
132
133 int
134 _wayland_tbm_util_show_path_parse(char * path_str, char * cwd, struct wayland_tbm_monitor_path *path)
135 {
136         char *end = path_str;
137         char *p = NULL;
138
139         if (!path_str)
140                 return 0;
141
142         /* parse options */
143         while ((p = strtok_r(NULL, ",", &end)) != NULL) {
144                 if (!strncmp(p, "dlog", 4))
145                         path->dlog = 1;
146                 else if (!strncmp(p, "console", 7))
147                         path->console = 1;
148                 else {
149                         if (p[0] == '/')
150                                 snprintf(path->file, WL_TBM_MONITOR_PATH_LEN, "%s", p);
151                         else {
152                                 if (cwd)
153                                         snprintf(path->file, WL_TBM_MONITOR_PATH_LEN, "%s/%s", cwd, p);
154                                 else
155                                         snprintf(path->file, WL_TBM_MONITOR_PATH_LEN, "%s", p);
156                         }
157                 }
158         }
159
160         return 1;
161 }
162
163
164 int
165 _waylend_tbm_util_trace(WL_TBM_MONITOR_PROC_STATE cmd, tbm_bufmgr bufmgr)
166 {
167         if (!bTrace && cmd == WL_TBM_MONITOR_PROC_STATE_ON) {
168                 tbm_bufmgr_debug_trace(bufmgr, 1);
169                 bTrace = 1;
170         } else if (bTrace && cmd == WL_TBM_MONITOR_PROC_STATE_OFF) {
171                 tbm_bufmgr_debug_trace(bufmgr, 0);
172                 bTrace = 0;
173         }
174         return bTrace;
175 }
176 void
177 _waylend_tbm_util_dump_snapshot(tbm_bufmgr bufmgr, double scale, char *path)
178 {
179         if (path) {
180                 tbm_bufmgr_debug_dump_set_scale(scale);
181                 tbm_bufmgr_debug_dump_all(path);
182         }
183 }
184
185 int
186 _waylend_tbm_util_dump_queue(WL_TBM_MONITOR_PROC_STATE cmd, tbm_bufmgr bufmgr, double scale)
187 {
188         static char *path = NULL;
189
190         if (!bDump && cmd == WL_TBM_MONITOR_PROC_STATE_ON) {
191                 path = _wayland_tbm_dump_directory_make();
192                 if (path != NULL) {
193                         tbm_bufmgr_debug_dump_set_scale(scale);
194                         tbm_bufmgr_debug_queue_dump(path, 20, 1);
195                         bDump = 1;
196                 }
197         } else if (bDump && cmd == WL_TBM_MONITOR_PROC_STATE_OFF) {
198                 tbm_bufmgr_debug_queue_dump(NULL, 0, 0);
199                 if (path) {
200                         free(path);
201                         path = NULL;
202                 }
203                 bDump = 0;
204         }
205         return bDump;
206 }
207
208 void
209 _wayland_tbm_util_get_appname_brief(char *brief)
210 {
211         char delim[] = "/";
212         char *token = NULL;
213         char temp[255] = {0,};
214         char *saveptr = NULL;
215
216         token = strtok_r(brief, delim, &saveptr);
217
218         while (token != NULL) {
219                 memset(temp, 0x00, 255 * sizeof(char));
220                 strncpy(temp, token, 254 * sizeof(char));
221                 token = strtok_r(NULL, delim, &saveptr);
222         }
223
224         snprintf(brief, sizeof(temp), "%s", temp);
225 }
226
227 void
228 _wayland_tbm_util_get_appname_from_pid(long pid, char *str)
229 {
230         FILE *fp;
231         int len;
232         long app_pid = pid;
233         char fn_cmdline[255] = {0,};
234         char cmdline[255] = {0,};
235
236         snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", app_pid);
237
238         fp = fopen(fn_cmdline, "r");
239         if (fp == 0) {
240                 fprintf(stderr, "cannot file open /proc/%ld/cmdline", app_pid);
241                 return;
242         }
243
244         if (!fgets(cmdline, 255, fp)) {
245                 fprintf(stderr, "fail to get appname for pid(%ld)\n", app_pid);
246                 fclose(fp);
247                 return;
248         }
249         fclose(fp);
250
251         len = strlen(cmdline);
252         if (len < 1)
253                 memset(cmdline, 0x00, 255);
254         else
255                 cmdline[len] = 0;
256
257         snprintf(str, sizeof(cmdline), "%s", cmdline);
258 }
259
260 void
261 _wayland_tbm_check_dlog_enable(void)
262 {
263 #ifdef HAVE_DLOG
264         char *env;
265
266         env = getenv("WL_TBM_DLOG");
267         if (env) {
268                 bDlog = atoi(env);
269                 WL_TBM_LOG("WL_TBM_DLOG=%s", env);
270         } else {
271                 bDlog = 1;
272         }
273 #endif
274         return;
275 }
276
277 char *
278 _wayland_tbm_dump_directory_make(void)
279 {
280         char *fullpath;
281         time_t timer;
282         struct tm *t, *buf;
283         char appname[255] = {'\0'};
284
285         timer = time(NULL);
286
287         buf = calloc(1, sizeof(struct tm));
288         if (buf == 0)
289                 return NULL;
290
291         t = localtime_r(&timer, buf);
292         if (!t) {
293                 free(buf);
294                 return NULL;
295         }
296
297         fullpath = (char *) calloc(1, PATH_MAX * sizeof(char));
298         if (!fullpath) {
299                 free(buf);
300                 return NULL;
301         }
302
303         _wayland_tbm_util_get_appname_from_pid(getpid(), appname);
304
305         _wayland_tbm_util_get_appname_brief(appname);
306
307
308         snprintf(fullpath, PATH_MAX, "/tmp/tbm_dump_%s_%04d%02d%02d.%02d%02d%02d", appname, t->tm_year + 1900,
309                         t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
310
311         free(buf);
312
313         if ((mkdir(fullpath, 0755)) < 0) {
314                 free(fullpath);
315                 return NULL;
316         }
317
318         return fullpath;
319 }