--- /dev/null
+/*
+ * debug-launchpad
+ *
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangmin Jeong <s-mim.jeong@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <aul.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include "app_sock.h"
+#include "simple_util.h"
+
+#define APP_PATH_MAX_LENGTH 1024
+
+static char app_path[APP_PATH_MAX_LENGTH];
+
+static void print_usage(const char *progname)
+{
+ printf("[usage] %s [appid] __AUL_SDK__ ATTACH __DLP_ATTACH_ARG__ --attach,:[port],[pid]\n", progname);
+ printf("ex) $ launch_debug [appid] __AUL_SDK__ ATTACH __DLP_ATTACH_ARG__ --attach,:10003,1234\n");
+}
+
+static int iterfunc(const aul_app_info *info, void *data)
+{
+ if (info && data && !strcmp(info->appid, (char *)data)) {
+ strncpy(app_path, info->app_path, APP_PATH_MAX_LENGTH - 1);
+ app_path[APP_PATH_MAX_LENGTH - 1] = '\0';
+ return -1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int i, j, cnt;
+ int ret;
+ bundle *b;
+ int b_datalen;
+ bundle_raw *b_data;
+ char *bundle_args[10];
+
+ if (argc < 2) {
+ print_usage(argv[0]);
+ exit(-1);
+ }
+
+ b = bundle_create();
+ if (b == NULL) {
+ printf("out of memory");
+ exit(-1);
+ }
+
+ if(aul_get_running_app_info_from_proc(iterfunc, argv[1]) != AUL_R_OK)
+ _E("get running app info failed");
+
+ for (i = 2; i < argc; i++) {
+ if (argv[i] && !strcmp(argv[i], "__AUL_SDK__"))
+ bundle_add(b, "__AUL_SDK__", argv[i + 1]);
+
+ if (argv[i] && !strcmp(argv[i], "__DLP_ATTACH_ARG__")) {
+ bundle_args[0] = strtok(argv[i + 1], ",");
+
+ cnt = 1;
+ while ((bundle_args[cnt] = strtok(NULL, ",")) != NULL)
+ cnt++;
+
+ bundle_add(b, "ATTACH", "__DLP_ATTACH_ARG__");
+ bundle_add_str_array(b, "__DLP_ATTACH_ARG__", NULL, cnt);
+
+ for (j = 0; j < cnt; j++)
+ bundle_set_str_array_element(b, "__DLP_ATTACH_ARG__", j, bundle_args[j]);
+ }
+ }
+
+ bundle_add(b, "__AUL_PKG_NAME__", argv[1]);
+ bundle_add(b, "__AUL_STARTTIME__", "1441865531/743961");
+ bundle_add(b, "__AUL_CALLER_PID__", "0");
+ bundle_add(b, "__AUL_HWACC__", "SYS");
+ bundle_add(b, "__AUL_TASKMANAGE__", "true");
+ bundle_add(b, "__AUL_EXEC__", app_path);
+ bundle_add(b, "__AUL_PACKAGETYPE__", "rpm");
+ bundle_add(b, "__AUL_INTERNAL_POOL__", "false");
+ bundle_add(b, "__AUL_PKGID_", argv[1]);
+ bundle_add(b, "__AUL_HIGHPRIORITY__", "true");
+
+ bundle_encode(b, &b_data, &b_datalen);
+
+ ret = __app_send_raw(DEBUG_LAUNCHPAD_PID, APP_START, b_data, b_datalen);
+ if (ret < 0)
+ _E("Bundle send fail");
+
+ free(b_data);
+
+ return ret;
+}
#include <poll.h>
#include <sys/prctl.h>
#include <malloc.h>
+#include <bundle_internal.h>
#include "app_sock.h"
#include "aul.h"
#include "sigchild.h"
#include "aul_util.h"
#include "pkgmgr-info.h"
+#include "fileutils.h"
#include "heap_dbg.h"
#include <sys/smack.h>
#include "fileutils.h"
#include <sys/capability.h>
+#ifdef _APPFW_FEATURE_SOCKET_ACTIVATION
+#include <systemd/sd-daemon.h>
+#endif
#define _static_ static inline
#define POLLFD_MAX 1
#define DLP_K_DEBUG_ARG "__DLP_DEBUG_ARG__"
#define DLP_K_UNIT_TEST_ARG "__DLP_UNIT_TEST_ARG__"
#define DLP_K_VALGRIND_ARG "__DLP_VALGRIND_ARG__"
+#define DLP_K_ATTACH_ARG "__DLP_ATTACH_ARG__"
#define PATH_GDBSERVER "/home/developer/sdk_tools/gdbserver/gdbserver"
#define PATH_VALGRIND "/home/developer/sdk_tools/valgrind/usr/bin/valgrind"
static int poll_outputfile = 0;
static int is_gdbserver_launched;
+static const char *debuggee_appid = NULL;
void __set_env(app_info_from_db * menu_info, bundle * kb);
int __prepare_exec(const char *pkg_name,
__preexec_run(menu_info->pkg_type, pkg_name, app_path);
- /* SET PRIVILEGES*/
- _D("pkg_name : %s / pkg_type : %s / app_path : %s", pkg_name
- , menu_info->pkg_type, app_path);
- if ((ret = __set_access(pkg_name, menu_info->pkg_type, app_path)) < 0) {
- _D("fail to set privileges - check your package's credential : %d\n"
- , ret);
- return -1;
+ if (strcmp(bundle_get_val(kb, "__AUL_SDK__"), "ATTACH")) {
+ /* SET PRIVILEGES*/
+ _D("pkg_name : %s / pkg_type : %s / app_path : %s", pkg_name
+ , menu_info->pkg_type, app_path);
+ if ((ret = __set_access(pkg_name, menu_info->pkg_type, app_path)) < 0) {
+ _D("fail to set privileges - check your package's credential : %d\n"
+ , ret);
+ return -1;
+ }
}
+
/* SET DUMPABLE - for coredump*/
prctl(PR_SET_DUMPABLE, 1);
const char **str_array = NULL;
int len = 0;
int i;
- char ** new_argv = NULL;
+ char **new_argv = NULL;
- if(bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
+ if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
str_array = bundle_get_str_array(kb, key, &len);
} else {
str = bundle_get_val(kb, key);
len = 1;
}
}
+
if(str_array != NULL) {
if(strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
- || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0)
- {
+ || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0) {
new_argv = (char **) realloc(argv
, sizeof(char *) * (*margc+len+2));
if(!new_argv) {
_D("euid : %d", geteuid());
_D("gid : %d", getgid());
_D("egid : %d", getegid());
+ } else if (strncmp(key, DLP_K_ATTACH_ARG, strlen(key)) == 0) {
+ new_argv = (char **) malloc((len + 2) * sizeof(char *));
+ for (i = 0; i < len; i++) {
+ new_argv[1+i] = strdup(str_array[i]);
+ }
+ *margc = 0;
+ len = len + 1;
} else {
new_argv = (char **) realloc(argv
, sizeof(char *) * (*margc+len+1));
exit(-1);
}
- if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
+ if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
} else {
str = bundle_get_val(kb, AUL_K_SDK);
- if(str) {
+ if (str) {
str_array = &str;
len = 1;
}
}
- if(str_array == NULL) {
+
+ if (str_array == NULL) {
*margc = argc;
return argv;
}
for (i = 0; i < len; i++) {
- if(str_array[i] == NULL) break;
+ if (str_array[i] == NULL)
+ break;
+
_D("index : [%d]", i);
/* gdbserver */
- if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
- {
+ if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0) {
char buf[MAX_LOCAL_BUFSZ];
- if (argv[0]) free(argv[0]);
- snprintf(buf,MAX_LOCAL_BUFSZ,"%s.exe",app_path);
+ if (argv[0])
+ free(argv[0]);
+ snprintf(buf, MAX_LOCAL_BUFSZ, "%s.exe", app_path);
// this code is added because core app don't have '.exe' excutable
// if '.exe' not exist then use app_path
- if(access(buf, F_OK) != 0)
+ if (access(buf, F_OK) != 0)
argv[0] = strdup(app_path);
else
argv[0] = strdup(buf);
+
new_argv = __add_arg(kb, argv, &argc, DLP_K_DEBUG_ARG);
new_argv[0] = strdup(PATH_GDBSERVER);
argv = new_argv;
}
/* valgrind */
- else if (strncmp(str_array[i], SDK_VALGRIND
- , strlen(str_array[i])) == 0)
- {
+ else if (strncmp(str_array[i], SDK_VALGRIND, strlen(str_array[i])) == 0) {
new_argv = __add_arg(kb, argv, &argc
, DLP_K_VALGRIND_ARG);
new_argv[0] = strdup(PATH_VALGRIND);
argv = new_argv;
}
/* unit test */
- else if (strncmp(str_array[i], SDK_UNIT_TEST
- , strlen(str_array[i])) == 0)
- {
+ else if (strncmp(str_array[i], SDK_UNIT_TEST, strlen(str_array[i])) == 0) {
new_argv = __add_arg(kb, argv, &argc
, DLP_K_UNIT_TEST_ARG);
argv = new_argv;
}
+ /* attach */
+ else if (strncmp(str_array[i], "ATTACH", strlen(str_array[i])) == 0) {
+ new_argv = __add_arg(kb, argv, &argc, DLP_K_ATTACH_ARG);
+ new_argv[0] = strdup(PATH_GDBSERVER);
+ argv = new_argv;
+ }
}
*margc = argc;
return menu_info;
}
-/**
- * free after use it
- */
-int get_native_appid(const char* app_path, char** appid) {
- int rc = smack_lgetlabel(app_path, appid, SMACK_LABEL_ACCESS);
-
- if (rc != 0 || *appid == NULL) {
- _E("smack_lgetlabel fail");
- return -1;
- }
-
- _D("get_appid return : %s", *appid);
- return 0;
-}
-
int apply_smack_rules(const char* subject, const char* object
, const char* access_type)
{
return 0;
}
-
+
if (sv == CAPABILITY_SET_INHERITABLE) {
h.pid = getpid();
if (capset(&h, inh_d) < 0) {
return 0;
}
-int __prepare_fork(bundle *kb, char *appid)
+int __prepare_fork(bundle *kb, const char *appid)
{
const char *str = NULL;
const char **str_array = NULL;
need_to_set_inh_cap_after_fork=0;
poll_outputfile = 0;
- if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
+ if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
} else {
str = bundle_get_val(kb, AUL_K_SDK);
- if(str) {
+ if (str) {
str_array = &str;
len = 1;
}
}
- if(str_array == NULL) return 0;
+
+ if (str_array == NULL)
+ return 0;
is_gdbserver_launched = 0;
gdbserver_pid = -1;
gdbserver_app_pid = -1;
for (i = 0; i < len; i++) {
- if(str_array[i] == NULL) break;
+ if (str_array[i] == NULL)
+ break;
+
/* gdbserver */
- if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
- {
+ if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0
+ || strncmp(str_array[i], "ATTACH", strlen(str_array[i])) == 0) {
// because of security issue, prevent debugging(ptrace) for preloaded app and downloaed app
- if(pkgmgrinfo_pkginfo_get_pkginfo(appid, &handle) == PMINFO_R_OK)
- {
- if(pkgmgrinfo_pkginfo_is_preload(handle, &bPreloaded) != PMINFO_R_OK)
+ if (pkgmgrinfo_pkginfo_get_pkginfo(appid, &handle) == PMINFO_R_OK) {
+ if (pkgmgrinfo_pkginfo_is_preload(handle, &bPreloaded) != PMINFO_R_OK)
return -1;
- if(pkgmgrinfo_pkginfo_get_storeclientid(handle, &storeclientid) != PMINFO_R_OK)
+ if (pkgmgrinfo_pkginfo_get_storeclientid(handle, &storeclientid) != PMINFO_R_OK)
return -1;
- if(bPreloaded || (storeclientid[0] != '\0'))
- {
+ if (bPreloaded || (storeclientid[0] != '\0')) {
_E("debugging is not allowed");
return -1;
}
}
- if(apply_smack_rules("sdbd",appid,"w")) {
+ if (apply_smack_rules("sdbd",appid,"w")) {
_E("smack_accesses_apply fail");
// return -1;
}
// fixed debug-as fail issue (grant permission to use 10.0.2.2, 10.0.2.16)
- if(apply_smack_rules(appid, "system::debugging_network", "rw")) {
+ if (apply_smack_rules(appid, "system::debugging_network", "rw")) {
_E("smack_accesses_apply fail");
}
- if(apply_smack_rules("system::debugging_network", appid, "w")) {
+
+ if (apply_smack_rules("system::debugging_network", appid, "w")) {
_E("smack_accesses_apply fail");
}
// FIXME: set gdbfolder to 755 also
- if(dlp_chmod(PATH_GDBSERVER
- , S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP
- |S_IROTH|S_IXOTH
- , 1))
- {
+ if (dlp_chmod(PATH_GDBSERVER, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, 1)) {
_D("unable to set 755 to %s", PATH_GDBSERVER);
}
+
__adjust_file_capability(PATH_GDBSERVER);
need_to_set_inh_cap_after_fork++;
is_gdbserver_launched++;
}
/* valgrind */
- else if (strncmp(str_array[i], SDK_VALGRIND
- , strlen(str_array[i])) == 0)
- {
+ else if (strncmp(str_array[i], SDK_VALGRIND, strlen(str_array[i])) == 0) {
if (__prepare_valgrind_outputfile(kb) == -1)
return -1;
+
__adjust_file_capability(PATH_MEMCHECK);
}
}
int wait_count = 0;
while(poll_outputfile && wait_count<10) {
/* valgrind log file */
- if( (poll_outputfile & POLL_VALGRIND_LOGFILE)
- && (access(PATH_VALGRIND_LOGFILE,F_OK)==0) )
- {
+ if ((poll_outputfile & POLL_VALGRIND_LOGFILE)
+ && (access(PATH_VALGRIND_LOGFILE,F_OK)==0)) {
__chmod_chsmack_toread(PATH_VALGRIND_LOGFILE);
poll_outputfile &= ~POLL_VALGRIND_LOGFILE;
}
/* valgrind xml file */
- if( (poll_outputfile & POLL_VALGRIND_XMLFILE)
- && (access(PATH_VALGRIND_XMLFILE,F_OK)==0) )
- {
+ if ((poll_outputfile & POLL_VALGRIND_XMLFILE)
+ && (access(PATH_VALGRIND_XMLFILE,F_OK)==0)) {
__chmod_chsmack_toread(PATH_VALGRIND_XMLFILE);
poll_outputfile &= ~POLL_VALGRIND_XMLFILE;
}
-
- if(poll_outputfile) {
+
+ if (poll_outputfile) {
_D("-- now wait for creating the file --");
usleep(50 * 1000); /* 50ms sleep*/
wait_count++;
}
}
- if(wait_count==10) _E("faild to waiting");
+ if (wait_count==10)
+ _E("faild to waiting");
+
return;
}
int __stdout_stderr_redirection(int defpid)
{
char defpath[UNIX_PATH_MAX];
- int deffd, result=0;
+ int deffd, result = 0;
/* stdout */
snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/1", defpid);
deffd = open(defpath,O_WRONLY);
- if(deffd < 0) {
+ if (deffd < 0) {
_E("opening caller(%d) stdout failed due to %s"
, defpid, strerror(errno));
result++;
- }else{
+ } else {
dup2(deffd, 1);
close(deffd);
}
/* stderr */
snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/2", defpid);
deffd = open(defpath,O_WRONLY);
- if(deffd < 0) {
+ if (deffd < 0) {
_E("opening caller(%d) stderr failed due to %s"
, defpid,strerror(errno));
result+=2;
- }else{
+ } else {
dup2(deffd, 2);
close(deffd);
}
int is_real_launch = 0;
char sock_path[UNIX_PATH_MAX] = {0,};
- char * appid = NULL;
pkt = __app_recv_raw(main_fd, &clifd, &cr);
if (!pkt) {
goto end;
}
if (app_path[0] != '/') {
- _D("app_path is not absolute path");
+ _D("app_path is not absolute path", app_path);
goto end;
}
- {
- int rc = get_native_appid(app_path,&appid);
- if(rc!=0 || appid==NULL) {
- _E("unable to get native appid");
- if(appid){
- free(appid);
- appid = NULL;
- }
- goto end;
- }
- }
+ debuggee_appid = bundle_get_val(kb, AUL_K_PKGID);
__modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
pkg_name = _get_pkgname(menu_info);
PERF("get package information & modify bundle done");
- if(__prepare_fork(kb,appid) == -1) goto end;
+ if (__prepare_fork(kb, debuggee_appid) == -1)
+ goto end;
pid = fork();
if (pid == 0) {
exit(-1);
}
- if(is_gdbserver_launched) {
- char buf[MAX_LOCAL_BUFSZ];
-
+ if (is_gdbserver_launched) {
usleep(100 * 1000); /* 100ms sleep */
- snprintf(buf, MAX_LOCAL_BUFSZ, "%s.exe", app_path);
- gdbserver_app_pid = __proc_iter_cmdline(NULL, buf);
- if(gdbserver_app_pid == -1) {
+ gdbserver_app_pid = __proc_iter_cmdline(NULL, (void *)app_path);
+
+ if (gdbserver_app_pid == -1) {
_E("faild to get app pid");
} else {
gdbserver_pid = pid;
_D("==> real launch pid : %d %s\n", pid, app_path);
is_real_launch = 1;
- end:
+end:
__send_result_to_caller(clifd, pid);
if (pid > 0) {
bundle_free(kb);
if (pkt != NULL)
free(pkt);
- if (appid != NULL)
- free(appid);
/* Active Flusing for Daemon */
if (initialized > AUL_POLL_CNT) {
if(poll_outputfile) __waiting_outputfile();
}
+#ifdef _APPFW_FEATURE_SOCKET_ACTIVATION
+_static_ int __create_sock_activation(void)
+{
+ int fd = -1;
+ int listen_fds;
+
+ listen_fds = sd_listen_fds(0);
+ if (listen_fds == 1) {
+ fd = SD_LISTEN_FDS_START + 0;
+ return fd;
+ } else if (listen_fds > 1) {
+ _E("Too many fild descriptors received.");
+ return -1;
+ } else {
+ _E("There is no socket stream");
+ return -1;
+ }
+}
+#endif
+
int __launchpad_pre_init(int argc, char **argv)
{
int fd;
}
_D("launchpad cmdline = %s", launchpad_cmdline);
+#ifdef _APPFW_FEATURE_SOCKET_ACTIVATION
/* create launchpad sock */
- fd = __create_server_sock(DEBUG_LAUNCHPAD_PID);
+ fd = __create_sock_activation();
if (fd < 0) {
- _E("server sock error");
- return -1;
+ _D("Create server socket without socket activation");
+#endif
+ fd = __create_server_sock(DEBUG_LAUNCHPAD_PID);
+ if (fd < 0) {
+ _E("server sock error");
+ return -1;
+ }
+#ifdef _APPFW_FEATURE_SOCKET_ACTIVATION
}
+#endif
__preload_init(argc, argv);
int __launchpad_post_init()
{
- /* Setting this as a global variable to keep track
+ /* Setting this as a global variable to keep track
of launchpad poll cnt */
/* static int initialized = 0;*/
if (poll(pfds, POLLFD_MAX, -1) < 0)
continue;
- /* init with concerning X & EFL (because of booting
+ /* init with concerning X & EFL (because of booting
sequence problem)*/
if (__launchpad_post_init() < 0) {
_E("launcpad post init failed");