2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <linux/limits.h>
22 #include <sys/types.h>
25 #include <bundle_internal.h>
27 #include "launchpad_common.h"
28 #include "launchpad_debug.h"
29 #include "debugger_info.h"
32 #define DEBUGGER_INFO_PATH "/usr/share/aul"
34 static int debug_initialized;
35 static GList *debugger_info_list;
36 static debugger_info_h debugger_info;
37 static GList *debug_argv_list;
38 static GList *extra_argv_list;
40 int _debug_create_extra_argv(int *argc, char ***argv)
44 const char *extra_argv;
48 if (argc == NULL || argv == NULL) {
49 _E("[DEBUG] Invalid parameter");
53 if (debugger_info == NULL)
56 new_argc = g_list_length(extra_argv_list);
60 new_argv = (char **)calloc(new_argc, sizeof(char *));
61 if (new_argv == NULL) {
67 iter = g_list_first(extra_argv_list);
69 extra_argv = (const char *)iter->data;
71 new_argv[i++] = strdup(extra_argv);
73 iter = g_list_next(iter);
78 _D("[DEBUG] argc: %d, i: %d", *argc, i);
83 int _debug_create_argv(int *argc, char ***argv, bool *attach)
88 const char *debug_argv;
89 const char *attach_str;
94 if (argc == NULL || argv == NULL || attach == NULL) {
95 _E("[DEBUG] Invalid parameter");
99 if (debugger_info == NULL)
102 exe = _debugger_info_get_exe(debugger_info);
106 attach_str = _debugger_info_get_attach(debugger_info);
107 if (attach_str && strcasecmp(attach_str, "true") == 0) {
112 list = _debugger_info_get_default_opt_list(debugger_info);
113 new_argc += g_list_length(debug_argv_list) + g_list_length(list) + 1;
114 new_argv = (char **)calloc(new_argc, sizeof(char *));
115 if (new_argv == NULL) {
121 new_argv[i++] = strdup(exe);
123 iter = g_list_first(list);
125 debug_argv = (const char *)iter->data;
127 new_argv[i++] = strdup(debug_argv);
129 iter = g_list_next(iter);
132 iter = g_list_first(debug_argv_list);
134 debug_argv = (const char *)iter->data;
136 new_argv[i++] = strdup(debug_argv);
138 iter = g_list_next(iter);
143 _D("[DEBUG] argc: %d, argv[0]: %s",
144 new_argc, new_argv[LOADER_ARG_PATH]);
149 void _debug_destroy_argv(int argc, char **argv)
156 for (i = 0; i < argc; i++)
161 int _debug_get_caller_pid(bundle *kb)
166 pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
168 pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
180 static int __redirect_std_fds(bundle *kb)
188 _E("[DEBUG] Invalid parameter");
192 caller_pid = _debug_get_caller_pid(kb);
193 if (caller_pid < 0) {
194 _E("[DEBUG] Failed to get caller pid");
199 snprintf(path, sizeof(path), "/proc/%d/fd/0", caller_pid);
200 fd = open(path, O_RDONLY);
202 _E("[DEBUG] Failed to open %s [%s]", path,
203 strerror_r(errno, err_buf, sizeof(err_buf)));
210 snprintf(path, sizeof(path), "/proc/%d/fd/1", caller_pid);
211 fd = open(path, O_WRONLY);
213 _E("[DEBUG] Failed to open %s [%s]", path,
214 strerror_r(errno, err_buf, sizeof(err_buf)));
221 snprintf(path, sizeof(path), "/proc/%d/fd/2", caller_pid);
222 fd = open(path, O_WRONLY);
224 _E("[DEBUG] Failed to open %s [%s]", path,
225 strerror_r(errno, err_buf, sizeof(err_buf)));
234 static void __add_extra_argv(gpointer data, gpointer user_data)
236 const char *key = (const char *)data;
237 bundle *kb = (bundle *)user_data;
239 const char **str_arr = NULL;
243 if (key == NULL || kb == NULL)
246 _D("[DEBUG] key: %s", key);
247 if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
248 str_arr = bundle_get_str_array(kb, key, &len);
250 str = bundle_get_val(kb, key);
257 for (i = 0; i < len; i++) {
258 if (str_arr[i] == NULL)
261 extra_argv_list = g_list_append(extra_argv_list,
269 static void __add_debug_argv(gpointer data, gpointer user_data)
271 const char *key = (const char *)data;
272 bundle *kb = (bundle *)user_data;
274 const char **str_arr = NULL;
278 if (key == NULL || kb == NULL)
281 _D("[DEBUG] key: %s", key);
282 if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
283 str_arr = bundle_get_str_array(kb, key, &len);
285 str = bundle_get_val(kb, key);
292 for (i = 0; i < len; i++) {
293 if (str_arr[i] == NULL)
296 debug_argv_list = g_list_append(debug_argv_list,
304 static void __set_debug_env(gpointer data, gpointer user_data)
306 const char *key = (const char *)data;
307 bundle *kb = (bundle *)user_data;
309 const char **str_arr = NULL;
312 char buf[LINE_MAX] = {0,};
314 if (key == NULL || kb == NULL)
317 _D("[DEBUG] key: %s", key);
318 if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
319 str_arr = bundle_get_str_array(kb, key, &len);
321 str = bundle_get_val(kb, key);
331 strncat(buf, str_arr[0], sizeof(buf) - strlen(buf) - 1);
332 for (i = 1; i < len; i++) {
333 if (str_arr[i] == NULL)
336 strncat(buf, ",", sizeof(buf) - strlen(buf) - 1);
337 strncat(buf, str_arr[i], sizeof(buf) - strlen(buf) - 1);
341 _D("[DEBUG] name: %s, value: %s", key, buf);
345 static void __remove_file(gpointer data, gpointer user_data)
347 const char *file = (const char *)data;
352 _D("[DEBUG] file: %s", file);
353 if (access(file, F_OK) == 0) {
354 if (remove(file) != 0)
355 _W("[DEBUG] Failed to remove %s", file);
359 void _debug_prepare_debugger(bundle *kb)
361 const char *debugger;
368 debugger = bundle_get_val(kb, AUL_K_SDK);
369 if (debugger == NULL)
372 ret = __redirect_std_fds(kb);
374 _E("[DEBUG] Failed to redirect standard fds");
376 _D("[DEBUG] debugger: %s", debugger);
377 debugger_info = _debugger_info_find(debugger_info_list, debugger);
378 if (debugger_info == NULL)
381 list = _debugger_info_get_unlink_list(debugger_info);
382 g_list_foreach(list, __remove_file, NULL);
384 list = _debugger_info_get_extra_env_list(debugger_info);
385 g_list_foreach(list, __set_debug_env, kb);
387 list = _debugger_info_get_extra_key_list(debugger_info);
388 g_list_foreach(list, __add_debug_argv, kb);
390 list = _debugger_info_get_last_extra_key_list(debugger_info);
391 g_list_foreach(list, __add_extra_argv, kb);
394 int _debug_init(void)
396 if (debug_initialized)
399 debugger_info_list = _debugger_info_load(DEBUGGER_INFO_PATH);
400 if (debugger_info_list == NULL)
403 debug_initialized = 1;
408 void _debug_fini(void)
410 if (!debug_initialized)
413 _debugger_info_unload(debugger_info_list);