[Title] apply runtime config and new protocol
authorgreatim <jaewon81.lim@samsung.com>
Wed, 10 Apr 2013 11:00:29 +0000 (20:00 +0900)
committergreatim <jaewon81.lim@samsung.com>
Wed, 10 Apr 2013 11:01:18 +0000 (20:01 +0900)
[Desc.]
[Issue]

Change-Id: I898f630aaa4494647ce5fa7dd73e2cba0b7e3c69

12 files changed:
daemon/Makefile
daemon/da_daemon.c [deleted file]
daemon/da_debug.c [moved from daemon/da_debug.h with 60% similarity]
daemon/daemon.c [new file with mode: 0644]
daemon/daemon.h [new file with mode: 0644]
daemon/main.c [new file with mode: 0644]
daemon/sys_stat.c
daemon/sys_stat.h
daemon/threads.c [new file with mode: 0644]
daemon/utils.c
daemon/utils.h
packaging/dynamic-analysis-manager.spec

index d08072e..c5889ca 100644 (file)
@@ -21,8 +21,11 @@ INC :=       -I/usr/include  \
                -I/usr/include/vconf
 
 DAEMON_SRCS := \
-       da_daemon.c     \
-       utils.c \
+       main.c          \
+       daemon.c        \
+       threads.c       \
+       da_debug.c      \
+       utils.c         \
        sys_stat.c
 
 LDLIBS_PATH := -L/usr/lib -L./lib/
@@ -38,7 +41,6 @@ LIBS_TIZEN :=# -lcapi-system-runtime-info \
                                -lSLP-db-util
 LIBS_COMMON := -lglib-2.0 \
                                -lvconf \
-                               -laul \
                                -lcapi-system-info
 
 DEBUG_ON := -DDEBUG=1
