add dump commands to the monitor for debugging 49/78849/3 accepted/tizen/common/20160719.172043 accepted/tizen/ivi/20160718.105001 accepted/tizen/mobile/20160718.105045 accepted/tizen/tv/20160718.104744 accepted/tizen/wearable/20160718.105008 submit/tizen/20160718.061633
authorRoman Marchenko <r.marchenko@samsung.com>
Wed, 6 Jul 2016 14:31:56 +0000 (17:31 +0300)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 15 Jul 2016 06:13:55 +0000 (23:13 -0700)
Change-Id: I9732694de0ca708c0d5e99ed8ff3fdec23b068be
Signed-off-by: Roman Marchenko <r.marchenko@samsung.com>
src/wayland-tbm-client.c
src/wayland-tbm-int.h
src/wayland-tbm-server.c
src/wayland-tbm-util.c
tool/wayland-tbm-monitor.c

index 376895c..f917e06 100644 (file)
@@ -89,16 +89,32 @@ WL_TBM_MONITOR_TRACE_STATUS trace_status;
 
 //#define DEBUG_TRACE
 #ifdef DEBUG_TRACE
-#define WL_TBM_TRACE(fmt, ...)   if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf (stderr, "[WL_TBM_C(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+#define WL_TBM_TRACE(fmt, ...)   if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf(stderr, "[WL_TBM_C(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
 #else
 #define WL_TBM_TRACE(fmt, ...)
 #endif
 
 static void
