Implement print backtrace request 09/323909/11
authorJihoi Kim <jihoi.kim@samsung.com>
Fri, 25 Apr 2025 07:04:21 +0000 (16:04 +0900)
committerJihoi Kim <jihoi.kim@samsung.com>
Mon, 12 May 2025 08:46:15 +0000 (17:46 +0900)
- amd_watchdog will handle WATCHDOG_PRINT_BT
- print backtrace of given pid(tid)

Change-Id: I0722f7a08f2c7f6519251d93f08915392a2f55a2
Signed-off-by: Jihoi Kim <jihoi.kim@samsung.com>
src/modules/watchdog/src/amd_watchdog.c

index f7eaff2458b731e913d2a65a719d569a4a98b109..a6420a044a123d5cf234df5a8d7ad0743ebdd0ff 100644 (file)
@@ -27,6 +27,8 @@
 #include <aul.h>
 #include <aul_cmd.h>
 #include <aul_sock.h>
+#include <aul_backtrace.h>
+#include <tizen_core.h>
 #include <bundle_internal.h>
 #include <amd.h>
 #include <signal.h>
@@ -321,6 +323,80 @@ static int __dispatch_watchdog_ping(amd_request_h req)
        return 0;
 }
 
+static bool __print_bactrace_cb(void *user_data)
+{
+       int pid = GPOINTER_TO_INT_SAFE(user_data);
+       int ret;
+
+       ret = aul_backtrace_print(pid);
+       if (ret != AUL_R_OK)
+               _E("Fail to print bt %d (%d)", pid, ret);
+
+       return false;
+}
+
+static int __dispatch_watchdog_print_bt(amd_request_h req)
+{
+       int ret;
+       tizen_core_h bt_core;
+       bundle *b = amd_request_get_bundle(req);
+       int pid = atoi(bundle_get_val(b, AUL_K_TARGET_PID));
+
+       _I("Print BT pid=%d", pid);
+       ret = tizen_core_find("Backtrace+", &bt_core);
+       if (ret != TIZEN_CORE_ERROR_NONE) {
+               _E("Fail to find backtrace core (%d)", ret);
+               amd_request_send_result(req, -EINVAL);
+               return -1;
+       }
+
+       tizen_core_source_h src;
+       ret = tizen_core_add_idle_job(bt_core, __print_bactrace_cb,
+                                     GINT_TO_POINTER(pid), &src);
+       if (ret != TIZEN_CORE_ERROR_NONE) {
+               _E("Fail to add backtrace job (%d)", ret);
+               amd_request_send_result(req, -EINVAL);
+               return -1;
+       }
+
+       amd_request_send_result(req, 0);
+       return 0;
+}
+
+static int __dispatch_printbt_checker(amd_cynara_caller_info_h info,
+                                     amd_request_h req, void *data)
+{
+       uid_t sender_uid;
+       pid_t sender_pid;
+       pid_t target_pid;
+       pid_t target_pgid;
+       bundle *b;
+
+       sender_uid = amd_request_get_uid(req);
+       if (sender_uid < REGULAR_UID_MIN)
+               return AMD_CYNARA_RET_ALLOWED;
+
+       sender_pid = amd_request_get_pid(req);
+       b = amd_request_get_bundle(req);
+       if (b == NULL) {
+               _E("Empty bundle data !!");
+               return AMD_CYNARA_RET_ERROR;
+       }
+
+       target_pid = atoi(bundle_get_val(b, AUL_K_TARGET_PID));
+       if (target_pid == 0) {
+               _E("Wrong target pid %s", bundle_get_val(b, AUL_K_TARGET_PID));
+               return AMD_CYNARA_RET_ERROR;
+       }
+
+       target_pgid = getpgid(target_pid);
+       if (sender_pid == target_pgid)
+               return AMD_CYNARA_RET_ALLOWED;
+
+       _E("Fail, caller_pid=%d, target_pgid=%d", sender_pid, target_pgid);
+       return AMD_CYNARA_RET_DENIED;
+}
+
 static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
                void *arg3, bundle *b)
 {
@@ -426,6 +502,18 @@ static amd_request_cmd_dispatch __dispatch_table[] = {
                .cmd = WATCHDOG_PING,
                .callback = __dispatch_watchdog_ping
        },
+       {
+               .cmd = WATCHDOG_PRINT_BT,
+               .callback = __dispatch_watchdog_print_bt
+       }
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+       {
+               .cmd = WATCHDOG_PRINT_BT,
+               .checker = __dispatch_printbt_checker,
+               .data = NULL,
+       },
 };
 
 static int __on_suspend_freezer_state_changed(const char *msg, int arg1,
@@ -475,6 +563,13 @@ EXPORT int AMD_MOD_INIT(void)
                return -1;
        }
 
+       r = amd_cynara_register_checkers(__cynara_checkers,
+                       ARRAY_SIZE(__cynara_checkers));
+       if (r < 0) {
+               _E("Failed to register checkers");
+               return -1;
+       }
+
        amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_ADD,
                        __on_app_status_add);
        amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_APP_START,