diff --git a/daemon/da_daemon.c b/daemon/da_daemon.c
deleted file mode 100644 (file)
index 10f6e89..0000000
+++ /dev/null
@@ -1,1670 +0,0 @@
-/*
-*  DA manager
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-*
-* Jaewon Lim <jaewon81.lim@samsung.com>
-* Woojin Jung <woojin2.jung@samsung.com>
-* Juyoung Kim <j0.kim@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.
-*
-* Contributors:
-* - S-Core Co., Ltd
-*
-*/ 
-
-#include <stdio.h>
-#include <stdlib.h>            // for realpath
-#include <string.h>            // for strtok, strcpy, strncpy
-#include <assert.h>            // for assert
-#include <limits.h>            // for realpath
-
-#define __USE_GNU
-#include <sys/types.h> // for socket, mkdir, opendir, readdir
-#include <sys/socket.h>        // for socket
-#include <sys/un.h>            // for sockaddr_un
-#include <arpa/inet.h> // for sockaddr_in, socklen_t
-#include <sys/stat.h>  // for chmod, mkdir
-#include <sys/time.h>  // for setitimer
-#include <signal.h>            // for sigemptyset, sigset_t, sigaddset, ...
-#include <unistd.h>            // for unlink
-#include <pthread.h>   // for pthread_mutex_t
-#include <sys/epoll.h> // for epoll apis
-#include <sys/ipc.h>   // for shmctl
-#include <sys/shm.h>   // for shared memory operation
-#include <dirent.h>            // for opendir, readdir
-
-#include "utils.h"
-#include "sys_stat.h"
-#include "da_debug.h"
-
-#define MAX_PATH_LENGTH                                256
-#define TARGET_CLIENT_COUNT_MAX                8
-#define READ_BUF_MAX                           4096+8
-#define DA_LOG_MAX                                     4096
-#define APP_INSTALL_PATH_MAX           1024
-#define UDS_NAME                                       "/tmp/da.socket"
-#define DA_INSTALL_DIR                         "/home/developer/sdk_tools/da/"
-#define DA_INSTALL_PATH                                "/home/developer/sdk_tools/da/da_install_path"
-#define DA_BUILD_OPTION                                "/home/developer/sdk_tools/da/da_build_option"
-#define DA_BASE_ADDRESS                                "/home/developer/sdk_tools/da/da_base_address"
-#define DA_READELF_PATH                                "/home/developer/sdk_tools/da/readelf"
-#define SCREENSHOT_DIR                         "/tmp/da"
-#define HOST_MSG_LENGTH                        3
-#define SHAREDMEMKEY                           ((key_t)463825)
-
-#define TIMER_INTERVAL_SEC                     1
-#define TIMER_INTERVAL_USEC                    0
-
-#define SECOND_INTERVAL
-#define MONITORING_INTERVAL                    1       // 1 second
-
-#ifdef SECOND_INTERVAL
-#define __sleep                sleep
-#else
-#define __sleep                usleep
-#endif
-
-#define RUN_APP_LOADER                         1
-
-enum TargetMessageType
-{
-       MSG_DEVICE = 1,
-       MSG_TIME = 2,
-       MSG_SAMPLE = 3,
-       MSG_RESOURCE = 4,
-       MSG_LOG = 5,
-       MSG_IMAGE = 6,
-       MSG_TERMINATE = 7,
-       MSG_PID = 8,
-       MSG_MSG = 9,
-       MSG_APPNAME = 10,
-       MSG_ERROR = 11
-};
-
-enum HostMessageType
-{
-       MSG_HOST_BEGIN = 100,
-       MSG_START = 100,
-       MSG_STOP = 101,
-       MSG_PAUSE = 102,
-       MSG_OPTION = 103,
-       MSG_ISALIVE = 104,
-       MSG_ALIVE = 105,
-       MSG_BATT_START = 106,
-       MSG_BATT_STOP = 107,
-       MSG_HOST_END = 107
-};
-
-enum DAState
-{
-       DAS_NONE = 0,
-       DAS_START_BEGIN = 1,
-       DAS_TARGET_ARM_START = 1,
-       DAS_TARGET_X86_START = 2,
-       DAS_EMUL_ARM_START = 3,
-       DAS_EMUL_X86_START = 4,
-       DAS_TARGET_ARM_BATT_START = 5,
-       DAS_TARGET_X86_BATT_START = 6,
-       DAS_EMUL_ARM_BATT_START = 7,
-       DAS_EMUL_X86_BATT_START = 8,
-       DAS_START_END = 8,
-       DAS_STOP = 9,
-       DAS_TERMINATE = 10
-};
-
-typedef struct
-{
-       int type;
-       int length;
-       char data[DA_LOG_MAX];
-} log_t;
-
-//TODO :
-typedef struct
-{
-       enum DAState status;
-       int serverSockFD;
-       int clientSockFD;
-} __daHostInfo;
-
-typedef struct
-{
-       enum DAState status;
-       int serverSockFD;
-       int connectCount;
-       int pidCount;
-       int clientSockFD[TARGET_CLIENT_COUNT_MAX];
-       int execPID[TARGET_CLIENT_COUNT_MAX];   // exec PID by target
-} __daTargetInfo;
-
-typedef struct
-{
-       long long allocsize;
-       long launch_flag;
-} __daSharedInfo;
-
-typedef struct
-{
-       int memid;
-       __daSharedInfo* pvalue;
-} __daSharedMem;
-
-typedef struct
-{
-       pthread_t timer_thread;
-       pthread_mutex_t sendMutex;
-       char appPath[128];                                      // application executable path
-       __daSharedMem sharedmem;
-       __daHostInfo iHost;
-       __daTargetInfo iTarget;
-}__daManager;
-
-__daManager manager =
-{
-       -1,                                                                     // timer_thread handle
-       PTHREAD_MUTEX_INITIALIZER,                      // pthread_mutex_t sendMutex
-       { 0, },                                                         // char appPath[128]
-       { -1, (void*)-1 },                                      // __daSharedMem sharedmem
-       { DAS_NONE, -1, -1 },                           // __daHostInfo iHost
-       { DAS_NONE, -1, 0, 0, {0, }, {0, }}     // __daTargetInfo iTarget
-};
-
-int aul_terminate_pid(int pid);
-static void* terminate_thread(void* data);
-static void terminate_error(char* errstr, int sendtohost);
-
-#ifdef LOCALTEST
-int aul_terminate_pid(int pid)
-{
-       return kill(pid, SIGTERM);
-}
-#endif
-
-int _terminate_pid(int pid)
-{
-       int ret;
-       pid_t* pids;
-       pthread_t term_thread;
-
-       ret = aul_terminate_pid(pid);
-
-       pids = (pid_t*)malloc(2 * sizeof(pid_t));
-       pids[0] = pid;
-       pids[1] = -2;
-
-       pthread_create(&term_thread, NULL, terminate_thread, pids);
-
-       return ret;
-}
-
-// return 0 if succeed
-// return -1 if error occured
-static int remove_indir(const char *dirname)
-{
-       DIR *dir;
-       struct dirent *entry;
-       char path[MAX_PATH_LENGTH];
-
-       dir = opendir(dirname);
-       if(dir == NULL)
-       {
-               return -1;
-       }
-
-       while((entry = readdir(dir)) != NULL)
-       {
-               if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
-               {
-                       snprintf(path, (size_t) MAX_PATH_LENGTH, "%s/%s", dirname, entry->d_name);
-                       if (entry->d_type != DT_DIR)    // file
-                       {
-                               unlink(path);
-                       }
-                       else { }        // directory
-               }
-       }
-       closedir(dir);
-
-       return 0;
-}
-
-// index is started from 0
-int set_launch_flag(int index, int bOn)
-{
-       int ret = 0;
-       // set launch flag before execute application
-       if(__builtin_expect(manager.sharedmem.pvalue != (void*)-1, 1))
-       {
-               if(bOn != 0)
-                       manager.sharedmem.pvalue->launch_flag |= (1 << index);
-               else
-                       manager.sharedmem.pvalue->launch_flag &= ~(1 << index);
-       }
-       else 
-               ret = -1;
-
-       return ret;
-}
-
-long long get_total_alloc_size()
-{
-       if(__builtin_expect(manager.sharedmem.pvalue != (void*)-1, 1))
-       {
-               return manager.sharedmem.pvalue->allocsize;
-       }
-       else
-       {
-               return 0L;
-       }
-}
-
-// return 0 for normal case
-static int __makeTargetServerSockFD()
-{
-       struct sockaddr_un serverAddrUn;
-
-       if(manager.iTarget.serverSockFD != -1)
-               return -1;      // should be never happend
-
-       // remove pre unix domain socket file
-       // remove(UDS_NAME);
-       unlink(UDS_NAME);
-
-       if ((manager.iTarget.serverSockFD = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-       {
-               LOGE("Target server socket creation failed\n");
-               return -1;
-       }
-       bzero(&serverAddrUn, sizeof(serverAddrUn));
-       serverAddrUn.sun_family = AF_UNIX;
-       sprintf(serverAddrUn.sun_path, "%s", UDS_NAME);
-
-       if (-1 == bind(manager.iTarget.serverSockFD, (struct sockaddr*) &serverAddrUn,
-                                       sizeof(serverAddrUn)))
-       {
-               LOGE("Target server socket binding failed\n");
-               close(manager.iTarget.serverSockFD);
-               return -1;
-       }
-
-       chmod(serverAddrUn.sun_path, 0777);
-
-       if (-1 == listen(manager.iTarget.serverSockFD, 5))
-       {
-               LOGE("Target server socket listening failed\n");
-               close(manager.iTarget.serverSockFD);
-               return -1;
-       }
-
-       LOGI("Created TargetSock %d\n", manager.iTarget.serverSockFD);
-       return 0;
-}
-
-// return 0 for normal case
-static int __makeHostServerSockFD()
-{
-       struct sockaddr_in serverAddrIn;
-       int opt = 1;
-
-       if(manager.iHost.serverSockFD != -1)
-               return -1;      // should be never happened
-
-       if ((manager.iHost.serverSockFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
-       {
-               LOGE("Host server socket creation failed\n");
-               return -1;
-       }
-
-       setsockopt(manager.iHost.serverSockFD, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
-       memset(&serverAddrIn, 0, sizeof(serverAddrIn));
-       serverAddrIn.sin_family = AF_INET;
-       serverAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
-       serverAddrIn.sin_port = htons(8001);
-
-       // bind address to server socket
-       if (-1 == bind(manager.iHost.serverSockFD, (struct sockaddr*) &serverAddrIn, sizeof(serverAddrIn)))
-       {
-               LOGE("Host server socket binding failed\n");
-               close(manager.iHost.serverSockFD);
-               return -1;
-       }
-
-       // enter listen state from client
-       if (-1 == listen(manager.iHost.serverSockFD, 5))
-       {
-               LOGE("Host server socket listening failed\n");
-               close(manager.iHost.serverSockFD);
-               return -1;
-       }
-
-       LOGI("Created HostSock %d\n", manager.iHost.serverSockFD);
-       return 0;
-}
-
-static int __destroySharedMemory()
-{
-       int ret = 0;
-       if(manager.sharedmem.pvalue != (void*)-1)
-       {
-               ret = shmdt(manager.sharedmem.pvalue);
-               if(ret == 0)
-                       manager.sharedmem.pvalue = (void*)-1;
-       }
-
-       if(manager.sharedmem.memid != -1)
-       {
-               ret = shmctl(manager.sharedmem.memid, IPC_RMID, 0);
-               if(ret == 0)
-                       manager.sharedmem.memid = -1;
-       }
-
-       return ret;
-}
-
-// return 0 for normal case
-// return -1 for error case
-static int __createSharedMemory()
-{
-       manager.sharedmem.memid = shmget(SHAREDMEMKEY, sizeof(__daSharedInfo), IPC_CREAT | 0666);
-       if(manager.sharedmem.memid == -1)
-       {
-               return -1;
-       }
-       else
-       {
-               manager.sharedmem.pvalue = (__daSharedInfo*)shmat(manager.sharedmem.memid, NULL, 0);
-               if(manager.sharedmem.pvalue == (void*)-1)
-               {
-                       __destroySharedMemory();
-                       return -1;
-               }
-               else
-               {
-                       manager.sharedmem.pvalue->allocsize = 0;
-                       manager.sharedmem.pvalue->launch_flag = 0;
-                       return 0;
-               }
-       }
-}
-
-/*
-static log_t * parsLogData(log_t * log, char* logStr)
-{
-#if 1
-       int i, nPos;
-
-       if (logStr == NULL || log == NULL)
-               return NULL;
-
-       //msgType
-       for (i = 0, nPos = 0; i < READ_BUF_MAX; i++)
-       {
-               if (logStr[i] == '|')
-               {
-                       logStr[i] = '\0';
-                       log->type = atoi(&logStr[nPos]);
-                       i++;
-                       break;
-               }
-               if (logStr[i] == '\0')
-                       return NULL;
-       }
-       //length
-       for (nPos = i; i < READ_BUF_MAX; i++)
-       {
-               if (logStr[i] == '|' || logStr[i] == '\0')
-               {
-                       logStr[i] = '\0';
-                       log->length = atoi(&logStr[nPos]);
-                       i++;
-                       break;
-               }
-       }
-       //data
-       if ((log->length > 0) && (log->length < DA_LOG_MAX))
-       {
-               strncpy(log->data, &logStr[i], log->length);
-               log->data[log->length] = '\0';
-       }
-
-       return log;
-
-#else
-
-       int i;
-       char * startPos = logStr;
-       char tempBuf[READ_BUF_MAX];
-
-       if(logStr && log)
-       {
-               log->type = -1;
-               log->length = 0;
-               log->data[0]='\0';
-               //type,length
-               for(i=0; i<READ_BUF_MAX; i++)
-               {
-                       if(logStr[i]=='|')
-                       {
-                               logStr[i]='\0';
-                               if(log->type == -1)
-                               {
-                                       log->type = atoi(startPos);
-                                       startPos = &logStr[i+1];
-                               }
-                               else {
-                                       log->length = atoi(startPos);
-                                       startPos = &logStr[i+1];
-                                       break;
-                               }
-                       }
-               }
-               //data
-               if((log->length > 0) && (log->length < DA_LOG_MAX) && (startPos))
-               {
-                       strncpy(log->data, startPos, log->length);
-                       log->data[log->length] = '\0';
-               }
-               LOGI("log type : %d, length : %d, data : %s\n", log->type, log->length, log->data);
-               return log;
-       }
-       else
-       return NULL;
-#endif
-}
-*/
-
-static int get_app_type(void)
-{
-       int fd;
-       char buf[DA_LOG_MAX];
-
-       sprintf(buf, "%s.exe", manager.appPath);
-       fd = open(buf, O_RDONLY);
-       if(fd != -1)
-       {
-               close(fd);
-               return APP_TYPE_OSP;
-       }
-       else
-       {
-               return APP_TYPE_TIZEN;
-       }
-}
-
-static int get_executable(char* buf, int buflen)
-{
-       int fd;
-
-       sprintf(buf, "%s.exe", manager.appPath);
-       fd = open(buf, O_RDONLY);
-       if(fd != -1)
-       {
-               close(fd);
-       }
-       else
-       {
-               strcpy(buf, manager.appPath);
-       }
-       return 0;
-}
-
-static int get_app_install_path(char *strAppInstall, int length)
-{
-       FILE *fp;
-       char buf[DA_LOG_MAX];
-       char *p;
-       int i;
-
-       if ((fp = fopen(DA_INSTALL_PATH, "r")) == NULL)
-       {
-               LOGE("Failed to open %s\n", DA_INSTALL_PATH);
-               return -1;
-       }
-
-       /*ex : <15>   DW_AT_comp_dir    : (indirect string, offset: 0x25f): /home/yt/workspace/templatetest/Debug-Tizen-Emulator        */
-       while (fgets(buf, DA_LOG_MAX, fp) != NULL)
-       {
-               //name
-               p = buf;
-               for (i = 0; i < DA_LOG_MAX; i++)
-               {
-                       if (*p == ':')
-                               break;
-                       p++;
-               }
-
-               if (*p != ':')
-                       break;
-               else
-                       p++;
-
-               //(...,offset:...)
-               for (; i < DA_LOG_MAX; i++)
-               {
-                       if (*p == '(')
-                       {
-                               while (*p != ')')
-                               {
-                                       p++;
-                               }
-                       }
-                       if (*p == ':')
-                               break;
-                       p++;
-               }
-
-               //find
-               if (*p != ':')
-                       break;
-               for (; i < DA_LOG_MAX; i++)
-               {
-                       if (*p == ':' || *p == ' ' || *p == '\t')
-                               p++;
-                       else
-                               break;
-               }
-
-               //name
-               if (strlen(p) <= length)
-               {
-                       sprintf(strAppInstall, "%s", p);
-                       for (i = 0; i < strlen(p); i++)
-                       {
-                               if (strAppInstall[i] == '\n' || strAppInstall[i] == '\t')
-                               {
-                                       strAppInstall[i] = '\0';
-                                       break;
-                               }
-                       }
-                       fclose(fp);
-                       return 1;
-               }
-       }
-       fclose(fp);
-       return -1;
-}
-
-static int is_app_built_pie(void)
-{
-       int result;
-       FILE *fp;
-       char buf[DA_LOG_MAX];
-
-       if((fp = fopen(DA_BUILD_OPTION, "r")) == NULL)
-       {
-               LOGE("Failed to open %s\n", DA_BUILD_OPTION);
-               return -1;
-       }
-
-       if(fgets(buf, DA_LOG_MAX, fp) != NULL)
-       {
-               if(strcmp(buf, "DYN\n") == 0)
-                       result = 1;
-               else if(strcmp(buf, "EXEC\n") == 0)
-                       result = 0;
-               else
-                       result = -1;
-       }
-       else
-       {
-               result = -1;
-       }
-       fclose(fp);
-
-       return result;
-}
-
-static int get_app_base_address(int *baseAddress)
-{
-       int res;
-       FILE *fp;
-       char buf[DA_LOG_MAX];
-
-       if((fp = fopen(DA_BASE_ADDRESS, "r")) == NULL)
-       {
-               LOGE("Failed to open %s\n", DA_BASE_ADDRESS);
-               return -1;
-       }
-
-       if(fgets(buf, DA_LOG_MAX, fp) != NULL)
-       {
-               res = sscanf(buf, "%x", baseAddress);
-       }
-       else
-       {
-               res = -1;
-       }
-       fclose(fp);
-
-       return res;
-}
-
-static int is_same_app_process(int pid)
-{
-       int ret = 0;
-       FILE *fp;
-       char buf[DA_LOG_MAX];
-       char cmdPath[PATH_MAX];
-       char execPath[PATH_MAX];
-
-       get_executable(execPath, PATH_MAX);
-       sprintf(cmdPath, "/proc/%d/cmdline", pid);
-
-       if((fp = fopen(cmdPath, "r")) == NULL)
-       {
-               return 0;
-       }
-
-       if(fgets(buf, DA_LOG_MAX, fp) != NULL)
-       {
-#if RUN_APP_LOADER
-               if(strcmp(buf, manager.appPath) == 0)
-#else
-               // use execPath instead of manager.appPath 
-               if(strcmp(buf, execPath) == 0)
-#endif
-                       ret = 1;
-               else
-                       ret = 0;
-       }
-       fclose(fp);
-
-       return ret;
-}
-
-static int sendMsgStrToHost(char* str, int msgType, int targetNo)
-{
-       static int initialized = 0;
-       int pid;
-       int is_pie_build;
-       int base_address;
-       int app_type;
-       char log[DA_LOG_MAX];
-       char bufDeviceInfo[DA_LOG_MAX];
-       char bufAppInstall[APP_INSTALL_PATH_MAX];
-
-       switch (msgType)
-       {
-       case MSG_LOG:
-       case MSG_RESOURCE:
-       case MSG_SAMPLE:
-       case MSG_ERROR:
-               if(__builtin_expect(initialized == 0, 0))
-                       return -1;
-               sprintf(log, "%d|%s\n", msgType, str);
-               break;
-       case MSG_PID:
-               LOGI("MSG_PID handling : %s\n", str);
-               pid = atoi(str);
-               if ((manager.iTarget.execPID[targetNo] != -1) && (pid != manager.iTarget.execPID[targetNo]))
-               {
-                       LOGE("Failed to check pid, pid of msg(%d), stored pid(%d)\n", pid, manager.iTarget.execPID[targetNo]);
-                       return -1;
-               }
-               LOGI("pid[%d]=%d\n",targetNo,pid);
-               manager.iTarget.execPID[targetNo] = pid;
-               manager.iTarget.pidCount++;
-
-               {
-                       char execPath[PATH_MAX];
-                       char realPath[PATH_MAX];
-                       char mapsPath[PATH_MAX];
-                       char appInstallCommand[PATH_MAX];
-
-                       get_executable(execPath, PATH_MAX);
-                       if(realpath(execPath, realPath) == NULL)
-                       {
-                               LOGW("Failed to get realpath of app\n");
-                               strcpy(realPath, execPath);
-                       }
-
-                       sprintf(mapsPath, "/proc/%d/maps", manager.iTarget.execPID[targetNo]);
-                       sprintf(appInstallCommand,
-                                       "cat %s | grep %s | cut -d\"-\" -f1 > %s", mapsPath,
-                                       realPath, DA_BASE_ADDRESS);
-                       LOGI("appInstallCommand is %s\n", appInstallCommand);
-
-                       do {
-                               if(access(mapsPath, F_OK) != 0)
-                                       return -1;
-                               if(is_same_app_process(manager.iTarget.execPID[targetNo]) == 0)
-                                       return -1;
-
-                               system(appInstallCommand);
-                               if(get_app_base_address(&base_address) == 1)
-                                       break;
-                               sleep(0);
-                       }
-                       while(1);
-               }
-               return 0;
-               break;
-       case MSG_TIME:
-               LOGI("MSG_TIME handling : %s\n", str);
-               if (strlen(manager.appPath) > 0)
-               {
-                       is_pie_build = is_app_built_pie();
-                       get_app_base_address(&base_address);
-                       app_type = get_app_type();
-                       bufAppInstall[0] = '\0';
-                       get_app_install_path(bufAppInstall, APP_INSTALL_PATH_MAX);
-                       get_device_info(bufDeviceInfo, DA_LOG_MAX);
-                       if (strlen(bufAppInstall) > 0)
-                       {
-                               char buf[PATH_MAX];
-                               get_executable(buf, PATH_MAX);
-                               sprintf(log, "%d|%s`,%d`,%s`,%d`,%u`,%d`,%s/%s\n", MSG_DEVICE, bufDeviceInfo,
-                                               manager.iTarget.execPID[targetNo], str, is_pie_build, base_address, app_type,
-                                               bufAppInstall, get_app_name(buf));
-                       }
-                       else
-                               sprintf(log, "%d|%s`,%d`,%s`,%d`,%u`,%d`,\n", MSG_DEVICE, bufDeviceInfo,
-                                               manager.iTarget.execPID[targetNo], str, is_pie_build, base_address, app_type);
-                       LOGI("MSG_DEVICE msg : %s\n", log);
-               }
-               else
-               {
-                       sprintf(log, "%d|%d`,%s", MSG_PID, manager.iTarget.execPID[targetNo], str);
-                       LOGI("MSG_DEVICE msg without appname : %s\n", log);
-               }
-               initialized = 1;
-               break;
-       case MSG_TERMINATE:
-               LOGI("MSG_TERMINATE handling : connectCount(%d)\n", manager.iTarget.connectCount);
-               if(manager.iTarget.connectCount == 1 ){
-                       sprintf(log, "%d|\n", msgType);
-                       pthread_mutex_lock(&(manager.sendMutex));
-#ifndef LOCALTEST                      
-                       send(manager.iHost.clientSockFD, log, strlen(log), 0);
-#else
-                       LOGI("send to host : %s\n", log);
-#endif
-                       pthread_mutex_unlock(&(manager.sendMutex));
-               }
-               return 0;
-       default:
-               sprintf(log, "%d|%s\n", msgType, str);
-               break;
-       }
-
-       if(manager.iHost.status >= DAS_TARGET_ARM_BATT_START && manager.iHost.status <= DAS_EMUL_X86_BATT_START)
-       {
-               LOGI("write batt log\n");
-               write_batt_log(log);
-       }
-       else
-       {
-               if (manager.iHost.clientSockFD != -1)
-               {
-                       pthread_mutex_lock(&(manager.sendMutex));
-#ifndef LOCALTEST
-                       send(manager.iHost.clientSockFD, log, strlen(log), 0);
-#else
-                       LOGI("send to host : %s\n", log);
-#endif
-                       pthread_mutex_unlock(&(manager.sendMutex));
-               }
-       }
-       return 0;
-}
-
-static void* timerThread(void* data)
-{
-       int err, signo;
-       char buf[DA_LOG_MAX];
-       sigset_t waitsigmask;
-
-       LOGI("Timer thread started\n");
-
-       sigemptyset(&waitsigmask);
-       sigaddset(&waitsigmask, SIGALRM);
-       sigaddset(&waitsigmask, SIGUSR1);
-
-       while(1)
-       {
-               err = sigwait(&waitsigmask, &signo);
-               if(err != 0)
-               {
-                       LOGE("Failed to sigwait() in timer thread\n");
-                       continue;
-               }
-               
-               if(signo == SIGALRM)
-               {       
-                       get_resource_info(buf, DA_LOG_MAX, manager.iTarget.execPID, manager.iTarget.pidCount);
-                       sendMsgStrToHost(buf, MSG_RESOURCE, -1);
-
-                       if (manager.iTarget.status < DAS_START_BEGIN || manager.iTarget.status > DAS_START_END )
-                               break;
-               }
-               else if(signo == SIGUSR1)
-               {
-                       // end this thread
-                       break;
-               }
-               else
-               {
-                       // not happened
-                       LOGE("This should not be happend in timer thread\n");
-               }
-       }
-
-       LOGI("Timer thread ended\n");
-       return NULL;
-}
-
-// return 0 if normal case
-// return minus value if critical error
-// return plus value if non-critical error
-static int timerStart()
-{
-       sigset_t newsigmask;
-       struct itimerval timerval;
-//     char buf[DA_LOG_MAX];
-
-       if(manager.timer_thread != -1)  // already started
-               return 1;
-
-       sigemptyset(&newsigmask);
-       sigaddset(&newsigmask, SIGALRM);
-       sigaddset(&newsigmask, SIGUSR1);
-       if(pthread_sigmask(SIG_BLOCK, &newsigmask, NULL) != 0)
-       {
-               LOGE("Failed to signal masking for main thread\n");
-               return -1;
-       }
-
-       if(pthread_create(&(manager.timer_thread), NULL, timerThread, NULL) < 0)
-       {
-               LOGE("Failed to create timer thread\n");
-               return -1;
-       }
-
-       timerval.it_interval.tv_sec = TIMER_INTERVAL_SEC;
-       timerval.it_interval.tv_usec = TIMER_INTERVAL_USEC;
-       timerval.it_value.tv_sec = TIMER_INTERVAL_SEC;
-       timerval.it_value.tv_usec = TIMER_INTERVAL_USEC;
-       setitimer(ITIMER_REAL, &timerval, NULL);
-
-       // commected because this resource log send to host before receiving MSG_TIME message from target process
-       // send initial value of profiling
-//     get_resource_info(buf, DA_LOG_MAX, manager.iTarget.execPID, manager.iTarget.pidCount);
-//     sendMsgStrToHost(buf, MSG_RESOURCE, -1);
-
-       return 0;
-}
-
-static int timerStop()
-{
-       if(manager.timer_thread != -1)
-       {
-//             int status;
-//             sigset_t oldsigmask;
-               struct itimerval stopval;
-
-//             sigemptyset(&oldsigmask);
-//             sigaddset(&oldsigmask, SIGALRM);
-//             sigaddset(&oldsigmask, SIGUSR1);
-
-               stopval.it_interval.tv_sec = 0;
-               stopval.it_interval.tv_usec = 0;
-               stopval.it_value.tv_sec = 0;
-               stopval.it_value.tv_usec = 0;
-
-               // stop timer
-               setitimer(ITIMER_REAL, &stopval, NULL);
-
-               pthread_kill(manager.timer_thread, SIGUSR1);
-//             pthread_join(manager.timer_thread, (void**) &status);
-
-//             if(sigprocmask(SIG_UNBLOCK, &oldsigmask, NULL) < 0)
-//             {
-//                     LOGE("Failed to pthread_sigmask\n");
-//             }
-               manager.timer_thread = -1;
-       }
-       __destroySharedMemory();
-
-       return 0;
-}
-
-#ifdef USE_BATT_LOG
-static void wait_for_starting()
-{
-       static int chargerfd = -1;
-       while (get_file_status(&chargerfd, CHARGERFD))
-       {
-               LOGI("wait for starting ... \n");
-               __sleep(MONITORING_INTERVAL);
-       }
-}
-#endif
-
-static int startProfiling(char* execpath, enum DAState status, long launchflag)
-{
-       if(__createSharedMemory() < 0)
-       {
-               LOGE("Failed to create shared memory\n");
-               return -1;
-       }
-
-       // set launch flag before execute application
-       manager.sharedmem.pvalue->launch_flag = launchflag;
-
-       // remove previous screen capture files
-       remove_indir(SCREENSHOT_DIR);
-       mkdir(SCREENSHOT_DIR, 0777);
-
-       // execute application
-       if (exec_app(execpath, get_app_type()))
-       {
-               manager.iTarget.status = status;
-               if(timerStart() < 0)
-               {
-                       return -1;
-               }
-               LOGI("Timer Started\n");
-       }
-       else
-       {
-               return -1;
-       }
-
-       return 0;
-}
-
-static void* terminate_thread(void* data)
-{
-       int i;
-       FILE* fp;
-       size_t readbyte;
-       char cmd[MAX_PATH_LENGTH];
-       pid_t* pids = (pid_t*)data;
-
-       sleep(1);
-       for(i = 0; pids[i] != -2; i++)
-       {
-               if(pids[i] != -1)
-               {
-                       sprintf(cmd, "ps ax | grep %d | grep -v grep", pids[i]);
-                       fp = popen(cmd, "r");
-                       if(fp)
-                       {
-                               readbyte = fread(cmd, MAX_PATH_LENGTH - 1, 1, fp);
-                               if(readbyte > 0)        // process is still alive
-                               {
-                                       sprintf(cmd, "kill -9 %d", pids[i]);
-                                       system(cmd);
-                               }
-                               pclose(fp);
-                       }
-               }
-       }
-
-       free(pids);
-
-       return NULL;
-}
-
-static void terminate_all_target()
-{
-       int i;
-       pthread_t term_thread;
-       pid_t* pids;
-
-       pids = (pid_t*)malloc((manager.iTarget.pidCount + 1) * sizeof(pid_t));
-
-       for (i = 0; i < manager.iTarget.pidCount; i++)
-       {
-               pids[i] = manager.iTarget.execPID[i];
-               if(manager.iTarget.execPID[i] != -1)
-               {
-                       LOGI("TERMINATE  process(%d) by terminate_all_target()\n", manager.iTarget.execPID[i]);
-                       aul_terminate_pid(manager.iTarget.execPID[i]);
-                       manager.iTarget.execPID[i] = -1;
-               }
-       }
-       pids[manager.iTarget.pidCount] = -2;
-
-       pthread_create(&term_thread, NULL, terminate_thread, pids);
-
-       manager.iTarget.pidCount = 0;
-}
-
-static void terminate_error(char* errstr, int sendtohost)
-{
-       LOGE("%s, status(%d)\n", errstr, manager.iHost.status);
-       manager.iHost.status = DAS_STOP;
-
-       terminate_all_target();
-
-       timerStop();
-
-       if(sendtohost)
-               sendMsgStrToHost(errstr, MSG_ERROR, -1);
-}
-
-
-// return 0 if normal case
-// return plus value if non critical error occur
-// return minus value if critical error occur
-static int hostMessageHandler(log_t * log)
-{
-       int ret = 0;
-       long flag = 0;
-       char *barloc, *tmploc;
-       char execPath[PATH_MAX];
-
-       if (log == NULL)
-               return 1;
-
-       switch (log->type)
-       {
-       case MSG_START:
-               LOGI("MSG_START handling : %s\n", log->data);
-               if (manager.iHost.status >= DAS_START_BEGIN     && manager.iHost.status <= DAS_START_END)
-               {
-                       LOGE("MSG_START status check : %d\n", manager.iHost.status);
-                       return 1;               // already started, then ignore this MSG_START message
-               }
-
-               if(log->length == 0)
-                       return -1;              // wrong message format
-
-               // parsing for host start status
-               tmploc  = log->data;
-               barloc = strchr(tmploc, '|');
-               if(barloc != NULL)
-               {
-                       manager.iHost.status = 0;
-                       while(tmploc < barloc)
-                       {
-                               manager.iHost.status = (manager.iHost.status * 2) + (*tmploc - '0');
-                               tmploc++;
-                       }
-                       manager.iHost.status += 1;
-
-                       if(manager.iHost.status < DAS_START_BEGIN || manager.iHost.status > DAS_START_END)
-                       {
-                               manager.iHost.status = DAS_EMUL_X86_START;
-                               ret = 1;
-                       }
-               }
-               else
-               {
-                       return -1;      // wrong message format
-               }
-
-               // parsing for target launch option flag
-               tmploc = barloc + 1;
-               barloc = strchr(tmploc, '|');
-               if(barloc != NULL)
-               {
-                       while(tmploc < barloc)
-                       {
-                               flag = (flag * 2) + (*tmploc - '0');
-                               tmploc++;
-                       }
-               }
-               else
-               {
-                       return -1;      // wrong message format
-               }
-
-               // parsing for application package name
-               tmploc = barloc + 1;
-               strcpy(manager.appPath, tmploc);
-
-#ifdef USE_BATT_LOG
-               if(manager.iHost.status == DAS_EMUL_ARM_BATT_START ||
-                               manager.iHost.status == DAS_EMUL_X86_BATT_START)
-                       wait_for_starting();
-#endif
-
-               get_executable(execPath, PATH_MAX); // get exact app executable file name
-#if RUN_APP_LOADER
-               kill_app(manager.appPath);
-#else
-               // use execPath instead of manager.appPath
-               kill_app(execPath);
-#endif
-               sleep(0);
-       
-               LOGI("executable app path %s\n", manager.appPath);
-
-               {
-                       char appInstallCommand[PATH_MAX];
-
-                       //save app install path
-                       mkdir(DA_INSTALL_DIR, 0775);
-                       sprintf(appInstallCommand,
-                                       "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH,
-                                       execPath, DA_INSTALL_PATH);
-                       LOGI("appInstallCommand %s\n", appInstallCommand);
-                       system(appInstallCommand);
-
-                       sprintf(appInstallCommand,
-                                       "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH,
-                                       execPath, DA_BUILD_OPTION);
-                       LOGI("appInstallCommand %s\n", appInstallCommand);
-                       system(appInstallCommand);
-
-#if RUN_APP_LOADER
-                       if(startProfiling(manager.appPath, manager.iHost.status, flag) < 0)
-#else
-                       // use execPath instead of manager.appPath
-                       if(startProfiling(execPath, manager.iHost.status, flag) < 0)
-#endif
-                       {
-                               terminate_error("Cannot start profiling", 1);
-                               return -1;
-                       }
-               }
-               break;
-       case MSG_STOP:
-               LOGI("MSG_STOP handling\n");
-               if (manager.iHost.status < DAS_START_BEGIN || manager.iHost.status > DAS_START_END)
-               {
-                       // already stopped, not possible, ignore MSG_STOP message
-                       LOGE("MSG_STOP status check : %d\n", manager.iHost.status);
-                       return 1;
-               }
-
-               manager.iHost.status = DAS_STOP;
-               terminate_all_target();
-               timerStop();
-               break;
-       case MSG_OPTION:
-               if(log->length > 0)
-               {
-                       if(log->data[0] == '0')
-                       {
-                               set_launch_flag(1, 0);
-                               LOGI("Snapshot disabled\n");
-                       }
-                       else if(log->data[0] == '1')
-                       {
-                               set_launch_flag(1, 1);
-                               LOGI("Snapshot enabled\n");
-                       }
-                       else
-                       {
-                               LOGI("Wrong option message from host\n");
-                       }
-               }
-               break;
-       case MSG_ISALIVE:
-               sendMsgStrToHost(NULL, MSG_ALIVE, 0);
-               break;
-
-#ifdef USE_BATT_LOG
-       case MSG_BATT_START:
-               {
-                       manager.iHost.status = DAS_BATT_START;
-                       sprintf(manager.appPath, "%s", log->data);
-                       create_open_batt_log(get_app_name(manager.appPath));
-                       wait_for_starting();
-                       if(startProfiling(manager.appPath, DAS_BATT_START, flag) < 0)
-                       {
-                               terminate_error("Cannot start profiling", 1);
-                               return -1;
-                       }
-//                     batt_start(manager.appPath);
-               }
-               break;
-       case MSG_BATT_STOP:
-               manager.iHost.status = DAS_BATT_STOP;
-               timerStop();
-//             batt_stop();
-               break;
-#endif
-
-       default:
-               LOGW("Unknown msg\n");
-       }
-
-       return ret;
-}
-
-static int parseHostMessage(log_t* log, char* msg)
-{
-       int i;
-       int bfind = 0;
-
-       if(log == NULL || msg == NULL)
-               return 0;
-
-       // Host message looks like this
-       // MSG_TYPE|MSG_LENGTH|MSG_STRING
-       // MSG_TYPE is always 3 digits number
-       if(msg[3] == '|')
-       {
-               msg[3] = '\0';
-               log->type = atoi(msg);
-
-               if(log->type < MSG_HOST_BEGIN || log->type > MSG_HOST_END)
-                       return 0;
-
-               msg = msg + 4;
-               for(i = 0; msg[i] != '\0'; i++)
-               {
-                       if(msg[i] == '|')
-                       {
-                               bfind = 1;
-                               msg[i] = '\0';
-                               break;
-                       }
-               }
-
-               if(bfind != 0)
-               {
-                       int msglen;
-                       log->length = atoi(msg);
-                       msg = msg + i + 1;
-                       msglen = strlen(msg);
-
-                       if(log->length == 0)
-                       {
-                               log->data[0] = '\0';
-                       }
-                       else
-                       {
-                               if(msglen == log->length)
-                                       strcpy(log->data, msg);
-                               else if(msglen > log->length)   // parsing error but deal as nonerror
-                                       strncpy(log->data, msg, log->length);
-                               else
-                                       return 0;       // parsing error
-
-                               log->data[log->length] = '\0';
-                       }
-               }
-               else
-               {
-                       return 0;       // parsing error
-               }
-
-               return 1;       // parsing success
-       }
-       else
-       {
-               return 0;       // parsing error
-       }
-}
-
-#define EPOLL_SIZE 10
-#define MAX_CONNECT_SIZE 12
-#define MAX_INAROW_TARGET_MSG 10
-
-// return 0 for normal case
-static int work()
-{
-       struct sockaddr_un clientAddrUn; //target
-       struct sockaddr_in clientAddrIn; //host
-       int i, k, find;
-       ssize_t recvLen;
-       char recvBuf[READ_BUF_MAX];
-       log_t log;
-
-       struct epoll_event ev, *events;
-       int efd;        // epoll fd
-       int numevent;   // number of occured events
-
-       // initialize epoll event pool
-       events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
-       if(events == NULL)
-       {
-               LOGE("Out of memory when allocate epoll event pool\n");
-               return -1;
-       }
-       if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
-       {
-               LOGE("epoll creation error\n");
-               free(events);
-               return -1;
-       }
-
-       // add server sockets to epoll event pool
-       ev.events = EPOLLIN;
-       ev.data.fd = manager.iHost.serverSockFD;
-       if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.iHost.serverSockFD, &ev) < 0)
-       {
-               LOGE("Host server socket epoll_ctl error\n");
-               free(events);
-               close(efd);
-               return -1;
-       }
-       ev.events = EPOLLIN;
-       ev.data.fd = manager.iTarget.serverSockFD;
-       if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.iTarget.serverSockFD, &ev) < 0)
-       {
-               LOGE("Target server socket epoll_ctl error\n");
-               free(events);
-               close(efd);
-               return -1;
-       }
-
-       // handler loop
-       while (1)
-       {
-               numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
-               if(numevent <= 0)
-               {
-                       LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
-                       continue;
-               }
-
-               for(i = 0; i < numevent; i++)
-               {
-                       find = 0;
-                       for(k = 0; k < manager.iTarget.connectCount; k++)
-                       {
-                               if(events[i].data.fd == manager.iTarget.clientSockFD[k])
-                               {
-                                       // read from target process
-                                       recvLen = recv(manager.iTarget.clientSockFD[k], &log,
-                                                       sizeof(log.type) + sizeof(log.length), 0);
-
-                                       // send to host
-                                       if (recvLen > 0)
-                                       {
-                                               int count = 0;
-                                               do {
-                                                       if (log.length > 0)
-                                                               recv(manager.iTarget.clientSockFD[k], log.data, log.length, 0);
-                                                       log.data[log.length] = '\0';
-                                                       if(log.type == 5)       // MSG_LOG
-                                                       {
-                                                               switch(log.data[0])
-                                                               {
-                                                                       case '2':       // UI control creation log
-                                                                       case '3':       // UI event log
-                                                                       case '6':       // UI lifecycle log
-                                                                       case '7':       // screnshot log
-                                                                       case '8':       // scene transition log
-                                                                               LOGI("%dclass|%s\n", log.data[0] - '0', log.data);
-                                                                               break;
-                                                                       default:
-                                                                               break;
-                                                               }
-                                                       }
-                                                       else if(log.type == 6)  // MSG_IMAGE
-                                                       {
-                                                               LOGI("MSG_IMAGE received\n");
-                                                       }
-                                                       else    // not MSG_LOG and not MSG_IMAGE
-                                                       {
-                                                               LOGI("Extra MSG TYPE (%d|%d|%s)\n", log.type, log.length, log.data);
-                                                       }
-                                                       sendMsgStrToHost(log.data, log.type, k);
-                                                       if(count++ > MAX_INAROW_TARGET_MSG)
-                                                               break;
-                                               } while ((recvLen = recv(manager.iTarget.clientSockFD[k],
-                                                                       &log, sizeof(log.type) + sizeof(log.length), MSG_DONTWAIT)) > 0);
-                                       }
-
-                                       // close request from target client socket
-                                       if(recvLen == 0)
-                                       {
-                                               LOGI("target close = %d(total %d)\n", manager.iTarget.clientSockFD[k], manager.iTarget.connectCount - 1);
-                                               if(epoll_ctl(efd, EPOLL_CTL_DEL, manager.iTarget.clientSockFD[k], NULL) < 0)
-                                               {
-                                                       LOGE("Failed to epoll_ctl delete fd from event poll\n");
-                                               }
-                                               close(manager.iTarget.clientSockFD[k]);
-                                               LOGI("Terminate %dth pid(%d)\n", k, manager.iTarget.execPID[k]);
-                                               // consume that target process is already in terminating phase
-//                                             _terminate_pid(manager.iTarget.execPID[k]);
-                                               manager.iTarget.connectCount--;
-                                               if(manager.iTarget.execPID[k] != -1)
-                                                       manager.iTarget.pidCount--;
-//                                             assert(manager.iTarget.connectCount == manager.iTarget.pidCount);
-                                               if (manager.iTarget.connectCount == 0)  // all target client are closed
-                                               {
-                                                       manager.iTarget.status = DAS_TERMINATE;
-
-                                                       LOGI("Exit daemon process\n");
-                                                       manager.iTarget.clientSockFD[k] = -1;
-                                                       manager.iTarget.execPID[k] = -1;
-                                                       timerStop();
-                                                       free(events);
-                                                       close(efd);
-                                                       return 0;
-                                               }
-                                               else
-                                               {
-                                                       manager.iTarget.clientSockFD[k] = manager.iTarget.clientSockFD[manager.iTarget.connectCount];
-                                                       manager.iTarget.clientSockFD[manager.iTarget.connectCount] = -1;
-                                                       manager.iTarget.execPID[k] = manager.iTarget.execPID[manager.iTarget.pidCount];
-                                                       manager.iTarget.execPID[manager.iTarget.pidCount] = -1;
-                                               }
-                                       }
-
-                                       find = 1;
-                                       break;
-                               }
-                       }
-                       if(find == 0)   // this event is not from target client socket
-                       {
-                               // connect request from target
-                               if(events[i].data.fd == manager.iTarget.serverSockFD)
-                               {
-                                       socklen_t addrlen;
-                                       addrlen = sizeof(clientAddrUn);
-                                       manager.iTarget.clientSockFD[manager.iTarget.connectCount] =
-                                                       accept(manager.iTarget.serverSockFD, (struct sockaddr *) &clientAddrUn, &addrlen);
-
-                                       if(manager.iTarget.clientSockFD[manager.iTarget.connectCount] >= 0)     // accept succeed
-                                       {
-                                               ev.events = EPOLLIN;
-                                               ev.data.fd = manager.iTarget.clientSockFD[manager.iTarget.connectCount];
-                                               if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.iTarget.clientSockFD[manager.iTarget.connectCount], &ev) < 0)
-                                               {
-                                                       // consider as accept fail
-                                                       LOGE("Target client epoll_ctl error\n");
-                                                       manager.iTarget.clientSockFD[manager.iTarget.connectCount] = -1;
-                                               }
-                                               else
-                                               {
-                                                       LOGI("target connect = %d(total%d)\n",
-                                                                       manager.iTarget.clientSockFD[manager.iTarget.connectCount], manager.iTarget.connectCount + 1);
-                                                       manager.iTarget.connectCount++;
-                                               }
-                                       }
-                                       else    // accept error
-                                       {
-                                               LOGE("Failed to accept from target server socket\n");
-                                       }
-                               }
-                               // connect request from host
-                               else if(events[i].data.fd == manager.iHost.serverSockFD)
-                               {
-                                       socklen_t addrlen;
-                                       addrlen = sizeof(clientAddrIn);
-                                       if(manager.iHost.clientSockFD != -1)
-                                       {
-                                               if(epoll_ctl(efd, EPOLL_CTL_DEL, manager.iHost.clientSockFD, NULL) < 0)
-                                               {
-                                                       LOGE("Failed to delete host client socket from epoll ctrl queue\n");
-                                               }
-                                               close(manager.iHost.clientSockFD);
-                                               LOGI("Host client socket is closed, fd(%d)\n", manager.iHost.clientSockFD);
-                                       }
-                                       manager.iHost.clientSockFD = accept(manager.iHost.serverSockFD, (struct sockaddr *) &clientAddrIn, &addrlen);
-
-                                       if(manager.iHost.clientSockFD >= 0)             // accept succeed
-                                       {
-                                               ev.events = EPOLLIN;
-                                               ev.data.fd = manager.iHost.clientSockFD;
-                                               if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.iHost.clientSockFD, &ev) < 0)
-                                               {
-                                                       // consider as accept fail
-                                                       close(manager.iHost.clientSockFD);
-                                                       manager.iHost.clientSockFD = -1;
-                                                       terminate_error("Host client epoll_ctl error", 1);
-                                               }
-                                               else
-                                               {
-                                                       LOGI("host connect = %d\n", manager.iHost.clientSockFD);
-                                               }
-                                       }
-                                       else    // accept error
-                                       {
-                                               LOGE("Failed to accept from host server socket\n");
-                                       }
-                               }
-                               // message from host
-                               else if(events[i].data.fd == manager.iHost.clientSockFD)
-                               {
-                                       // host log format xxx|length|str
-                                       LOGI("Host client socket selected(Message from host)\n");
-                                       recvLen = recv(manager.iHost.clientSockFD, recvBuf, READ_BUF_MAX, 0);
-
-                                       if (recvLen > 0)
-                                       {
-                                               recvBuf[recvLen] = '\0';
-                                               LOGI("host sent this msg len(%d) str(%s)\n", recvLen, recvBuf);
-                                               if(parseHostMessage(&log, recvBuf) == 0)
-                                               {
-                                                       // error to parse host message
-                                                       sendMsgStrToHost("host log message is unrecognizable", MSG_ERROR, -1);
-                                                       continue;
-                                               }
-
-                                               //host msg command handling
-                                               if(hostMessageHandler(&log) < 0)
-                                               {
-                                                       terminate_error("Host message handling error", 1);
-                                                       free(events);
-                                                       close(efd);
-                                                       return 0;
-                                               }
-                                       }
-                                       else    // close request from HOST
-                                       {
-                                               // work loop quit
-                                               if(manager.iHost.status >= DAS_START_BEGIN && manager.iHost.status <= DAS_START_END)
-                                               {
-                                                       // host client socket end unexpectly
-                                                       terminate_error("Host client socket closed unexpectly", 0);
-                                               }
-                                               LOGI("host close = %d\n", manager.iHost.clientSockFD);
-                                               free(events);
-                                               close(efd);
-                                               return 0;
-                                       }
-                               }
-                               else
-                               {
-                                       // never happened
-                                       LOGW("Unknown socket fd\n");
-                               }
-                       }
-               }
-       }
-
-       free(events);
-       close(efd);
-       return 0;
-}
-
-// return 0 for normal case
-static int initialize_manager()
-{
-       int i;
-       // make server socket
-       if(__makeTargetServerSockFD() != 0)
-               return -1;
-       if(__makeHostServerSockFD() != 0)
-               return -1;
-
-       // initialize target client sockets
-       for (i = 0; i < TARGET_CLIENT_COUNT_MAX; i++)
-       {
-               manager.iTarget.clientSockFD[i] = -1;
-               manager.iTarget.execPID[i] = -1;
-       }
-
-       // initialize sendMutex
-       pthread_mutex_init(&(manager.sendMutex), NULL);
-
-       if(initialize_system_info() < 0)
-               return -1;
-
-       return 0;
-}
-
-static int finalize_manager()
-{
-       int i;
-
-       finalize_system_info();
-
-       terminate_all_target();
-
-       LOGI("Finalize daemon\n");
-
-       // finalize target client sockets
-       for (i = 0; i < TARGET_CLIENT_COUNT_MAX; i++)
-       {
-               if(manager.iTarget.clientSockFD[i] != -1)
-                       close(manager.iTarget.clientSockFD[i]);
-       }
-
-       // close host client socket
-       if(manager.iHost.clientSockFD != -1)
-               close(manager.iHost.clientSockFD);
-
-       // close server socket
-       if(manager.iHost.serverSockFD != -1)
-               close(manager.iHost.serverSockFD);
-       if(manager.iTarget.serverSockFD != -1)
-               close(manager.iTarget.serverSockFD);
-
-       return 0;
-}
-
-static void __attribute((destructor)) exit_func()
-{
-       __destroySharedMemory();
-}
-
-int main()
-{
-#if DEBUG
-       write_log();
-#endif
-
-       //for terminal exit
-       signal(SIGHUP, SIG_IGN);
-       chdir("/");
-
-       //new session reader
-       setsid();
-
-       // initialize manager
-       if(initialize_manager() == 0)
-       {
-               //daemon work
-               work();
-
-               finalize_manager();
-               return 0;
-       }
-       else
-               return 1;
-}
similarity index 60%
rename from daemon/da_debug.h
rename to daemon/da_debug.c
index 9d53da9..f4b02ce 100644 (file)
@@ -3,12 +3,12 @@
 *
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
 *