+_wayland_tbm_client_dump(struct wayland_tbm_client * tbm_client, WL_TBM_MONITOR_DUMP_COMMAND cmd, WL_TBM_MONITOR_DUMP_TYPE type)
+{
+       if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT) {
+               char * path = _wayland_tbm_dump_directory_make();
+               if (path) {
+                       tbm_surface_internal_dump_all(path);
+                       free(path);
+               }
+       }
+       else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_ON)
+               WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_ON isn't implemented yet\n");
+       else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_OFF)
+               WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_OFF isn't implemented yet\n");
+}
+
+static void
 handle_tbm_monitor_client_tbm_bo(void *data,
                                 struct wl_tbm *wl_tbm,
                                 int32_t command,
-                                int32_t trace_command,
+                                int32_t subcommand,
                                 int32_t target,
                                 int32_t pid)
 {
@@ -106,7 +122,7 @@ handle_tbm_monitor_client_tbm_bo(void *data,
 
 #ifdef DEBUG_TRACE
        WL_TBM_TRACE("command=%d, trace_command=%d, target=%d, pid=%d.\n",
-                  command, trace_command, target, pid);
+                  command, subcommand, target, pid);
 #endif
 
        if (command == WL_TBM_MONITOR_COMMAND_SHOW) {
@@ -122,16 +138,26 @@ handle_tbm_monitor_client_tbm_bo(void *data,
        } else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {
                if (target == WL_TBM_MONITOR_TARGET_CLIENT) {
                        if (getpid() == pid) {
-                               if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+                               if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
                                        WL_TBM_DEBUG("clinet(%d): trace status: %s\n", getpid(), _tarce_status_to_str(trace_status));
                                else
-                                       _change_trace_status(&trace_status, trace_command, tbm_client->bufmgr);
+                                       _change_trace_status(&trace_status, subcommand, tbm_client->bufmgr);
                        }
                } else if (target == WL_TBM_MONITOR_TARGET_ALL) {
-                       if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+                       if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
                                WL_TBM_DEBUG("clinet(%d): trace status: %s\n", getpid(), _tarce_status_to_str(trace_status));
                        else
-                               _change_trace_status(&trace_status, trace_command, tbm_client->bufmgr);
+                               _change_trace_status(&trace_status, subcommand, tbm_client->bufmgr);
+               } else {
+                       WL_TBM_LOG("[%s]: Error target is not available. target = %d\n", __func__,
+                                  target);
+               }
+       } else if (command == WL_TBM_MONITOR_COMMAND_DUMP) {
+               if (target == WL_TBM_MONITOR_TARGET_CLIENT) {
+                       if (getpid() == pid)
+                               _wayland_tbm_client_dump(tbm_client, subcommand & 0xFF, subcommand >> 16 & 0xFF);
+               } else if (target == WL_TBM_MONITOR_TARGET_ALL) {
+                       _wayland_tbm_client_dump(tbm_client, subcommand & 0xFF, subcommand >> 16 & 0xFF);
                } else {
                        WL_TBM_LOG("[%s]: Error target is not available. target = %d\n", __func__,
                                   target);
@@ -140,7 +166,6 @@ handle_tbm_monitor_client_tbm_bo(void *data,
                WL_TBM_LOG("[%s]: Error command is not available. command = %d\n", __func__,
                           command);
        }
-
 }
 
 static const struct wl_tbm_listener wl_tbm_client_listener = {
index fa80c1f..69a61b7 100644 (file)
@@ -105,6 +105,7 @@ typedef enum {
        WL_TBM_MONITOR_COMMAND_LIST,
        WL_TBM_MONITOR_COMMAND_SHOW,
        WL_TBM_MONITOR_COMMAND_TRACE,
+       WL_TBM_MONITOR_COMMAND_DUMP,
 } WL_TBM_MONITOR_COMMAND;
 
 typedef enum {
@@ -118,6 +119,21 @@ typedef enum {
 } WL_TBM_MONITOR_TRACE_COMMAND;
 
 typedef enum {
+       WL_TBM_MONITOR_DUMP_COMMAND_ON,
+       WL_TBM_MONITOR_DUMP_COMMAND_OFF,
+       WL_TBM_MONITOR_DUMP_COMMAND_REGISTER,
+       WL_TBM_MONITOR_DUMP_COMMAND_UNREGISTER,
+       WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT,
+       WL_TBM_MONITOR_DUMP_COMMAND_STATUS,
+} WL_TBM_MONITOR_DUMP_COMMAND;
+
+typedef enum {
+       WL_TBM_MONITOR_DUMP_TYPE_IMPORT,
+       WL_TBM_MONITOR_DUMP_TYPE_REF,
+       WL_TBM_MONITOR_DUMP_TYPE_MAP,
+} WL_TBM_MONITOR_DUMP_TYPE;
+
+typedef enum {
        WL_TBM_MONITOR_TRACE_STATUS_UNREGISTERED,
        WL_TBM_MONITOR_TRACE_STATUS_OFF,
        WL_TBM_MONITOR_TRACE_STATUS_ON,
@@ -148,6 +164,9 @@ _change_trace_status(WL_TBM_MONITOR_TRACE_STATUS * curr_status, WL_TBM_MONITOR_T
 char *
 _tarce_status_to_str(WL_TBM_MONITOR_TRACE_STATUS status);
 
+char *
+_wayland_tbm_dump_directory_make(void);
+
 #ifdef  __cplusplus
 }
 #endif
index 81d0d7a..ac4e96a 100644 (file)
@@ -50,7 +50,7 @@ WL_TBM_MONITOR_TRACE_STATUS trace_status;
 //#define WL_TBM_SERVER_DEBUG
 //#define DEBUG_TRACE
 #ifdef DEBUG_TRACE
-#define WL_TBM_TRACE(fmt, ...)   if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf (stderr, "[WL_TBM_S(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+#define WL_TBM_TRACE(fmt, ...)   if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf(stderr, "[WL_TBM_S(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
 #else
 #define WL_TBM_TRACE(fmt, ...)
 #endif
@@ -224,10 +224,26 @@ static const struct wl_tbm_queue_interface _wayland_tbm_queue_impementation = {
 };
 
 static void
+_wayland_tbm_server_dump(struct wayland_tbm_server *tbm_srv, WL_TBM_MONITOR_DUMP_COMMAND cmd, WL_TBM_MONITOR_DUMP_TYPE type)
+{
+       if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT) {
+               char * path = _wayland_tbm_dump_directory_make();
+               if (path) {
+                       tbm_surface_internal_dump_all(path);
+                       free (path);
+               }
+       }
+       else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_ON)
+               WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_ON isn't implemented yet\n");
+       else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_OFF)
+               WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_OFF isn't implemented yet\n");
+}
+
+static void
 _wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,
                struct wl_resource *resource,
                int32_t command,
-               int32_t trace_command,
+               int32_t subcommand,
                int32_t target,
                int32_t pid)
 {
@@ -236,8 +252,8 @@ _wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,
        int i = 0;
 
 #ifdef DEBUG_TRACE
-       WL_TBM_TRACE("command=%d, trace_command=%d, target=%d, pid=%d.\n",
-                  command, trace_command, target, pid);
+       WL_TBM_TRACE("command=%d, subcommand=%x, target=%d, pid=%d.\n",
+                  command, subcommand, target, pid);
 #endif
 
        if (command == WL_TBM_MONITOR_COMMAND_LIST) {
@@ -278,7 +294,7 @@ _wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,
                                if (c_res->resource == resource)
                                        continue;
 
-                               wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
+                               wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, subcommand,
                                                                  target, pid);
                        }
                }
@@ -286,11 +302,13 @@ _wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,
                if (command == WL_TBM_MONITOR_COMMAND_SHOW) {
                        tbm_bufmgr_debug_show(tbm_srv->bufmgr);
                } else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {
-                       if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+                       if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
                                WL_TBM_DEBUG("server: trace status: %s\n",
                                                        _tarce_status_to_str(trace_status));
                        else
-                               _change_trace_status(&trace_status, trace_command, tbm_srv->bufmgr);
+                               _change_trace_status(&trace_status, subcommand, tbm_srv->bufmgr);
+               } else if (command == WL_TBM_MONITOR_COMMAND_DUMP) {
+                       _wayland_tbm_server_dump(tbm_srv, subcommand & 0xFF, subcommand >> 16 & 0xFF);
                } else
                        wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
                                               "invalid format");
