2 * Copyright (c) 2015 - 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.
20 #include <pkgmgr-info.h>
22 #include <bundle_internal.h>
26 #include "file_util.h"
27 #include "security_util.h"
28 #include "debug_util.h"
30 #define LABEL_SDBD "sdbd"
31 #define LABEL_NETWORK "system::debugging_network"
33 #define POLL_VALGRIND_LOGFILE 0x00000001
34 #define POLL_VALGRIND_XMLFILE 0x00000002
35 #define POLL_VALGRIND_MASSIFFILE 0x00000004
37 static int gdbserver_pid = -1;
38 static int gdbserver_app_pid = -1;
39 static bool gdbserver;
40 static int valgrind_option;
42 bool _gdbserver_is_running(void)
47 int _get_gdbserver_pid(void)
52 int _get_gdbserver_app_pid(void)
54 return gdbserver_app_pid;
57 int _get_valgrind_option(void)
59 return valgrind_option;
62 static int __check_pkginfo(const char *appid)
66 char *storeclientid = NULL;
67 pkgmgrinfo_pkginfo_h handle;
69 r = pkgmgrinfo_pkginfo_get_usr_pkginfo(appid, getuid(), &handle);
70 if (r != PMINFO_R_OK) {
71 _E("Failed to get pkginfo: %s", appid);
75 r = pkgmgrinfo_pkginfo_is_preload(handle, &preload);
76 if (r != PMINFO_R_OK) {
77 _E("Faield to check preload: %s", appid);
78 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
82 r = pkgmgrinfo_pkginfo_get_storeclientid(handle, &storeclientid);
83 if (r != PMINFO_R_OK) {
84 _E("Failed to get store client id: %s", appid);
85 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
89 if (preload == true || (storeclientid && storeclientid[0] != '\0')) {
90 _E("Debugging is not allowed");
91 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
95 r = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
96 if (r != PMINFO_R_OK) {
97 _E("Failed to destroy pkginfo: %s", appid);
98 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
104 static int __prepare_gdbserver(bundle *kb, const char *appid)
109 r = __check_pkginfo(appid);
113 path = bundle_get_val(kb, DLP_K_GDBSERVER_PATH);
117 r = dlp_chmod(path, S_IRUSR | S_IWUSR
118 | S_IXUSR | S_IRGRP | S_IXGRP
119 | S_IROTH | S_IXOTH, 1);
121 _W("Failed to set 755: %s", path);
128 static int __prepare_valgrind(bundle *kb)
131 const char **str_arr = NULL;
135 if (bundle_get_type(kb, DLP_K_VALGRIND_ARG) & BUNDLE_TYPE_ARRAY) {
136 str_arr = bundle_get_str_array(kb, DLP_K_VALGRIND_ARG, &len);
140 str = bundle_get_val(kb, DLP_K_VALGRIND_ARG);
147 for (i = 0; i < len; i++) {
148 if (str_arr[i] == NULL)
151 if (strncmp(str_arr[i], OPT_VALGRIND_LOGFILE_FIXED,
152 strlen(OPT_VALGRIND_LOGFILE_FIXED)) == 0) {
153 valgrind_option |= POLL_VALGRIND_LOGFILE;
154 if (access(PATH_VALGRIND_LOGFILE, F_OK) == 0) {
155 if (remove(PATH_VALGRIND_LOGFILE) != 0)
156 _W("Failed to remove %s",
157 PATH_VALGRIND_LOGFILE);
159 } else if (strncmp(str_arr[i], OPT_VALGRIND_XMLFILE_FIXED,
160 strlen(OPT_VALGRIND_XMLFILE_FIXED)) == 0) {
161 valgrind_option |= POLL_VALGRIND_XMLFILE;
162 if (access(PATH_VALGRIND_XMLFILE, F_OK) == 0) {
163 if (remove(PATH_VALGRIND_XMLFILE) != 0)
164 _W("Failed to remove %s",
165 PATH_VALGRIND_XMLFILE);
167 } else if (strncmp(str_arr[i], OPT_VALGRIND_MASSIFFILE_FIXED,
168 strlen(OPT_VALGRIND_MASSIFFILE_FIXED)) == 0) {
169 valgrind_option |= POLL_VALGRIND_MASSIFFILE;
170 if (access(PATH_VALGRIND_MASSIFFILE, F_OK) == 0) {
171 if (remove(PATH_VALGRIND_MASSIFFILE) != 0)
172 _W("Failed to remove %s",
173 PATH_VALGRIND_MASSIFFILE);
181 int _prepare_debug_tool(bundle *kb, const char *appid,
182 const char **str_arr, int len)
186 if (appid == NULL || str_arr == NULL)
191 gdbserver_app_pid = -1;
194 for (i = 0; i < len; i++) {
195 if (str_arr[i] == NULL)
198 if (strncmp(str_arr[i], SDK_DEBUG, strlen(SDK_DEBUG)) == 0 ||
199 strncmp(str_arr[i], SDK_ATTACH,
200 strlen(SDK_ATTACH)) == 0) {
201 if (__prepare_gdbserver(kb, appid) < 0)
203 } else if (strncmp(str_arr[i], SDK_VALGRIND,
204 strlen(SDK_VALGRIND)) == 0) {
205 __prepare_valgrind(kb);
212 /* chmod and chsmack to read file without root privilege */
213 void _change_file(const char *path)
217 r = dlp_chmod(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, 0);
219 _E("Failed to set 644: %s", path);
221 r = _set_smack_access_label(path, "*");
223 _E("Failed to set smack label %s *", path);
226 void _wait_for_valgrind_output(void)
231 if (valgrind_option & POLL_VALGRIND_LOGFILE) {
232 if (access(PATH_VALGRIND_LOGFILE, F_OK) == 0) {
233 _change_file(PATH_VALGRIND_LOGFILE);
234 valgrind_option &= ~POLL_VALGRIND_LOGFILE;
238 if (valgrind_option & POLL_VALGRIND_XMLFILE) {
239 if (access(PATH_VALGRIND_XMLFILE, F_OK) == 0) {
240 _change_file(PATH_VALGRIND_XMLFILE);
241 valgrind_option &= ~POLL_VALGRIND_XMLFILE;
245 if (valgrind_option & POLL_VALGRIND_MASSIFFILE) {
246 if (access(PATH_VALGRIND_MASSIFFILE, F_OK) == 0) {
247 _change_file(PATH_VALGRIND_MASSIFFILE);
248 valgrind_option &= ~POLL_VALGRIND_MASSIFFILE;
252 usleep(50 * 1000); /* 50ms */
254 } while (valgrind_option && wait_count <= 10);
257 _E("Failed to wait for valgrind output file");