-* Contact: 
+* Contact:
 *
 * Jaewon Lim <jaewon81.lim@samsung.com>
 * Woojin Jung <woojin2.jung@samsung.com>
 * Juyoung Kim <j0.kim@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
 * Contributors:
 * - S-Core Co., Ltd
 *
-*/ 
+*/
 
-#ifndef _DA_DEBUG_H_
-#define _DA_DEBUG_H_
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if DEBUG
-       #define LOGI(...)       do{ fprintf(stderr, "[INF]" __VA_ARGS__ ); fflush(stderr); } while(0)
-       #define LOGE(...)       do{ fprintf(stderr, "[ERR]" __VA_ARGS__ ); fflush(stderr); } while(0)
-       #define LOGW(...)       do{ fprintf(stderr, "[WRN]" __VA_ARGS__ ); fflush(stderr); } while(0)
-#else
-       #define LOGI(...)       do{} while(0)
-       #define LOGE(...)       do{} while(0)
-       #define LOGW(...)       do{} while(0)
-#endif
+#include "daemon.h"
 
+#define DEBUG_LOGFILE          "/tmp/daemonlog.da"
 
+#if DEBUG
+void initialize_log()
+{
+    int fd;
 
+    fd = open("/dev/null", O_RDONLY);
+    dup2(fd, 0);
 
+    fd = open(DEBUG_LOGFILE, O_WRONLY | O_CREAT | O_TRUNC, 0777);
+    if(fd < 0) {
+        fd = open("/dev/null", O_WRONLY);
+    }
+    dup2(fd, 1);
+    dup2(fd, 2);
 
-#ifdef __cplusplus
+    fprintf(stderr, "--- daemon starting (pid %d) ---\n", getpid());
+}
+#else
+void initialize_log()
+{
 }
 #endif
 