@@ -303,7 +321,7 @@ _wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,
                                        if (c_res->resource == resource)
                                                continue;
 
-                                       wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
+                                       wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, subcommand,
                                                                          target, pid);
                                }
                        }
@@ -316,15 +334,29 @@ _wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,
                                        if (c_res->resource == resource)
                                                continue;
 
-                                       wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
+                                       wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, subcommand,
                                                                          target, pid);
                                }
                        }
-                       if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+                       if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
                                WL_TBM_DEBUG("server: trace status: %s\n",
                                                        _tarce_status_to_str(trace_status));
                        else
-                               _change_trace_status(&trace_status, trace_command, tbm_srv->bufmgr);
+                               _change_trace_status(&trace_status, subcommand, tbm_srv->bufmgr);
+               } else if (command == WL_TBM_MONITOR_COMMAND_DUMP) {
+                       /* send the events to all client containing wl_tbm resource except for the wayland-tbm-monitor(requestor). */
+                       if (!wl_list_empty(&tbm_srv->cresource_list)) {
+                               wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->cresource_list, link) {
+                                       /* skip the requestor (wayland-tbm-monitor */
+                                       if (c_res->resource == resource)
+                                               continue;
+
+                                       wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, subcommand,
+                                                                         target, pid);
+                               }
+                       }
+                       _wayland_tbm_server_dump(tbm_srv, subcommand & 0xFF, subcommand >> 16 & 0xFF);
+
                } else
                        wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
                                               "invalid format");
index fcb8f62..e250f32 100644 (file)
@@ -30,8 +30,13 @@ DEALINGS IN THE SOFTWARE.
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
+#include <limits.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
 #include "wayland-tbm-int.h"
 
 #ifdef HAVE_DLOG
@@ -141,3 +146,46 @@ _wayland_tbm_check_dlog_enable(void)
     return;
 }
 
