Feature:Add startup debugging

Signed-off-by: hongtao <hongtao11@huawei.com>
Change-Id: I9b6ca62889de20fd3815869f7bb877168ab96e11
This commit is contained in:
hongtao 2023-04-13 15:47:25 +08:00
parent e390a02aa6
commit 09bd6b1032
4 changed files with 72 additions and 0 deletions

View File

@ -17,12 +17,14 @@
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <sched.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
@ -124,6 +126,12 @@ int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *l
return ret, "Failed to setCapabilities");
}
if (content->waitForDebugger) {
ret = content->waitForDebugger(client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret);
return ret, "Failed to waitForDebugger");
}
// notify success to father process and start app process
NotifyResToParent(content, client, 0);
return 0;

View File

@ -73,6 +73,7 @@ typedef struct AppSpawnContent_ {
int (*getWrapBundleNameValue)(struct AppSpawnContent_ *content, AppSpawnClient *client);
int (*setSeccompFilter)(struct AppSpawnContent_ *content, AppSpawnClient *client);
void (*handleInternetPermission)(const AppSpawnClient *client);
int (*waitForDebugger)(AppSpawnClient *client);
} AppSpawnContent;
typedef struct {

View File

@ -66,6 +66,7 @@ typedef enum AppOperateType_ {
#define APP_DEBUGGABLE 0x08 // debuggable application
#define APP_ASANENABLED 0x10
#define APP_ACCESS_BUNDLE_DIR 0x20
#define APP_NATIVEDEBUG 0X40
#define BITLEN32 32
#define FDLEN2 2

View File

@ -287,6 +287,67 @@ static int32_t SetFileDescriptors(struct AppSpawnContent_ *content, AppSpawnClie
return 0;
}
static int32_t CheckTraceStatus(void)
{
int fd = open("/proc/self/status", O_RDONLY);
if (fd == -1) {
APPSPAWN_LOGE("open /proc/self/status error: %{public}d", errno);
return (-errno);
}
char data[1024];
ssize_t dataNum = read(fd, data, sizeof(data));
if (close(fd) < 0) {
APPSPAWN_LOGE("close fd error: %{public}d", errno);
return (-errno);
}
if (dataNum <= 0) {
APPSPAWN_LOGE("fail to read data");
return -1;
}
const char* tracerPid = "TracerPid:\t";
char *traceStr = strstr(data, tracerPid);
if (traceStr == NULL) {
APPSPAWN_LOGE("fail to find %{public}s", tracerPid);
return -1;
}
char *separator = strchr(traceStr, '\n');
if (separator == NULL) {
APPSPAWN_LOGE("fail to find line break");
return -1;
}
int len = separator - traceStr - strlen(tracerPid);
char pid = *(traceStr + strlen(tracerPid));
if (len > 1 || pid != '0') {
return 0;
}
return -1;
}
static int32_t WaitForDebugger(AppSpawnClient *client)
{
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
// wait for debugger only debugging is required and process is debuggable
if ((appProperty->property.flags & APP_NATIVEDEBUG) != 0 &&
(appProperty->property.flags & APP_DEBUGGABLE) != 0) {
uint32_t count = 0;
while (CheckTraceStatus() != 0) {
usleep(1000 * 100); // sleep 1000 * 100 microsecond
count++;
// remind users to connect to the debugger every 60 * 10 times
if (count % (10 * 60) == 0) {
count = 0;
APPSPAWN_LOGI("wait for debugger, please attach the process");
}
}
}
return 0;
}
static void Free(char **argv, HspList *hspList)
{
argv[0] = NULL;
@ -504,4 +565,5 @@ void SetContentFunction(AppSpawnContent *content)
content->setSeccompFilter = SetSeccompFilter;
content->setUidGidFilter = SetUidGidFilter;
content->handleInternetPermission = HandleInternetPermission;
content->waitForDebugger = WaitForDebugger;
}