-#endif // _DA_DEBUG_H_
diff --git a/daemon/daemon.c b/daemon/daemon.c
new file mode 100644 (file)
index 0000000..d77ce44
--- /dev/null
@@ -0,0 +1,891 @@
+/*
+*  DA manager
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+*
+* Jaewon Lim <jaewon81.lim@samsung.com>
+* Woojin Jung <woojin2.jung@samsung.com>
+* Juyoung Kim <j0.kim@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.
+*
+* Contributors:
+* - S-Core Co., Ltd
+*
+*/ 
+
+#include <stdio.h>
+#include <stdlib.h>                    // for realpath
+#include <string.h>                    // for strtok, strcpy, strncpy
+#include <limits.h>                    // for realpath
+
+#include <errno.h>                     // for errno
+#include <sys/types.h>         // for accept, mkdir, opendir, readdir
+#include <sys/socket.h>                // for accept
+#include <sys/stat.h>          // for mkdir
+#include <sys/eventfd.h>       // for eventfd
+#include <sys/epoll.h>         // for epoll apis
+#include <unistd.h>                    // for access, sleep
+#include <attr/xattr.h>                // for fsetxattr
+
+#include "daemon.h"
+#include "sys_stat.h"
+#include "utils.h"
+
+#define DA_WORK_DIR                            "/home/developer/sdk_tools/da/"
+#define DA_READELF_PATH                        "/home/developer/sdk_tools/da/readelf"
+#define SCREENSHOT_DIR                 "/tmp/da"
+
+#define EPOLL_SIZE 10
+#define MAX_CONNECT_SIZE 12
+
+static void terminate_error(char* errstr, int sendtohost);
+
+long long get_total_alloc_size()
+{
+       int i;
+       long long allocsize = 0;
+
+       for(i = 0; i < MAX_TARGET_COUNT; i++)
+       {
+               if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
+                       allocsize += manager.target[i].allocmem;
+       }
+       return allocsize;
+}
+
+static int getEmptyTargetSlot()
+{
+       int i;
+       for(i = 0; i < MAX_TARGET_COUNT; i++)
+       {
+               if(manager.target[i].socket == -1)
+                       break;
+       }
+
+       return i;
+}
+
+static void setEmptyTargetSlot(int index)
+{
+       if(index >= 0 && index < MAX_TARGET_COUNT)
+       {
+               manager.target[index].pid = -1;
+               manager.target[index].recv_thread = -1;
+               manager.target[index].allocmem = 0;
+               manager.target[index].starttime = 0;
+               if(manager.target[index].event_fd != -1)
+                       close(manager.target[index].event_fd);
+               manager.target[index].event_fd = -1;
+               if(manager.target[index].socket != -1)
+                       close(manager.target[index].socket);
+               manager.target[index].socket = -1;
+       }
+}
+
+// ======================================================================================
+// send functions to host
+// ======================================================================================
+
+int sendDataToHost(msg_t* log)
+{
+       if (manager.host.data_socket != -1)
+       {
+               char logstr[DA_MSG_MAX];
+               int loglen;
+
+               if(log->length != 0)
+                       loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
+               else
+                       loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
+
+//             loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
+
+               pthread_mutex_lock(&(manager.host.data_socket_mutex));
+               send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
+               pthread_mutex_unlock(&(manager.host.data_socket_mutex));
+               return 0;
+       }
+       else
+               return 1;
+}
+
+// msgstr can be NULL
+static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
+{
+       if (manager.host.control_socket != -1)
+       {
+               char logstr[DA_MSG_MAX];
+               int loglen;
+
+               if(msgstr != NULL)
+                       loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
+               else
+                       loglen = sprintf(logstr, "%d|0|", (int)resp);
+
+               send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
+               return 0;
+       }
+       else
+               return 1;
+}
+
+static int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
+{
+       if (manager.host.control_socket != -1)
+       {
+               char codestr[16];
+               char logstr[DA_MSG_MAX];
+               int loglen, codelen;
+
+               codelen = sprintf(codestr, "%d", msgcode);
+               loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
+
+               send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
+               return 0;
+       }
+       else
+               return 1;
+}
+
+// ========================================================================================
+// start and terminate control functions
+// ========================================================================================
+
+static int startProfiling(long launchflag)
+{
+       char execPath[PATH_MAX];
+
+       // remove previous screen capture files
+       remove_indir(SCREENSHOT_DIR);
+       mkdir(SCREENSHOT_DIR, 0777);
+
+       manager.config_flag = launchflag;
+
+#ifdef RUN_APP_LOADER
+       strcpy(execPath, manager.appPath);
+#else
+       get_executable(manager.appPath, execPath, PATH_MAX);
+#endif
+       if(exec_app(execPath, get_app_type(manager.appPath)))
+       {
+               if(samplingStart() < 0)
+               {
+                       return -1;
+               }
+               LOGI("Timer Started\n");
+       }
+       else
+               return -1;
+
+       return 0;
+}
+
+// terminate single target
+// just send stop message to target process
+static void terminate_target(int index)
+{
+       ssize_t sendlen;
+       msg_t sendlog;
+       sendlog.type = MSG_STOP;
+       sendlog.length = 0;
+
+       if(manager.target[index].socket != -1)
+       {
+               // result of sending to disconnected socket is not expected
+               sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
+               if(sendlen != -1)
+               {
+                       LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
+               }
+       }
+}
+
+// just send stop message to all target process
+static void terminate_all_target()
+{
+       int i;
+       ssize_t sendlen;
+       msg_t sendlog;
+
+       sendlog.type = MSG_STOP;
+       sendlog.length = 0;
+
+       for (i = 0; i < MAX_TARGET_COUNT; i++)
+       {
+               if(manager.target[i].socket != -1)
+               {
+                       sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
+                       if(sendlen != -1)
+                       {
+                               LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
+                       }
+               }
+       }
+}
+
+// terminate all target and wait for threads
+static void terminate_all()
+{
+       int i;
+       terminate_all_target();
+       samplingStop();
+
+       // wait for all other thread exit
+       for(i = 0; i < MAX_TARGET_COUNT; i++)
+       {
+               if(manager.target[i].recv_thread != -1)
+               {
+                       pthread_join(manager.target[i].recv_thread, NULL);
+               }
+       }
+}
+
+// terminate all profiling by critical error
+static void terminate_error(char* errstr, int sendtohost)
+{
+       msg_t log;
+
+       LOGE("TERMINATE ERROR: %s\n", errstr);
+       if(sendtohost)
+       {
+               log.type = MSG_ERROR;
+               log.length = sprintf(log.data, "%s", errstr);
+               sendDataToHost(&log);
+       }
+
+       terminate_all();
+}
+
+// ===========================================================================================
+// message parsing and handling functions
+// ===========================================================================================
+
+// return 0 for normal case
+// return negative value for error case
+static int parseHostMessage(msg_t* log, char* msg)
+{
+       int i;
+       int bfind = 0;
+       int ret = 0;    // parsing success
+
+       if(log == NULL || msg == NULL)
+               return -1;
+
+       // Host message looks like this
+       // MSG_TYPE|MSG_LENGTH|MSG_STRING
+       // MSG_TYPE is always 3 digits number
+       if(msg[3] == '|')
+       {
+               msg[3] = '\0';
+               log->type = atoi(msg);
+
+               msg = msg + 4;
+               for(i = 0; msg[i] != '\0'; i++)
+               {
+                       if(msg[i] == '|')
+                       {
+                               bfind = 1;
+                               msg[i] = '\0';
+                               break;
+                       }
+               }
+               log->length = atoi(msg);
+
+               if(log->length == 0)
+               {
+                       log->data[0] = '\0';
+               }
+               else
+               {
+                       if(bfind != 0)
+                       {
+                               int msglen;
+                               msg = msg + i + 1;
+                               msglen = strlen(msg);
+
+                               if(msglen == log->length)
+                               {
+                                       strcpy(log->data, msg);
+                                       log->data[log->length] = '\0';
+                               }
+//                             else if(msglen > log->length)
+//                             {
+//                                     strncpy(log->data, msg, log->length);
+//                                     log->data[log->length] = '\0';
+//                             }
+                               else
+                               {
+                                       ret = -1;       // parsing error
+                               }
+                       }
+                       else
+                       {
+                               ret = -1;       // parsing error
+                       }
+               }
+       }
+       else
+       {
+               ret = -1;       // parsing error
+       }
+
+       return ret;
+}
+
+// return 0 if normal case
+// return plus value if non critical error occur
+// return minus value if critical error occur
+static int hostMessageHandler(msg_t* log)
+{
+       int ret = 0;
+       long flag = 0;
+       char *barloc, *tmploc;
+       char execPath[PATH_MAX];
+
+       if (log == NULL)
+               return 1;
+
+       switch (log->type)
+       {
+       case MSG_VERSION:
+               if(strcmp(PROTOCOL_VERSION, log->data) != 0)
+               {
+                       sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION);
+               }
+               else
+               {
+                       sendACKStrToHost(MSG_OK, NULL);
+               }
+               break;
+       case MSG_START:
+               LOGI("MSG_START handling : %s\n", log->data);
+               if(log->length == 0)
+               {
+                       sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
+                       return -1;              // wrong message format
+               }
+
+               // parsing for host start status
+               tmploc  = log->data;
+               barloc = strchr(tmploc, '|');
+               if(barloc == NULL)
+               {
+                       sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
+                       return -1;              // wrong message format
+               }
+
+               // parsing for target launch option flag
+               tmploc = barloc + 1;
+               barloc = strchr(tmploc, '|');
+               if(barloc != NULL)
+               {
+                       while(tmploc < barloc)
+                       {
+                               flag = (flag * 10) + (*tmploc - '0');
+                               tmploc++;
+                       }
+               }
+               else
+               {
+                       sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
+                       return -1;      // wrong message format
+               }
+               LOGI("launch flag : %lx\n", flag);
+
+               // parsing for application package name
+               tmploc = barloc + 1;
+               strcpy(manager.appPath, tmploc);
+
+               get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name
+               LOGI("executable app path %s\n", manager.appPath);
+
+#ifdef RUN_APP_LOADER
+               kill_app(manager.appPath);
+#else
+               kill_app(execPath);
+#endif
+
+               {
+                       char command[PATH_MAX];
+
+                       //save app install path
+                       mkdir(DA_WORK_DIR, 0775);
+                       sprintf(command,
+                                       "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH,
+                                       execPath, DA_INSTALL_PATH);
+                       LOGI("appInstallCommand %s\n", command);
+                       system(command);
+
+                       sprintf(command,
+                                       "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH,
+                                       execPath, DA_BUILD_OPTION);
+                       LOGI("appInstallCommand %s\n", command);
+                       system(command);
+
+                       if(startProfiling(flag) < 0)
+                       {
+                               sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING);
+                               return -1;
+                       }
+               }
+               sendACKStrToHost(MSG_OK, NULL);
+               break;
+       case MSG_STOP:
+               LOGI("MSG_STOP handling\n");
+               sendACKStrToHost(MSG_OK, NULL);
+               terminate_all();
+               break;
+       case MSG_OPTION:
+               if(log->length > 0)
+               {
+                       int i;
+                       msg_t sendlog;
+                       manager.config_flag = atoi(log->data);
+                       sendACKStrToHost(MSG_OK, NULL);
+
+                       LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag);
+
+                       sendlog.type = MSG_OPTION;
+                       sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag);
+
+                       for(i = 0; i < MAX_TARGET_COUNT; i++)
+                       {
+                               if(manager.target[i].socket != -1)
+                               {
+                                       send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL);
+                               }
+                       }
+               }
+               else
+               {
+                       sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
+                       ret = 1;
+               }
+               break;
+       case MSG_ISALIVE:
+               sendACKStrToHost(MSG_OK, NULL);
+               break;
+       default:
+               LOGW("Unknown msg\n");
+               sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE);
+               ret = 1;
+               break;
+       }
+
+       return ret;
+}
+
+// ========================================================================================
+// socket and event_fd handling functions
+// ========================================================================================
+
+// return 0 if normal case
+// return plus value if non critical error occur
+// return minus value if critical error occur
+// return -11 if all target process closed
+static int targetEventHandler(int epollfd, int index, uint64_t msg)
+{
+       msg_t log;
+
+       if(msg & EVENT_PID)
+       {
+               if(index == 0)          // assume index 0 is main application process
+               {
+                       int base_address;
+                       char tempBuff[DA_MSG_MAX];
+                       char tempBuff2[DA_MSG_MAX];
+                       char tempPath[PATH_MAX];
+
+                       get_executable(manager.appPath, tempPath, PATH_MAX);
+                       if(realpath(tempPath, tempBuff) == NULL)
+                       {
+                               LOGW("Failed to get realpath of app\n");
+                               strcpy(tempBuff, tempPath);
+                       }
+
+                       sprintf(tempPath, "/proc/%d/maps", manager.target[index].pid);
+                       sprintf(tempBuff2, "cat %s | grep %s | cut -d\"-\" -f1 > %s",
+                                       tempPath, tempBuff, DA_BASE_ADDRESS);
+                       LOGI("base address command is %s\n", tempBuff2);
+
+                       do {
+                               if(access(tempPath, F_OK) != 0)
+                                       return -1;
+                               if(is_same_app_process(manager.appPath, manager.target[index].pid) == 0)
+                                       return -1;
+
+                               system(tempBuff2);
+                               if(get_app_base_address(&base_address) == 1)
+                                       break;
+                               sleep(0);
+                       } while(1);
+
+                       tempPath[0] = '\0';
+                       get_app_install_path(tempPath, PATH_MAX);
+                       get_device_info(tempBuff, DA_MSG_MAX);
+                       log.type = MSG_DEVICE;
+                       if (strlen(tempPath) > 0)
+                       {
+                               get_executable(manager.appPath, tempBuff2, DA_MSG_MAX);
+                               log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,%s/%s", tempBuff,
+                                               manager.target[index].pid, manager.target[index].starttime,
+                                               is_app_built_pie(), base_address, get_app_type(manager.appPath),
+                                               tempPath, get_app_name(tempBuff2));
+                       }
+                       else
+                       {
+                               log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,", tempBuff,
+                                               manager.target[index].pid, manager.target[index].starttime,
+                                               is_app_built_pie(), base_address, get_app_type(manager.appPath));
+                       }
+
+                       LOGI("%s\n", log.data);
+               }
+               else
+               {
+                       log.type = MSG_PID;
+                       log.length = sprintf(log.data, "%d`,%Lu", manager.target[index].pid, manager.target[index].starttime);
+               }
+
+               sendDataToHost(&log);
+       }
+
+       if(msg & EVENT_STOP || msg & EVENT_ERROR)
+       {
+               LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
+                               manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
+
+               terminate_target(index);
+               epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
+               setEmptyTargetSlot(index);
+               if (0 == __sync_sub_and_fetch(&manager.target_count, 1))        // all target client are closed
+               {
+                       log.type = MSG_TERMINATE;
+                       log.length = 0;
+                       log.data[0] = '\0';
+                       sendDataToHost(&log);
+                       return -11;
+               }
+       }
+
+       return 0;
+}
+
+// return 0 if normal case
+// return plus value if non critical error occur
+// return minus value if critical error occur
+static int targetServerHandler(int efd)
+{
+       msg_t log;
+       struct epoll_event ev;
+
+       int index = getEmptyTargetSlot();
+       if(index == MAX_TARGET_COUNT)
+       {
+               LOGW("Max target number(8) reached, no more target can connected\n");
+               return 1;
+       }
+
+       manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
+
+       if(manager.target[index].socket >= 0)   // accept succeed
+       {
+               // set smack attribute for certification
+               fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
+               fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
+
+               // send config message to target process
+               log.type = MSG_OPTION;
+               log.length = sprintf(log.data, "%u", manager.config_flag);
+               send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
+
+               // make event fd
+               manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
+               if(manager.target[index].event_fd == -1)
+               {
+                       // fail to make event fd
+                       LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
+                       goto TARGET_CONNECT_FAIL;
+               }
+
+               // add event fd to epoll list
+               ev.events = EPOLLIN;
+               ev.data.fd = manager.target[index].event_fd;
+               if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
+               {
+                       // fail to add event fd
+                       LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
+                       goto TARGET_CONNECT_FAIL;
+               }
+
+               // make recv thread for target
+               if(makeRecvThread(index) != 0)
+               {
+                       // fail to make recv thread
+                       LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
+                       epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
+                       goto TARGET_CONNECT_FAIL;
+               }
+
+               LOGI("target connected = %d(running %d target)\n",
+                               manager.target[index].socket, manager.target_count + 1);
+
+               manager.target_count++;
+               return 0;
+       }
+       else    // accept error
+       {
+               LOGE("Failed to accept at target server socket\n");
+       }
+
+TARGET_CONNECT_FAIL:
+       if(manager.target_count == 0)   // if this connection is main connection
+       {
+               return -1;
+       }
+       else    // if this connection is not main connection then ignore process by error
+       {
+               setEmptyTargetSlot(index);
+               return 1;
+       }
+}
+
+// return 0 if normal case
+// return plus value if non critical error occur
+// return minus value if critical error occur
+static int hostServerHandler(int efd)
+{
+       static int hostserverorder = 0;
+       int csocket;
+       struct epoll_event ev;
+
+       if(hostserverorder > 1) // control and data socket connected already
+               return 1;                       // ignore
+
+       csocket = accept(manager.host_server_socket, NULL, NULL);
+
+       if(csocket >= 0)                // accept succeed
+       {
+               ev.events = EPOLLIN;
+               ev.data.fd = csocket;
+               if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
+               {
+                       // consider as accept fail
+                       LOGE("Failed to add socket fd to epoll list\n");
+                       close(csocket);
+                       return -1;
+               }
+
+               if(hostserverorder == 0)
+               {
+                       manager.host.control_socket = csocket;
+                       LOGI("host control socket connected = %d\n", csocket);
+               }
+               else
+               {
+                       manager.host.data_socket = csocket;
+                       LOGI("host data socket connected = %d\n", csocket);
+               }
+
+               hostserverorder++;
+               return 0;
+       }
+       else    // accept error
+       {
+               LOGE("Failed to accept from host server socket\n");
+               return -1;
+       }
+}
+
+// return 0 if normal case
+// return plus value if non critical error occur
+// return minus value if critical error occur
+// return -11 if socket closed
+static int controlSocketHandler()
+{
+       ssize_t recvLen;
+       char recvBuf[DA_MSG_MAX];
+       msg_t log;
+
+       // host log format xxx|length|str
+       recvLen = recv(manager.host.control_socket, recvBuf, RECV_BUF_MAX, 0);
+
+       if (recvLen > 0)
+       {
+               recvBuf[recvLen] = '\0';
+               LOGI("host sent control msg str(%s)\n", recvBuf);
+
+               if(parseHostMessage(&log, recvBuf) < 0)
+               {
+                       // error to parse host message
+                       sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
+                       return 1;
+               }
+
+               // host msg command handling
+               return hostMessageHandler(&log);
+       }
+       else    // close request from HOST
+       {
+               return -11;
+       }
+}
+
+// return 0 for normal case
+int daemonLoop()
+{
+       int                     ret = 0;                                // return value
+       int                     i, k;
+       ssize_t         recvLen;
+
+       struct epoll_event ev, *events;
+       int efd;                // epoll fd
+       int numevent;   // number of occured events
+
+       // initialize epoll event pool
+       events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
+       if(events == NULL)
+       {
+               LOGE("Out of memory when allocate epoll event pool\n");
+               ret = -1;
+               goto END_RETURN;
+       }
+       if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
+       {
+               LOGE("epoll creation error\n");
+               ret = -1;
+               goto END_EVENT;
+       }
+
+       // add server sockets to epoll event pool
+       ev.events = EPOLLIN;
+       ev.data.fd = manager.host_server_socket;
+       if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
+       {
+               LOGE("Host server socket epoll_ctl error\n");
+               ret = -1;
+               goto END_EFD;
+       }
+       ev.events = EPOLLIN;
+       ev.data.fd = manager.target_server_socket;
+       if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
+       {
+               LOGE("Target server socket epoll_ctl error\n");
+               ret = -1;
+               goto END_EFD;
+       }
+
+       // handler loop
+       while (1)
+       {
+               numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
+               if(numevent <= 0)
+               {
+                       LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
+                       continue;
+               }
+
+               for(i = 0; i < numevent; i++)
+               {
+                       // check for request from event fd
+                       for(k = 0; k < MAX_TARGET_COUNT; k++)
+                       {
+                               if(manager.target[k].socket != -1 &&
+                                               events[i].data.fd == manager.target[k].event_fd)
+                               {
+                                       uint64_t u;
+                                       recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
+                                       if(recvLen != sizeof(uint64_t))
+                                       {
+                                               // maybe closed, but ignoring is more safe then removing fd from epoll list
+                                       }
+                                       else
+                                       {
+                                               if(-11 == targetEventHandler(efd, k, u))
+                                               {
+                                                       LOGI("all target process is closed\n");
+                                                       terminate_all();
+                                                       ret = 0;
+                                                       goto END_EFD;
+                                               }
+                                       }
+                                       break;
+                               }
+                       }
+
+                       if(k != MAX_TARGET_COUNT)
+                               continue;
+
+                       // connect request from target
+                       if(events[i].data.fd == manager.target_server_socket)
+                       {
+                               if(targetServerHandler(efd) < 0)        // critical error
+                               {
+                                       terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
+                                       ret = -1;
+                                       goto END_EFD;
+                               }
+                       }
+                       // connect request from host
+                       else if(events[i].data.fd == manager.host_server_socket)
+                       {
+                               int result = hostServerHandler(efd);
+                               if(result < 0)
+                               {
+                                       terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
+                                       ret = -1;
+                                       goto END_EFD;
+                               }
+                       }
+                       // control message from host
+                       else if(events[i].data.fd == manager.host.control_socket)
+                       {
+                               int result = controlSocketHandler();
+                               if(result == -11)       // socket close
+                               {
+                                       // close target and host socket and quit
+                                       LOGI("host close = %d\n", manager.host.control_socket);
+                                       terminate_all();
+                                       ret = 0;
+                                       goto END_EFD;
+                               }
+                               else if(result < 0)
+                               {
+                                       terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
+                                       ret = -1;
+                                       goto END_EFD;
+                               }
+                       }
+                       else if(events[i].data.fd == manager.host.data_socket)
+                       {
+                               LOGW("host message from data socket\n");
+                       }
+                       // unknown socket
+                       else
+                       {
+                               // never happened
+                               LOGW("Unknown socket fd (%d)\n", events[i].data.fd);
+                       }
+               }
+       }
+
+END_EFD:
+       close(efd);
+END_EVENT:
+       free(events);
+END_RETURN:
+       return ret;
+}
diff --git a/daemon/daemon.h b/daemon/daemon.h
new file mode 100644 (file)
index 0000000..4c70209
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+*  DA manager
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+*
+* Jaewon Lim <jaewon81.lim@samsung.com>
+* Woojin Jung <woojin2.jung@samsung.com>
+* Juyoung Kim <j0.kim@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.
+*
+* Contributors:
+* - S-Core Co., Ltd
+*
+*/ 
+
+#include <stdint.h>            // for uint64_t, int64_t
+#include <pthread.h>   // for pthread_mutex_t
+
+#ifndef _DAEMON_H_
+#define _DAEMON_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PROTOCOL_VERSION                       "2.1"
+
+#define RUN_APP_LOADER
+
+#define MAX_TARGET_COUNT                       8
+#define DA_MSG_MAX                                     4096
+#define RECV_BUF_MAX                           4104    // = sizeof(msg_t)
+
+enum ErrorCode
+{
+       ERR_LOCKFILE_CREATE_FAILED = -101,
+       ERR_ALREADY_RUNNING = -102,
+       ERR_INITIALIZE_SYSTEM_INFO_FAILED = -103,
+       ERR_HOST_SERVER_SOCKET_CREATE_FAILED = -104,
+       ERR_TARGET_SERVER_SOCKET_CREATE_FAILED = -105,
+       ERR_WRONG_MESSAGE_FORMAT = -201,
+       ERR_WRONG_MESSAGE_TYPE = -202,
+       ERR_WRONG_MESSAGE_DATA = -203,
+       ERR_CANNOT_START_PROFILING = -204,
+       ERR_WRONG_PROTOCOL_VERSION = -205
+};
+
+enum TargetMessageType
+{
+       MSG_DEVICE = 1,
+       MSG_TIME = 2,
+       MSG_SAMPLE = 3,
+       MSG_RESOURCE = 4,
+       MSG_LOG = 5,
+       MSG_IMAGE = 6,
+       MSG_TERMINATE = 7,
+       MSG_PID = 8,
+       MSG_MSG = 9,
+       MSG_ALLOC = 10,
+       MSG_ERROR = 11
+};
+
+enum HostMessageType
+{
+       MSG_HOST_BEGIN = 100,
+       MSG_START = 100,
+       MSG_STOP = 101,
+       MSG_PAUSE = 102,
+       MSG_OPTION = 103,
+       MSG_ISALIVE = 104,
+       MSG_ALIVE = 105,
+       MSG_BATT_START = 106,
+       MSG_BATT_STOP = 107,
+       MSG_OK = 901,
+       MSG_NOTOK = 902,
+       MSG_VERSION = 999,
+       MSG_HOST_END = 999
+};
+
+enum DaOptions
+{
+       OPT_CPUMEM              =       0x00000001,
+       OPT_FUNC                =       0x00000002,
+       OPT_ALLOC               =       0x00000004,
+       OPT_FILE                =       0x00000008,
+       OPT_THREAD              =       0x00000010,
+       OPT_UI                  =       0x00000020,
+       OPT_SNAPSHOT    =       0x00000040,
+       OPT_EVENT               =       0x00000080,
+       OPT_RECORD              =       0x00000100
+};
+
+enum DAState
+{
+       DAS_NONE = 0,
+       DAS_START_BEGIN = 1,
+       DAS_TARGET_ARM_START = 1,
+       DAS_TARGET_X86_START = 2,
+       DAS_EMUL_ARM_START = 3,
+       DAS_EMUL_X86_START = 4,
+       DAS_TARGET_ARM_BATT_START = 5,
+       DAS_TARGET_X86_BATT_START = 6,
+       DAS_EMUL_ARM_BATT_START = 7,
+       DAS_EMUL_X86_BATT_START = 8,
+       DAS_START_END = 8,
+       DAS_STOP = 9,
+       DAS_TERMINATE = 10
+};
+
+
+#ifndef likely
+#define likely(x)      __builtin_expect((x), 1)
+#define unlikely(x)    __builtin_expect((x), 0)
+#endif
+
+#if DEBUG
+       #define LOGI(...)       do{ fprintf(stderr, "[INF]" __VA_ARGS__ ); fflush(stderr); } while(0)
+       #define LOGE(...)       do{ fprintf(stderr, "[ERR]" __VA_ARGS__ ); fflush(stderr); } while(0)
+       #define LOGW(...)       do{ fprintf(stderr, "[WRN]" __VA_ARGS__ ); fflush(stderr); } while(0)
+#else
+       #define LOGI(...)       do{} while(0)
+       #define LOGE(...)       do{} while(0)
+       #define LOGW(...)       do{} while(0)
+#endif
+
+#define EVENT_STOP             0x00000001
+#define EVENT_PID              0x00000002
+#define EVENT_ERROR            0x00000004
+
+typedef struct
+{
+       unsigned int    type;
+       unsigned int    length;
+       char                    data[DA_MSG_MAX];
+} msg_t;
+
+typedef struct
+{
+       int                                     control_socket;
+       int                                     data_socket;
+       pthread_mutex_t         data_socket_mutex;
+} __da_host_info;
+
+typedef struct
+{
+       uint64_t                starttime;              // written only by recv thread
+       int64_t                 allocmem;               // written only by recv thread
+       int                             pid;                    // written only by recv thread
+       int                             socket;                 // written only by main thread
+       pthread_t               recv_thread;    // written only by main thread
+       int                             event_fd;               // for thread communication (from recv thread to main thread)
+} __da_target_info;
+
+typedef struct
+{
+       FILE*                           portfile;
+       int                                     host_server_socket;
+       int                                     target_server_socket;
+       int                                     target_count;
+       unsigned int            config_flag;
+       pthread_t                       sampling_thread;
+       __da_host_info          host;
+       __da_target_info        target[MAX_TARGET_COUNT];
+       char                            appPath[128];                           // application executable path
+} __da_manager;
+
+extern __da_manager manager;
+
+void initialize_log();
+int daemonLoop();
+int sendDataToHost(msg_t* log);
+long long get_total_alloc_size();
+
+int makeRecvThread(int index);
+int samplingStart();
+int samplingStop();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DAEMON_H_
diff --git a/daemon/main.c b/daemon/main.c
new file mode 100644 (file)
index 0000000..f3b78f8
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+*  DA manager
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+*
+* Jaewon Lim <jaewon81.lim@samsung.com>
+* Woojin Jung <woojin2.jung@samsung.com>
+* Juyoung Kim <j0.kim@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.
+*
+* Contributors:
+* - S-Core Co., Ltd
+*
+*/
+
+#include <stdio.h>                     // for fopen, fprintf
+#include <stdlib.h>                    // for atexit
+#include <sys/types.h>         // for open
+#include <sys/stat.h>          // for open
+#include <sys/socket.h>                // for socket
+#include <sys/un.h>                    // for sockaddr_un
+#include <arpa/inet.h>         // for sockaddr_in, socklen_t
+
+#include <signal.h>                    // for signal
+#include <unistd.h>                    // for unlink
+#include <fcntl.h>                     // for open, fcntl
+#include <attr/xattr.h>                // for fsetxattr
+
+#include "daemon.h"
+#include "sys_stat.h"
+
+#define SINGLETON_LOCKFILE                     "/tmp/lockfile.da"
+#define PORTFILE                                       "/tmp/port.da"
+#define UDS_NAME                                       "/tmp/da.socket"
+
+#define INIT_PORT                              8001
+#define LIMIT_PORT                             8100
+
+// initialize global variable
+__da_manager manager =
+{
+       NULL, -1, -1,                                                           // portfile pointer, host / target server socket
+       0,                                                                              // target count
+       0,                                                                              // config_flag
+       -1,                                                                             // sampling_thread handle
+       {-1, -1, PTHREAD_MUTEX_INITIALIZER},    // host
+       {{0L, }, },                                                             // target
+       {0, }                                                                   // appPath
+};
+
+// ==============================================================================
+// util functions
+// ==============================================================================
+
+static void writeToPortfile(int code)
+{
+       if(unlikely(manager.portfile == 0))
+               return;
+
+       fprintf(manager.portfile, "%d", code);
+}
+
+// ==============================================================================
+// atexit functions
+// ==============================================================================
+
+void _close_server_socket(void)
+{
+       LOGI("close_server_socket\n");
+       // close server socket
+       if(manager.host_server_socket != -1)
+               close(manager.host_server_socket);
+       if(manager.target_server_socket != -1)
+               close(manager.target_server_socket);
+}
+
+static void _unlink_file(void)
+{
+       LOGI("unlink files\n");
+       unlink(PORTFILE);
+       unlink(SINGLETON_LOCKFILE);
+}
+
+// ===============================================================================
+// making sockets
+// ===============================================================================
+
+// return 0 for normal case
+static int makeTargetServerSocket()
+{
+       struct sockaddr_un serverAddrUn;
+
+       if(manager.target_server_socket != -1)
+               return -1;      // should be never happend
+
+       // remove existed unix domain socket file
+       unlink(UDS_NAME);
+
+       if ((manager.target_server_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+       {
+               LOGE("Target server socket creation failed\n");
+               return -1;
+       }
+
+       // set smack attribute for certification
+       fsetxattr(manager.target_server_socket, "security.SMACK64IPIN", "*", 1, 0);
+       fsetxattr(manager.target_server_socket, "security.SMACK64IPOUT", "*", 1, 0);
+
+       bzero(&serverAddrUn, sizeof(serverAddrUn));
+       serverAddrUn.sun_family = AF_UNIX;
+       sprintf(serverAddrUn.sun_path, "%s", UDS_NAME);
+
+       if (-1 == bind(manager.target_server_socket, (struct sockaddr*) &serverAddrUn,
+                                       sizeof(serverAddrUn)))
+       {
+               LOGE("Target server socket binding failed\n");
+               return -1;
+       }
+
+       chmod(serverAddrUn.sun_path, 0777);
+
+       if (-1 == listen(manager.target_server_socket, 5))
+       {
+               LOGE("Target server socket listening failed\n");
+               return -1;
+       }
+
+       LOGI("Created TargetSock %d\n", manager.target_server_socket);
+       return 0;
+}
+
+// return port number for normal case
+// return negative value for error case
+static int makeHostServerSocket()
+{
+       struct sockaddr_in serverAddrIn;
+       int opt = 1;
+       int port;
+
+       if(manager.host_server_socket != -1)
+               return -1;      // should be never happened
+
+       if ((manager.host_server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+       {
+               LOGE("Host server socket creation failed\n");
+               return -1;
+       }
+
+       setsockopt(manager.host_server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+       memset(&serverAddrIn, 0, sizeof(serverAddrIn));
+       serverAddrIn.sin_family = AF_INET;
+       serverAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
+
+       // bind address to server socket
+       for(port = INIT_PORT; port < LIMIT_PORT; port++)
+       {
+               serverAddrIn.sin_port = htons(port);
+               if (0 == bind(manager.host_server_socket, (struct sockaddr*) &serverAddrIn, sizeof(serverAddrIn)))
+                       break;
+       }
+
+       if(port == LIMIT_PORT)
+       {
+               LOGE("Host server socket binding failed\n");
+               return -1;
+       }
+
+       // enter listen state from client
+       if (-1 == listen(manager.host_server_socket, 5))
+       {
+               LOGE("Host server socket listening failed\n");
+               return -1;
+       }
+
+       LOGI("Created HostSock %d\n", manager.host_server_socket);
+       return port;
+}
+
+// ===============================================================================
+// initializing / finalizing functions
+// ===============================================================================
+
+static int singleton(void)
+{
+       struct flock fl;
+       int fd;
+
+       fd = open(SINGLETON_LOCKFILE, O_RDWR | O_CREAT, 0600);
+       if(fd < 0)
+       {
+               writeToPortfile(ERR_LOCKFILE_CREATE_FAILED);
+               LOGE("singleton lock file creation failed");
+               return -1;
+       }
+
+       fl.l_start = 0;
+       fl.l_len = 0;
+       fl.l_type = F_WRLCK;
+       fl.l_whence = SEEK_SET;
+       if(fcntl(fd, F_SETLK, &fl) < 0)
+       {
+               writeToPortfile(ERR_ALREADY_RUNNING);
+               LOGE("another instance of daemon is already running");
+               return -1;
+       }
+
+       return 0;
+}
+
+// return 0 for normal case
+static int initializeManager()
+{
+       int i;
+
+       atexit(_close_server_socket);
+
+       if(initialize_system_info() < 0)
+       {
+               writeToPortfile(ERR_INITIALIZE_SYSTEM_INFO_FAILED);
+               return -1;
+       }
+
+       // make server socket
+       if(makeTargetServerSocket() != 0)
+       {
+               writeToPortfile(ERR_TARGET_SERVER_SOCKET_CREATE_FAILED);
+               return -1;
+       }
+
+       i = makeHostServerSocket();
+       if(i < 0)
+       {
+               writeToPortfile(ERR_HOST_SERVER_SOCKET_CREATE_FAILED);
+               return -1;
+       }
+       else    // host server socket creation succeed
+       {
+               writeToPortfile(i);
+       }
+
+       LOGI("SUCCESS to write port\n");
+
+       // initialize target client sockets
+       for (i = 0; i < MAX_TARGET_COUNT; i++)
+       {
+               manager.target[i].pid = -1;
+               manager.target[i].socket = -1;
+               manager.target[i].event_fd = -1;
+               manager.target[i].recv_thread = -1;
+               manager.target[i].allocmem = 0;
+               manager.target[i].starttime = 0;
+       }
+       manager.target_count = 0;
+
+       // initialize sendMutex
+       pthread_mutex_init(&(manager.host.data_socket_mutex), NULL);
+
+       return 0;
+}
+
+static int finalizeManager()
+{
+       finalize_system_info();
+
+       LOGI("Finalize daemon\n");
+
+       // close host client socket
+       if(manager.host.control_socket != -1)
+               close(manager.host.control_socket);
+       if(manager.host.data_socket != -1)
+               close(manager.host.data_socket);
+
+       return 0;
+}
+
+// main function
+int main()
+{
+       int result;
+       initialize_log();
+
+       atexit(_unlink_file);
+
+       manager.portfile = fopen(PORTFILE, "w");
+       if(manager.portfile == NULL)
+       {
+               LOGE("cannot create portfile");
+               return 1;
+       }
+
+       if(singleton() < 0)
+               return 1;
+
+       //for terminal exit
+       signal(SIGHUP, SIG_IGN);
+       chdir("/");
+
+       //new session reader
+       setsid();
+
+       // initialize manager
+       result = initializeManager();
+       fclose(manager.portfile);
+       if(result == 0)
+       {
+               //daemon work
+               daemonLoop();
+
+               finalizeManager();
+               return 0;
+       }
+       else
+       {
+               return 1;
+       }
+}
index 9bc4350..1562957 100644 (file)
 */ 
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <stdbool.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/vfs.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <dirent.h>
 #endif
 
 #include "sys_stat.h"
-#include "da_debug.h"
+#include "daemon.h"
 
 // defines for runtime environment
 #define FOR_EACH_CPU
 
-
 #define BUFFER_MAX                     1024
 #define LARGE_BUFFER           512
 #define MIDDLE_BUFFER          256
 #define DA_PROBE_TIZEN_SONAME          "da_probe_tizen.so"
 #define DA_PROBE_OSP_SONAME                    "da_probe_osp.so"
 
-#ifndef likely
-#define likely(x)      __builtin_expect((x), 1)
-#define unlikely(x)    __builtin_expect((x), 0)
-#endif
-
 enum PROCESS_DATA
 {
        PROCDATA_STAT,
        PROCDATA_SMAPS
 };
 
-long long get_total_alloc_size();
-
 // declared by greatim
 static int Hertz = 0;
 static int num_of_cpu = 0;
@@ -98,19 +94,6 @@ static unsigned long mem_slot_array[MEM_SLOT_MAX];
 static CPU_t* cpus = NULL;
 static unsigned long probe_so_size = 0;
 
-// utility function
-int get_flag_num(unsigned int flag)
-{
-       int i;
-       for(i = 0; flag != 0; i++)
-       {
-               flag &= (flag - 1);
-       }
-       return i;
-}
-
-
-
 // daemon api : get status from file
 // pfd must not be null
 int get_file_status(int* pfd, const char* filename)
index 91e2091..d714cd4 100644 (file)
 extern "C" {
 #endif
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <string.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/vfs.h>
-
 #define CHARGERFD                                      "/sys/class/power_supply/battery/charge_now"
 #define VOLTAGEFD                                      "/sys/class/power_supply/battery/voltage_now"
 
diff --git a/daemon/threads.c b/daemon/threads.c
new file mode 100644 (file)
index 0000000..1c50934
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+*  DA manager
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+*
+* Jaewon Lim <jaewon81.lim@samsung.com>
+* Woojin Jung <woojin2.jung@samsung.com>
+* Juyoung Kim <j0.kim@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.
+*
+* Contributors:
+* - S-Core Co., Ltd
+*
+*/
+
+#include <stdio.h>
+#include <stdlib.h>                    // for atoi, atol
+#include <string.h>                    // for strchr
+#include <stdint.h>                    // for uint64_t
+#include <sys/types.h>         // for recv
+#include <sys/socket.h>                // for recv
+#include <sys/time.h>          // for setitimer
+#include <signal.h>                    // for sigemptyset, sigset_t, sigaddset, ...
+#include <unistd.h>                    // for write
+
+#include "daemon.h"
+#include "utils.h"
+#include "sys_stat.h"
+
+#define TIMER_INTERVAL_SEC                     1
+#define TIMER_INTERVAL_USEC                    0
+
+static void* recvThread(void* data)
+{
+       int index = (int)data;
+       uint64_t event;
+       ssize_t recvLen;
+       msg_t log;
+
+       // initialize target variable
+       manager.target[index].pid = -1;
+       manager.target[index].starttime = 0;
+       manager.target[index].allocmem = 0;
+
+       while(1)
+       {
+               // read from target process
+               recvLen = recv(manager.target[index].socket, &log,
+                               sizeof(log.type) + sizeof(log.length), MSG_WAITALL);
+
+               if(unlikely(recvLen < sizeof(log.type) + sizeof(log.length)))
+               {       // disconnect
+                       event = EVENT_STOP;
+                       write(manager.target[index].event_fd, &event, sizeof(uint64_t));
+                       break;
+               }
+
+               // send to host
+               if (likely(log.length > 0))
+               {
+                       recvLen = recv(manager.target[index].socket, log.data, log.length, MSG_WAITALL);
+                       if(unlikely(recvLen != log.length))     // consume as disconnect
+                       {
+                               event = EVENT_STOP;
+                               write(manager.target[index].event_fd, &event, sizeof(uint64_t));
+                               break;
+                       }
+               }
+
+               log.data[log.length] = '\0';
+               if(log.type == MSG_ALLOC)
+               {
+                       manager.target[index].allocmem = str_to_int64(log.data);
+                       continue;               // don't send to host
+               }
+               else if(log.type == MSG_PID)
+               {
+                       LOGI("MSG_PID arrived : %s\n", log.data);
+
+                       // only when first MSG_PID is arrived
+                       if(manager.target[index].pid == -1)
+                       {
+                               char* barloc;
+                               barloc = strchr(log.data, '|');
+                               if(barloc == NULL)
+                               {
+                                       // MSG_PID parsing error
+                                       // send error message to host
+                                       log.type = MSG_ERROR;
+                                       log.length = sprintf(log.data, "Process id information of target application is not correct.");
+                                       sendDataToHost(&log);
+
+                                       // send stop message to main thread
+                                       event = EVENT_STOP;
+                                       write(manager.target[index].event_fd, &event, sizeof(uint64_t));
+                                       break;
+                               }
+                               barloc[0] = '\0';
+                               barloc++;
+
+                               manager.target[index].pid = atoi(log.data);
+                               manager.target[index].starttime = str_to_uint64(barloc);
+
+                               event = EVENT_PID;
+                               write(manager.target[index].event_fd, &event, sizeof(uint64_t));
+                       }
+                       continue;               // don't send to host
+               }
+               else if(log.type == MSG_TERMINATE)
+               {
+                       // send stop message to main thread
+                       event = EVENT_STOP;
+                       write(manager.target[index].event_fd, &event, sizeof(uint64_t));
+                       break;
+               }
+#ifdef PRINT_TARGET_LOG
+               else if(log.type == MSG_LOG)
+               {
+                       switch(log.data[0])
+                       {
+                               case '2':       // UI control creation log
+                               case '3':       // UI event log
+                               case '6':       // UI lifecycle log
+                               case '7':       // screenshot log
+                               case '8':       // scene transition log
+                                       LOGI("%dclass|%s\n", log.data[0] - '0', log.data);
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               else if(log.type == MSG_IMAGE)
+               {
+                       LOGI("MSG_IMAGE received\n");
+               }
+               else    // not MSG_LOG and not MSG_IMAGE
+               {
+                       LOGI("Extra MSG TYPE (%d|%d|%s)\n", log.type, log.length, log.data);
+               }
+#endif
+
+               // any message before MSG_PID message arrived did not be sent to host
+               if(manager.target[index].pid != -1)
+                       sendDataToHost(&log);
+       }
+
+       manager.target[index].recv_thread = -1;
+       return NULL;
+}
+
+int makeRecvThread(int index)
+{
+       if(manager.target[index].socket == -1)
+               return -1;
+
+       if(pthread_create(&(manager.target[index].recv_thread), NULL, recvThread, (void*)index) < 0)
+       {
+               LOGE("Failed to create recv thread for socket (%d)\n", manager.target[index].socket);
+               return -1;
+       }
+
+       return 0;
+}
+
+static void* samplingThread(void* data)
+{
+       int err, signo, i;
+       int pidarray[MAX_TARGET_COUNT];
+       int pidcount;
+       sigset_t waitsigmask;
+       msg_t log;
+
+       LOGI("sampling thread started\n");
+
+       sigemptyset(&waitsigmask);
+       sigaddset(&waitsigmask, SIGALRM);
+       sigaddset(&waitsigmask, SIGUSR1);
+
+       while(1)
+       {
+               err = sigwait(&waitsigmask, &signo);
+               if(err != 0)
+               {
+                       LOGE("Failed to sigwait() in sampling thread\n");
+                       continue;
+               }
+
+               if(signo == SIGALRM)
+               {
+                       pidcount = 0;
+                       for(i = 0; i < MAX_TARGET_COUNT; i++)
+                       {
+                               if(manager.target[i].socket != -1 && manager.target[i].pid != -1)
+                                       pidarray[pidcount++] = manager.target[i].pid;
+                       }
+
+                       log.length = get_resource_info(log.data, DA_MSG_MAX, pidarray, pidcount);
+                       if(log.length >= 0)
+                       {
+                               log.type = MSG_RESOURCE;
+                               sendDataToHost(&log);
+                       }
+               }
+               else if(signo == SIGUSR1)
+               {
+                       // end this thread
+                       break;
+               }
+               else
+               {
+                       // not happened
+                       LOGE("This should not be happend in sampling thread\n");
+               }
+       }
+
+       LOGI("sampling thread ended\n");
+       return NULL;
+}
+
+
+// return 0 if normal case
+// return minus value if critical error
+// return plus value if non-critical error
+int samplingStart()
+{
+       sigset_t newsigmask;
+       struct itimerval timerval;
+
+       if(manager.sampling_thread != -1)       // already started
+               return 1;
+
+       sigemptyset(&newsigmask);
+       sigaddset(&newsigmask, SIGALRM);
+       sigaddset(&newsigmask, SIGUSR1);
+       if(pthread_sigmask(SIG_BLOCK, &newsigmask, NULL) != 0)
+       {
+               LOGE("Failed to signal masking for main thread\n");
+               return -1;
+       }
+
+       if(pthread_create(&(manager.sampling_thread), NULL, samplingThread, NULL) < 0)
+       {
+               LOGE("Failed to create sampling thread\n");
+               return -1;
+       }
+
+       timerval.it_interval.tv_sec = TIMER_INTERVAL_SEC;
+       timerval.it_interval.tv_usec = TIMER_INTERVAL_USEC;
+       timerval.it_value.tv_sec = TIMER_INTERVAL_SEC;
+       timerval.it_value.tv_usec = TIMER_INTERVAL_USEC;
+       setitimer(ITIMER_REAL, &timerval, NULL);
+
+       return 0;
+}
+
+int samplingStop()
+{
+       if(manager.sampling_thread != -1)
+       {
+               struct itimerval stopval;
+//             int status;
+//             sigset_t oldsigmask;
+//             sigemptyset(&oldsigmask);
+//             sigaddset(&oldsigmask, SIGALRM);
+//             sigaddset(&oldsigmask, SIGUSR1);
+
+               // stop timer
+               stopval.it_interval.tv_sec = 0;
+               stopval.it_interval.tv_usec = 0;
+               stopval.it_value.tv_sec = 0;
+               stopval.it_value.tv_usec = 0;
+               setitimer(ITIMER_REAL, &stopval, NULL);
+
+               pthread_kill(manager.sampling_thread, SIGUSR1);
+               pthread_join(manager.sampling_thread, NULL);
+
+               // this code commented because this phrase occurs an error
+//             if(sigprocmask(SIG_UNBLOCK, &oldsigmask, NULL) < 0)
+//             {
+//                     LOGE("Failed to pthread_sigmask\n");
+//             }
+               manager.sampling_thread = -1;
+       }
+
+       return 0;
+}
index 13070ff..c6278db 100644 (file)
 *
 */ 
 
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
 #include <pthread.h>
+#include <unistd.h>            // for unlink
+#include <dirent.h>            // for opendir, readdir
+#include <sys/types.h> // for open
+#include <sys/stat.h>  // for open
+#include <fcntl.h>             // for open
+#include <grp.h>               // for setgroups
+
+#include "daemon.h"
 #include "utils.h"
-#include "da_debug.h"
 
-#define BUFFER_MAX             1024
+#define BUFFER_MAX                     1024
+#define APP_GROUPS_MAX         100
+#define APP_GROUP_LIST         "/usr/share/privilege-control/app_group_list"
+#define SELF_LABEL_FILE                "/proc/self/attr/current"
+#define SMACK_LABEL_LEN                255
+#define SID_APP                                5000
 
-static int file_fd = -1;
+#define APPDIR1                                "/opt/apps/"
+#define APPDIR2                                "/opt/usr/apps/"
 
-static pthread_mutex_t write_mutex;
+uint64_t str_to_uint64(char* str)
+{
+       uint64_t res = 0;
+       
+       if(str != NULL)
+       {
+               while(*str >= '0' && *str <= '9')
+               {
+                       res = res * 10 + (*str - '0');
+                       str++;
+               }
+       }
 
-// get application name from executable binary path
-char* get_app_name(char* binary_path)
+       return res;
+}
+
+int64_t str_to_int64(char* str)
 {
-       char* pos;
+       int64_t res = 0;
+       int64_t factor = 1;
+       
+       if(str != NULL)
+       {
+               if(*str == '-')
+               {
+                       factor = -1;
+                       str++;
+               }
+               else if(*str == '+')
+               {
+                       factor = 1;
+                       str++;
+               }
 
-       pos = strrchr(binary_path, '/');
-       if(pos != NULL)
-               pos++;
+               while(*str >= '0' && *str <= '9')
+               {
+                       res = res * 10 + (*str - '0');
+                       str++;
+               }
+       }
 
-       return pos;
+       return (res * factor);
 }
 
-// execute applcation with executable binary path
-// return 0 to fail to execute
-// return 1 to succeed to execute
-int exec_app(const char* exec_path, int app_type)
+int read_line(const int fd, char* ptr, const unsigned int maxlen)
 {
-       pid_t   pid;
-       char command[PATH_MAX];
+       unsigned int n = 0;
+       char c[2];
+       int rc;
 
-       if (exec_path == NULL || strlen(exec_path) <= 0) 
+       while(n != maxlen)
        {
-               LOGE("Executable path is not correct\n");
-               return 0;
+               if((rc = read(fd, c, 1)) != 1)
+                       return -1; // eof or read err
+
+               if(*c == '\n')
+               {
+                       ptr[n] = 0;
+                       return n;
+               }
+               ptr[n++] = *c;
        }
+       return -1; // no space
+}
 
-       if (( pid = fork()) < 0)        // fork error
-       return 0;
+int smack_set_label_for_self(const char *label)
+{
+       int len;
+       int fd;
+       int ret;
 
-    else if(pid > 0)
-       return 1;               // exit parent process with successness
+       len = strnlen(label, SMACK_LABEL_LEN + 1);
+       if (len > SMACK_LABEL_LEN)
+               return -1;
+
+       fd = open(SELF_LABEL_FILE, O_WRONLY);
+       if (fd < 0)
+               return -1;
 
-       sprintf(command, "%s %s", DA_PRELOAD(app_type), exec_path);
-       LOGI("launch app path is %s, executable path is %s\n", LAUNCH_APP_PATH, exec_path);
-       execl(SHELL_CMD, SHELL_CMD, "-c", command, NULL);
+       ret = write(fd, label, len);
+       close(fd);
 
-       return 1;
+       return (ret < 0) ? -1 : 0;
 }
 
-#ifdef USE_LAUNCH_PAD
-// execute application by launch pad
-// return 0 to fail to execute
-// return 1 to succeed to execute
-int exec_app_by_launchpad(const char* pkg_name)
+void set_appuser_groups(void)
 {
-       pid_t   pid;
-
-       if (pkg_name == NULL || strlen(pkg_name) <= 0) 
+       int fd = 0;
+       char buffer[5];
+       gid_t t_gid = -1;
+       gid_t groups[APP_GROUPS_MAX] = {0, };
+       int cnt = 0;
+
+       // groups[cnt++] = SID_DEVELOPER;
+       fd = open(APP_GROUP_LIST, O_RDONLY);
+       if(fd < 0)
        {
-               LOGE("Package name is not correct\n");
-               return 0;
+               LOGE("cannot get app's group lists from %s", APP_GROUP_LIST);
+               return;
        }
 
-       if (( pid = fork()) < 0)        // fork error
-       return 0;
+       for(;;)
+       {
+               if(read_line(fd, buffer, sizeof buffer) < 0)
+               {
+                       break;
+               }
 
-    else if(pid > 0)
-       return 1;               // exit parent process with successness
+               t_gid = strtoul(buffer, 0, 10);
+               errno = 0;
+               if(errno != 0)
+               {
+                       LOGE("cannot change string to integer: [%s]\n", buffer);
+                       continue;
+               }
 
-       LOGI("launch app path is %s, pkg name is %s\n", LAUNCH_APP_PATH, pkg_name);
-       execl(LAUNCH_APP_PATH, LAUNCH_APP_NAME, pkg_name, DA_PRELOAD_EXEC, NULL);
+               if(t_gid)
+               {
+                       if(cnt < APP_GROUPS_MAX)
+                       {
+                               groups[cnt++] = t_gid;
+                       }
+                       else
+                       {
+                               LOGE("cannot add groups more than %d", APP_GROUPS_MAX);
+                               break;
+                       }
+               }
+       }
 
-       return 1;
+       if(cnt > 0)
+       {
+               if(setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0)
+               {
+                       fprintf(stderr, "set groups failed errno: %d\n", errno);
+                       exit(1);
+               }
+       }
 }
-#endif
 
-#if 0
-void kill_app(const char* binary_path)         // fork version
+int get_smack_label(const char* execpath, char* buffer, int buflen)
 {
-       pid_t pid;
-       pid_t pkg_pid;
-       char command[PATH_MAX];
+       int i, ret = 0;
+       char* temp;
+       if(strncmp(execpath, APPDIR1, strlen(APPDIR1)) == 0)
+       {
+               execpath = execpath + strlen(APPDIR1);
+               temp = strchr(execpath, '/');
+               for(i = 0; i < strlen(execpath) ; i++)
+               {
+                       if(execpath + i == temp)
+                               break;
+                       buffer[i] = execpath[i];
+               }
+               buffer[i] = '\0';
+       }
+       else if(strncmp(execpath, APPDIR2, strlen(APPDIR2)) == 0)
+       {
+               execpath = execpath + strlen(APPDIR2);
+               temp = strchr(execpath, '/');
+               for(i = 0; i < strlen(execpath) ; i++)
+               {
+                       if(execpath + i == temp)
+                               break;
+                       buffer[i] = execpath[i];
+               }
+               buffer[i] = '\0';
+       }
+       else
+       {
+               ret = -1;
+       }
 
-       if (( pid = fork()) < 0)
-       return;
+       return ret;
+}
 
-    //exit parent process
-    else if(pid > 0)
-       return;
-       
-       pkg_pid = find_pid_from_path(binary_path);
+// return 0 if succeed
+// return -1 if error occured
+int remove_indir(const char *dirname)
+{
+       DIR *dir;
+       struct dirent *entry;
+       char path[PATH_MAX];
 
-       if(pkg_pid > 0)
+       dir = opendir(dirname);
+       if(dir == NULL)
        {
-               sprintf(command, "kill -9 %d", pkg_pid);
-               LOGI(" : %s\n", command);
-               execl(SHELL_CMD, SHELL_CMD, "-c", command, NULL);
+               return -1;
        }
-       else
+
+       while((entry = readdir(dir)) != NULL)
        {
-               exit(0);
+               if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
+               {
+                       snprintf(path, (size_t) PATH_MAX, "%s/%s", dirname, entry->d_name);
+                       if (entry->d_type != DT_DIR)    // file
+                       {
+                               unlink(path);
+                       }
+                       else { }        // directory
+               }
        }
+       closedir(dir);
+
+       return 0;
 }
-#else
-void kill_app(const char* binary_path)         // non fork version
+
+// get application name from executable binary path
+char* get_app_name(char* binary_path)
 {
-       pid_t pkg_pid;
+       char* pos;
+
+       pos = strrchr(binary_path, '/');
+       if(pos != NULL)
+               pos++;
+
+       return pos;
+}
+
+// execute applcation with executable binary path
+// return 0 to fail to execute
+// return 1 to succeed to execute
+int exec_app(const char* exec_path, int app_type)
+{
+       pid_t   pid;
        char command[PATH_MAX];
+       char appid[SMACK_LABEL_LEN];
 
-       pkg_pid = find_pid_from_path(binary_path);
+       if (exec_path == NULL || strlen(exec_path) <= 0) 
+       {
+               LOGE("Executable path is not correct\n");
+               return 0;
+       }
 
-       if(pkg_pid > 0)
+       if (( pid = fork()) < 0)        // fork error
+       return 0;
+
+    else if(pid > 0)
+       return 1;               // exit parent process with successness
+
+       if(get_smack_label(exec_path, appid, SMACK_LABEL_LEN) < 0)
        {
-               sprintf(command, "kill -9 %d", pkg_pid);
-               LOGI("kill app : %s\n", command);
-               system(command);
+               LOGE("failed to get smack label\n");
+               return 0;
+       }
+       else
+       {
+               LOGI("smack lable is %s\n", appid);
+               if(smack_set_label_for_self(appid) < 0)
+               {
+                       LOGE("failed to set label for self\n");
+               }
+
+               set_appuser_groups();
+               if(setgid(SID_APP) < 0)
+               {
+                       LOGE("failed to setgid\n");
+               }
+               if(setuid(SID_APP) < 0)
+               {
+                       LOGE("failed to setuid\n");
+               }
+               sprintf(command, "%s %s", DA_PRELOAD(app_type), exec_path);
+               LOGI("launch app path is %s, executable path is %s\n", LAUNCH_APP_PATH, exec_path);
+               execl(SHELL_CMD, SHELL_CMD, "-c", command, NULL);
+               return 1;
        }
 }
-#endif
 
 // find process id from executable binary path
 pid_t find_pid_from_path(const char* path)
@@ -183,78 +357,215 @@ pid_t find_pid_from_path(const char* path)
        return status;
 }
 
-static void mkdirs()
+void kill_app(const char* binary_path)
 {
-       mkdir("/home/developer/sdk_tools/da", 0775);
-       mkdir("/home/developer/sdk_tools/da/battery", 0775);
+       pid_t pkg_pid;
+       char command[PATH_MAX];
+
+       pkg_pid = find_pid_from_path(binary_path);
+       if(pkg_pid > 0)
+       {
+               sprintf(command, "kill -9 %d", pkg_pid);
+               system(command);
+       }
 }
 
-int create_open_batt_log(const char* app_name) 
+int get_app_type(char* appPath)
 {
-       char log_path[PATH_MAX];
+       int fd;
+       char buf[BUFFER_MAX];
 
-       pthread_mutex_init(&write_mutex, NULL);
-       sprintf(log_path, "%s%s", BATT_LOG_FILE, app_name);
-
-       if ((file_fd = open(log_path, O_WRONLY|O_CREAT|O_TRUNC)) == -1)
+       sprintf(buf, "%s.exe", appPath);
+       fd = open(buf, O_RDONLY);
+       if(fd != -1)
        {
-               mkdirs();
-               if ((file_fd = open(log_path, O_WRONLY|O_CREAT|O_TRUNC)) == -1)
-               {               
-                       LOGE("Failed to open batt log file\n");
-                       return 0;
-               }
+               close(fd);
+               return APP_TYPE_OSP;
+       }
+       else
+       {
+               return APP_TYPE_TIZEN;
        }
-
-       return file_fd;
 }
 
-int get_batt_fd()
+int get_executable(char* appPath, char* buf, int buflen)
 {
-       return file_fd;
+       int fd;
+
+       sprintf(buf, "%s.exe", appPath);
+       fd = open(buf, O_RDONLY);
+       if(fd != -1)
+       {
+               close(fd);
+       }
+       else
+       {
+               strcpy(buf, appPath);
+       }
+       return 0;
 }
 
-int write_batt_log(const char* msg) 
+int get_app_install_path(char *strAppInstall, int length)
 {
-       int length = -1;
+       FILE *fp;
+       char buf[BUFFER_MAX];
+       char *p;
+       int i;
 
-       if (file_fd == -1 ) 
+       if ((fp = fopen(DA_INSTALL_PATH, "r")) == NULL)
        {
+               LOGE("Failed to open %s\n", DA_INSTALL_PATH);
                return -1;
        }
 
-       pthread_mutex_lock(&write_mutex);
+       /*ex : <15>   DW_AT_comp_dir    : (indirect string, offset: 0x25f): /home/yt/workspace/templatetest/Debug-Tizen-Emulator        */
+       while (fgets(buf, BUFFER_MAX, fp) != NULL)
+       {
+               //name
+               p = buf;
+               for (i = 0; i < BUFFER_MAX; i++)
+               {
+                       if (*p == ':')
+                               break;
+                       p++;
+               }
+
+               if (*p != ':')
+                       break;
+               else
+                       p++;
 
-       length = write(file_fd, msg, strlen(msg));
+               //(...,offset:...)
+               for (; i < BUFFER_MAX; i++)
+               {
+                       if (*p == '(')
+                       {
+                               while (*p != ')')
+                               {
+                                       p++;
+                               }
+                       }
+                       if (*p == ':')
+                               break;
+                       p++;
+               }
 
-       pthread_mutex_unlock(&write_mutex);
+               //find
+               if (*p != ':')
+                       break;
+               for (; i < BUFFER_MAX; i++)
+               {
+                       if (*p == ':' || *p == ' ' || *p == '\t')
+                               p++;
+                       else
+                               break;
+               }
 
-       return length;
+               //name
+               if (strlen(p) <= length)
+               {
+                       sprintf(strAppInstall, "%s", p);
+                       for (i = 0; i < strlen(p); i++)
+                       {
+                               if (strAppInstall[i] == '\n' || strAppInstall[i] == '\t')
+                               {
+                                       strAppInstall[i] = '\0';
+                                       break;
+                               }
+                       }
+                       fclose(fp);
+                       return 1;
+               }
+       }
+       fclose(fp);
+       return -1;
 }
 
-void close_batt_fd()
+int is_app_built_pie(void)
 {
-       close(file_fd);
-       file_fd = -1;
+       int result;
+       FILE *fp;
+       char buf[BUFFER_MAX];
+
+       if((fp = fopen(DA_BUILD_OPTION, "r")) == NULL)
+       {
+               LOGE("Failed to open %s\n", DA_BUILD_OPTION);
+               return -1;
+       }
+
+       if(fgets(buf, BUFFER_MAX, fp) != NULL)
+       {
+               if(strcmp(buf, "DYN\n") == 0)
+                       result = 1;
+               else if(strcmp(buf, "EXEC\n") == 0)
+                       result = 0;
+               else
+                       result = -1;
+       }
+       else
+       {
+               result = -1;
+       }
+       fclose(fp);
+
+       return result;
 }
 
-#if DEBUG
-void write_log()
+int get_app_base_address(int *baseAddress)
 {
-    int fd;
+       int res;
+       FILE *fp;
+       char buf[BUFFER_MAX];
 
-    fd = open("/dev/null", O_RDONLY);
-    dup2(fd, 0);
+       if((fp = fopen(DA_BASE_ADDRESS, "r")) == NULL)
+       {
+               LOGE("Failed to open %s\n", DA_BASE_ADDRESS);
+               return -1;
+       }
 
-    fd = open("/tmp/da_daemon.log", O_WRONLY | O_CREAT | O_TRUNC, 0640);
-    if(fd < 0) {
-        fd = open("/dev/null", O_WRONLY);
-    }
-    dup2(fd, 1);
-    dup2(fd, 2);
+       if(fgets(buf, BUFFER_MAX, fp) != NULL)
+       {
+               res = sscanf(buf, "%x", baseAddress);
+       }
+       else
+       {
+               res = -1;
+       }
+       fclose(fp);
 
-    fprintf(stderr,"--- da starting (pid %d) ---\n", getpid());
+       return res;
 }
+
+int is_same_app_process(char* appPath, int pid)
+{
+       int ret = 0;
+       FILE *fp;
+       char buf[BUFFER_MAX];
+       char cmdPath[PATH_MAX];
+       char execPath[PATH_MAX];
+
+       get_executable(appPath, execPath, PATH_MAX);
+       sprintf(cmdPath, "/proc/%d/cmdline", pid);
+
+       if((fp = fopen(cmdPath, "r")) == NULL)
+       {
+               return 0;
+       }
+
+       if(fgets(buf, BUFFER_MAX, fp) != NULL)
+       {
+#ifdef RUN_APP_LOADER
+               if(strcmp(buf, appPath) == 0)
+#else
+               // use execPath instead of manager.appPath
+               if(strcmp(buf, execPath) == 0)
 #endif
+                       ret = 1;
+               else
+                       ret = 0;
+       }
+       fclose(fp);
 
+       return ret;
+}
 
index 1df092a..b0f72b9 100644 (file)
 *
 */ 
 
-#ifndef _UTILS_
-#define _UTILS_
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <linux/limits.h>
-
 #define LAUNCH_APP_PATH                        "/usr/bin/launch_app"
 #define KILL_APP_PATH                  "/usr/bin/pkill"
 #define LAUNCH_APP_NAME                        "launch_app"
@@ -52,12 +46,21 @@ extern "C" {
 #define BATT_LOG_FILE                  "/home/developer/sdk_tools/da/battery/"
 #define SHELL_CMD                              "/bin/sh"
 
+#define DA_INSTALL_PATH                "/home/developer/sdk_tools/da/da_install_path"
+#define DA_BUILD_OPTION                "/home/developer/sdk_tools/da/da_build_option"
+#define DA_BASE_ADDRESS                "/home/developer/sdk_tools/da/da_base_address"
+
 enum ApplicationType
 {
        APP_TYPE_TIZEN = 0,
        APP_TYPE_OSP = 1
 };
 
+uint64_t       str_to_uint64(char* str);
+int64_t                str_to_int64(char* str);
+
+int remove_indir(const char *dirname);
+
 char* get_app_name(char* binary_path);
 
 int exec_app(const char* exec_path, int app_type);
@@ -66,18 +69,12 @@ void kill_app(const char* binary_path);
 
 pid_t find_pid_from_path(const char* path);
 
-int create_open_batt_log(const char* app_name);
-
-int get_batt_fd();
-
-int write_batt_log(const char* message);
-
-void close_batt_fd();
-
-#if DEBUG
-void write_log();
-#endif
-
+int get_app_type(char* appPath);
+int get_executable(char* appPath, char* buf, int buflen);
+int get_app_install_path(char *strAppInstall, int length);
+int is_app_built_pie(void);
+int get_app_base_address(int *baseAddress);
+int is_same_app_process(char* appPath, int pid);
 
 #ifdef __cplusplus
 }
index 9e4a606..86d2e79 100644 (file)
@@ -1,10 +1,11 @@
 Name:       dynamic-analysis-manager
 Summary:    dynamic analyzer manager
-Version:    2.1.0
+Version:    2.1.1
 Release:    1
 Group:      System/Libraries
 License:       Apache License, Version 2
 Source:    %{name}_%{version}.tar.gz
+BuildRequires:  libattr-devel
 BuildRequires:  glib2-devel
 BuildRequires:  aul-devel
 BuildRequires:  vconf-devel