+char *
+_wayland_tbm_dump_directory_make(void)
+{
+       char *fullpath;
+       time_t timer;
+       struct tm *t, *buf;
+       char appname[255] = {'\0'};
+
+       timer = time(NULL);
+
+       buf = calloc(1, sizeof(struct tm));
+       if (buf == 0)
+               return NULL;
+
+       t = localtime_r(&timer, buf);
+       if (!t) {
+               free(buf);
+               return NULL;
+       }
+
+       fullpath = (char *) calloc(1, PATH_MAX * sizeof(char));
+       if (!fullpath) {
+               free(buf);
+               return NULL;
+       }
+
+       _wayland_tbm_util_get_appname_from_pid(getpid(), appname);
+
+       _wayland_tbm_util_get_appname_brief(appname);
+
+
+       snprintf(fullpath, PATH_MAX, "/tmp/tbm_dump_%s_%04d%02d%02d.%02d%02d%02d", appname, t->tm_year + 1900,
+                       t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+
+       free(buf);
+
+       if ((mkdir(fullpath, 0755)) < 0) {
+               free(fullpath);
+               return NULL;
+       }
+
+       return fullpath;
+}
index 3629f5a..5cf38d8 100644 (file)
@@ -42,7 +42,14 @@ struct wayland_tbm_monitor {
 
        struct {
                WL_TBM_MONITOR_COMMAND command;
-               WL_TBM_MONITOR_TRACE_COMMAND trace_command;
+               union {
+                       int  subcommand;
+                       WL_TBM_MONITOR_TRACE_COMMAND trace_command;
+                       struct {
+                               WL_TBM_MONITOR_DUMP_COMMAND dump_command : 16;
+                               WL_TBM_MONITOR_DUMP_TYPE dump_type : 16;
+                       };
+               };
                WL_TBM_MONITOR_TARGET target;
                int pid;
        } options;
@@ -71,7 +78,7 @@ _wayland_tbm_monitor_registry_handle_global(void *data,
                /* request the tbm monitor */
                wl_tbm_request_tbm_monitor(tbm_monitor->wl_tbm,
                                           tbm_monitor->options.command,
-                                          tbm_monitor->options.trace_command,
+                                          tbm_monitor->options.subcommand,
                                           tbm_monitor->options.target,
                                           tbm_monitor->options.pid);
                wl_display_roundtrip(tbm_monitor->dpy);
@@ -106,6 +113,39 @@ _wl_tbm_trace_usage()
 }
 
 static void
+_wl_tbm_dump_usage()
+{
+       WL_TBM_LOG("  dump : dump the tbm_bos\n");
+       WL_TBM_LOG("   usage : wayland-tbm-monitor dump [command]\n");
+       WL_TBM_LOG("    <command>\n");
+       WL_TBM_LOG("      snapshot client [pid]         : make dumps of all tbm_bos for the client with pid.\n");
+       WL_TBM_LOG("      snapshot server               : make dumps of all tbm_bos for the server.\n");
+       WL_TBM_LOG("      snapshot all                  : make dumps of all tbm_bos for all clients and server.\n");
+       WL_TBM_LOG("      on                            : turn on process of dumping.\n");
+       WL_TBM_LOG("      off                           : turn off process of dumping.\n");
+       WL_TBM_LOG("      register [type] client [pid]  : register the pid of client.\n");
+       WL_TBM_LOG("      register [type] server        : register the server.\n");
+       WL_TBM_LOG("      register [type] all           : register all clients and server.\n");
+       WL_TBM_LOG("      unregister client [pid]       : unregister the pid of client.\n");
+       WL_TBM_LOG("      unregister server             : unregister the server.\n");
+       WL_TBM_LOG("      unregister all                : unregister all clients and server.\n");
+       WL_TBM_LOG("      status                        : show the status of the dump setting values.\n");
+       WL_TBM_LOG("    <type>\n");
+       WL_TBM_LOG("      import                        : make dump when a tbm_bo is imported/exported.\n");
+       WL_TBM_LOG("      ref                           : make dump when a tbm_bo is ref/unref.\n");
+       WL_TBM_LOG("      map                           : make dump when a tbm_bo is mapped/unmapped.\n");
+       WL_TBM_LOG("    <examples>\n");
+       WL_TBM_LOG("      # wayland-tbm-monitor dump register map client 1234\n");
+       WL_TBM_LOG("      # wayland-tbm-monitor dump register import all\n");
+       WL_TBM_LOG("      # wayland-tbm-monitor dump unregister all\n");
+       WL_TBM_LOG("      # wayland-tbm-monitor dump snapshot all\n");
+       WL_TBM_LOG("      # wayland-tbm-monitor dump on\n");
+       WL_TBM_LOG("      # wayland-tbm-monitor dump off\n");
+       WL_TBM_LOG("\n");
+}
+
+
+static void
 _wl_tbm_show_usage()
 {
        WL_TBM_LOG("  show : show the infomation of the tbm_bo\n");
@@ -136,10 +176,27 @@ _wl_tbm_usage()
        _wl_tbm_list_usage();
        _wl_tbm_show_usage();
        _wl_tbm_trace_usage();
+       _wl_tbm_dump_usage();
        WL_TBM_LOG("\n");
 }
 
 static int
+_wl_tbm_select_dump_type_option(struct wayland_tbm_monitor *tbm_monitor, int argc,
+                                                               char *argv[], int arg_pos)
+{
+       if (!strncmp(argv[arg_pos], "import", strlen(argv[arg_pos]) + 1))
+               tbm_monitor->options.dump_type = WL_TBM_MONITOR_DUMP_TYPE_IMPORT;
+       else if (!strncmp(argv[arg_pos], "ref", strlen(argv[arg_pos]) + 1))
+               tbm_monitor->options.dump_type = WL_TBM_MONITOR_DUMP_TYPE_REF;
+       else if (!strncmp(argv[arg_pos], "map", strlen(argv[arg_pos]) + 1))
+               tbm_monitor->options.dump_type = WL_TBM_MONITOR_DUMP_TYPE_MAP;
+       else
+               return 0;
+
+       return 1;
+}
+
+static int
 _wl_tbm_select_target_option(struct wayland_tbm_monitor *tbm_monitor, int argc,
                             char *argv[], int arg_pos)
 {
@@ -232,6 +289,63 @@ _wl_tbm_monitor_process_options(struct wayland_tbm_monitor *tbm_monitor,
                        _wl_tbm_trace_usage();
                        return 0;
                }
+       } else if (!strncmp(argv[1], "dump", strlen(argv[1]) + 1)) {
+
+               tbm_monitor->options.command = WL_TBM_MONITOR_COMMAND_DUMP;
+
+               if (!strncmp(argv[2], "on", strlen(argv[2]) + 1)) {
+                       tbm_monitor->options.dump_command = WL_TBM_MONITOR_DUMP_COMMAND_ON;
+                       tbm_monitor->options.target = WL_TBM_MONITOR_TARGET_ALL;
+               } else if (!strncmp(argv[2], "off", strlen(argv[2]) + 1)) {
+                       tbm_monitor->options.dump_command = WL_TBM_MONITOR_DUMP_COMMAND_OFF;
+                       tbm_monitor->options.target = WL_TBM_MONITOR_TARGET_ALL;
+               } else if (!strncmp(argv[2], "snapshot", strlen(argv[2]) + 1)) {
+                       tbm_monitor->options.dump_command = WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT;
+                       if (argc < 4)
+                               tbm_monitor->options.target = WL_TBM_MONITOR_TARGET_ALL;
+                       else {
+                               if (!_wl_tbm_select_target_option(tbm_monitor, argc, argv, 3)) {
+                                       WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+                                       _wl_tbm_dump_usage();
+                                       return 0;
+                               }
+                       }
+               } else if (!strncmp(argv[2], "register", strlen(argv[2]) + 1)) {
+                       if (argc < 5) {
+                               WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+                               _wl_tbm_dump_usage();
+                               return 0;
+                       }
+
+                       tbm_monitor->options.trace_command = WL_TBM_MONITOR_DUMP_COMMAND_REGISTER;
+
+                       if (!_wl_tbm_select_dump_type_option(tbm_monitor, argc, argv, 3)) {
+                               _wl_tbm_dump_usage();
+                               return 0;
+                       }
+
+                       if (!_wl_tbm_select_target_option(tbm_monitor, argc, argv, 4)) {
+                               WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+                               _wl_tbm_dump_usage();
+                               return 0;
+                       }
+               } else if (!strncmp(argv[2], "unregister", strlen(argv[2]) + 1)) {
+                       if (argc < 4) {
+                               WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+                               _wl_tbm_dump_usage();
+                               return 0;
+                       }
+
+                       tbm_monitor->options.trace_command = WL_TBM_MONITOR_DUMP_COMMAND_UNREGISTER;
+                       if (!_wl_tbm_select_target_option(tbm_monitor, argc, argv, 3)) {
+                               WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+                               _wl_tbm_dump_usage();
+                               return 0;
+                       }
+               } else {
+                       _wl_tbm_dump_usage();
+                       return 0;
+               }
        } else {
                _wl_tbm_usage();
                return 0;