From 2239d8c216263b3a0d9499e8064cf76744735a72 Mon Sep 17 00:00:00 2001 From: Vitaliy Cherepanov Date: Thu, 10 Oct 2013 12:11:02 +0400 Subject: [PATCH] [PROTO] library user space instrumentation are common for all applications - convert new protocol to old format in new protocol there are appinst list and libinst list and libinst list is common for all app list in old protocol there are differents libinst list for each app Change-Id: I1ac605b13a8c77afe598254d55f969f5b4d2dcc5 Signed-off-by: Vitaliy Cherepanov --- daemon/Makefile | 2 + daemon/da_inst.c | 710 +++++++++++++++++++++++++++++++++++++++++++++ daemon/da_inst.h | 89 ++++++ daemon/da_protocol.c | 492 ++++++++----------------------- daemon/da_protocol.h | 80 +++-- daemon/da_protocol_check.c | 23 +- daemon/da_protocol_check.h | 1 + daemon/da_protocol_inst.c | 247 ++++++++++++++++ daemon/da_protocol_inst.h | 46 +++ daemon/daemon.c | 52 +++- daemon/debug.c | 2 +- daemon/process_info.c | 21 +- 12 files changed, 1326 insertions(+), 439 deletions(-) create mode 100644 daemon/da_inst.c create mode 100644 daemon/da_inst.h create mode 100644 daemon/da_protocol_inst.c create mode 100644 daemon/da_protocol_inst.h diff --git a/daemon/Makefile b/daemon/Makefile index 2f511c1..7ce5251 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -18,6 +18,8 @@ DAEMON_SRCS = \ da_data.c \ da_debug.c \ da_protocol.c \ + da_protocol_inst.c \ + da_inst.c \ daemon.c \ debug.c \ elf.c \ diff --git a/daemon/da_inst.c b/daemon/da_inst.c new file mode 100644 index 0000000..105dfe5 --- /dev/null +++ b/daemon/da_inst.c @@ -0,0 +1,710 @@ +/* + * DA manager + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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: + * - Samsung RnD Institute Russia + * + */ + +// TODO check memory (malloc, free) + +#include +#include + +#include "da_inst.h" +#include "da_protocol.h" +#include "da_protocol_inst.h" +#include "debug.h" + + +struct lib_list_t *new_lib_inst_list = NULL; + +uint32_t app_count = 0; +char *packed_app_list = NULL; +char *packed_lib_list = NULL; + +uint32_t libs_count; +// ------------------ prints -------------- +void print_probe_debug(struct probe_list_t *p) +{ + LOGI(" size<%d> <0x%016llX, %s> \n", + p->size, + p->func->func_addr, + p->func->args, + (long unsigned int)p->prev, + (long unsigned int)p, + (long unsigned int)p->next + ); +} + +void print_probe_inst_list(struct probe_list_t *list) +{ + struct probe_list_t *p; + + for (p = list; p != NULL; p = p->next) + print_probe_debug(p); +} + +void print_lib_inst_list(struct lib_list_t *list) +{ + struct lib_list_t *p = list; + + for (p = list; p != NULL; p = p->next) { + LOGI("lib <%s> size<%d> h0x%08lX\n", + p->lib->bin_path, + p->size, + (long unsigned int)p->hash); + print_probe_inst_list(p->list); + } +} + +void print_app_inst_list(struct app_list_t *list) +{ + struct app_list_t *p; + for (p = list; p != NULL; p = p->next) { + LOGI("app <%s> size<%d> h0x%08lX\n", + p->app->exe_path, + p->size, + (long unsigned int)p->hash); + print_probe_inst_list(p->list); + } +} + + +//----------------------------------- lists ---------------------------------- + +static int data_list_add_probe_to_hash(struct data_list_t *to, struct probe_list_t *probe) +{ + // TODO add hash + return 0; +} + +// create hash for lib +static int data_list_make_hash(struct data_list_t *what) +{ + struct probe_list_t *p; + + for (p = what->list; p != NULL; p = p->next) + data_list_add_probe_to_hash(what, p); + return 0; +} + +//------------ create - destroy +struct data_list_t *new_data() +{ + struct data_list_t *lib = malloc(sizeof(*lib)); + lib->next = NULL; + lib->prev = NULL; + lib->hash = 0; + lib->size = 0; + lib->list = NULL; + return lib; +} + +struct lib_list_t *new_lib() +{ + struct lib_list_t *lib = (struct lib_list_t *)new_data(); + lib->lib = malloc(sizeof(*lib->lib)); + memset(lib->lib, 0, sizeof(*lib->lib)); + return lib; +} + +struct app_list_t *new_app() +{ + struct app_list_t *app = (struct app_list_t *)new_data(); + app->app = malloc(sizeof(*app->app)); + memset(app->app, 0, sizeof(*app->app)); + return app; +} + +struct probe_list_t *new_probe() +{ + struct probe_list_t *probe = malloc(sizeof(*probe)); + probe->next = NULL; + probe->prev = NULL; + probe->size = 0; + probe->func = NULL; + return probe; +} + +static void free_probe_element(struct probe_list_t *probe) +{ + free(probe->func); + free(probe); +} + +static void free_data_element(struct data_list_t *lib) +{ + free(lib); +} + +static void free_probe_list(struct probe_list_t *probe) +{ + struct probe_list_t *next; + while (probe != NULL) { + next = probe->next; + free_probe_element(probe); + probe = next; + } +} + +void free_data(struct data_list_t *lib) +{ + free_probe_list(lib->list); + free_data_element(lib); +} + +void free_data_list(struct data_list_t **data) +{ + while (*data != NULL) { + struct data_list_t *next = (*data)->next; + free_data(*data); + *data = next; + } +} + +//------------- add - remove +int data_list_append(struct data_list_t **to, struct data_list_t *from) +{ + struct data_list_t *p = NULL; + if (*to == NULL) { + // empty list + *to = from; + } else { + p = *to; + *to = from; + from->next = (void *)p; + p->prev = (void *)from; + } + return 0; +} + + +static int data_list_append_probes_hash(struct data_list_t *to, struct data_list_t *from) +{ + struct probe_list_t *p = from->list; + struct probe_list_t *last = p; + + to->size += p->size; + to->func_num += from->func_num; + for (p = from->list; p != NULL; p = p->next) { + data_list_add_probe_to_hash(to, p); + last = p; + } + + last->next = to->list; + to->list->prev = last; + to->list = from->list; + + return 1; +} + +int probe_list_append(struct data_list_t *to, struct probe_list_t *from) +{ + struct probe_list_t **list = &(to->list); + struct probe_list_t *p = NULL; + uint32_t num = 0; + if (*list == NULL) { + // empty list + *list = from; + } else { + p = *list; + *list = from; + from->next = (void *)p; + p->prev = (void *)from; + } + to->size += from->size; + + num = 0; + for (p = from; p != NULL; p = p->next) + num++; + to->func_num += num; + return 0; +} + +static struct probe_list_t *probe_list_rm_element(struct data_list_t *list, struct probe_list_t *element) +{ + struct probe_list_t *prev = element->prev; + struct probe_list_t *next = element->next; + if (element != NULL) { + if (prev != NULL) + // prev != null, next == null + // prev != null, next != null + prev->next = next; + else + // prev == null, next == null + // prev == null, next != null + list->list = next; + + if (next != NULL) + next->prev = prev; + + list->size -= element->size; + } + + list->func_num--; + free_probe_element(element); + return next; +} + +static struct data_list_t *data_list_unlink_data(struct data_list_t **list, struct data_list_t *element) +{ + struct data_list_t *prev = element->prev; + struct data_list_t *next = element->next; + if (element != NULL) { + if (prev != NULL) + // prev != null, next == null + // prev != null, next != null + prev->next = next; + else + // prev == null, next == null + // prev == null, next != null + *list = next; + + if (next != NULL) + next->prev = (struct lib_list_t *)prev; + + } + element->prev = NULL; + element->next = NULL; + + return next; +} + +static struct data_list_t *data_list_rm_data(struct data_list_t **list, struct data_list_t *element) +{ + struct data_list_t *next = NULL; + + next = data_list_unlink_data(list, element); + free_data_element(element); + + return next; +} + +// find +static struct data_list_t *data_list_find_data(struct data_list_t *whered, struct data_list_t *whatd, cmp_data_f cmp) +{ + struct data_list_t *where; + struct data_list_t *what = whatd; + for (where = whered; where != NULL; where = where->next) { + if (where->hash == what->hash) { + if (cmp(where, what)) + return where; + } + } + return NULL; +} + +static struct probe_list_t *find_probe(struct data_list_t *where, struct probe_list_t *probe) +{ + struct probe_list_t *p ; + for (p = where->list; p != NULL; p = p->next) + if (p->size == probe->size) + if (p->func->func_addr == probe->func->func_addr) + if (strcmp(p->func->args, probe->func->args) == 0) + break; + + return p; +} + +// "from" will be destroyed after this call +static int data_list_move_with_hash(struct data_list_t **to, struct data_list_t **from, cmp_data_f cmp) +{ + + struct data_list_t *p = *from; + struct data_list_t *next = NULL; + struct data_list_t *sch = NULL; + while (p != NULL) { + sch = data_list_find_data(*to, p, cmp); + next = data_list_unlink_data(from, p); + if (sch == NULL) { + data_list_make_hash(p); + data_list_append(to, p); + } else { + data_list_append_probes_hash(sch, p); + } + p = next; + } + return 1; +} + +//---------------------------- collisions resolve ------------------------------ + +static int cmp_libs(struct data_list_t *el_1, struct data_list_t *el_2) +{ + return (strcmp( + ((struct lib_list_t *)el_1)->lib->bin_path, + ((struct lib_list_t *)el_2)->lib->bin_path + ) == 0); +} + +// this function for future use +static int cmp_apps(struct data_list_t *el_1, struct data_list_t *el_2) +{ + return (strcmp( + ((struct app_list_t *)el_1)->app->exe_path, + ((struct app_list_t *)el_2)->app->exe_path + ) == 0); +} + +/////////////////////////////////////////////////////////////////////////// +// function removes from new list all probes which are already installed +// +// cur - current state (lib list with probes) +// new - additional probes which were received with MSG_SWAP_INST_ADD msg +// (lib list with probes) +// this function removes all probes which are present in cur and new list from +// new list so after this function call in new list will be only probes which are +// not present in cur list +static int resolve_collisions_for_add_msg(struct lib_list_t **cur, struct lib_list_t **new) +{ + struct data_list_t *p = (struct data_list_t *)*new; + struct data_list_t *sch = NULL; + + struct probe_list_t *pr = NULL; + struct probe_list_t *next_pr = NULL; + + // remove collisions from list "new" + while (p != NULL) { + sch = data_list_find_data((struct data_list_t *)*cur, p, cmp_libs); + if (sch == NULL) { + // lib not found in cur config + } else { + // lib found in cur config so resolve collisions + pr = p->list; + while (pr != NULL) { + // remove collisions + if (find_probe(sch, pr) != NULL) { + // probe already exist + // rm from new config + next_pr = probe_list_rm_element(p, pr); + pr = next_pr; + } else { + pr = pr->next; + } + } + + // rm lib if it is empty + if (p->list == NULL) { + p = data_list_rm_data((struct data_list_t **)new, p); + continue; + } + } + p = p->next; + } + return 1; +} + +/////////////////////////////////////////////////////////////////////////// +// function removes from cur list all probes which are in list "new" +// and removes from "new" all probes which are not instaled +// +// cur - current state (lib list with probes) +// new - list for probes remove which were received with MSG_SWAP_INST_REMOVE msg +// +// this function removes all probes which are present in cur and new list from +// cur list and removes all probes which are present in new but not present in +// cur list so after this function call in new list will be only probes which are +// present in cur list +static int resolve_collisions_for_rm_msg(struct lib_list_t **cur, struct lib_list_t **new) +{ + struct data_list_t *p = (struct data_list_t *)*new; + struct data_list_t *next_l = NULL; + struct data_list_t *sch = NULL; + + struct probe_list_t *pr = NULL; + struct probe_list_t *next_pr = NULL; + struct probe_list_t *tmp = NULL; + + // remove collisions from list "new" + while (p != NULL) { + sch = data_list_find_data((struct data_list_t *)*cur, p, cmp_libs); + if (sch == NULL) { + //lib not found so no probes remove + next_l = data_list_rm_data((struct data_list_t **)new, p); + } else { + //lib found so we need remove collisions + pr = p->list; + if (pr == NULL) { + // if rm probe list is empty that is mean we need + // to remove all probes on this lib + data_list_unlink_data((struct data_list_t **)cur, sch); + data_list_append((struct data_list_t **)new, sch); + next_l = data_list_rm_data((struct data_list_t **)cur, p); + } else { + // lib is not empty so merge + while (pr != NULL) { + // remove collisions + if ((tmp = find_probe(sch, pr)) != NULL) { + // probe found so remove probe + // from cur state + probe_list_rm_element(sch, tmp); + pr = pr->next; + } else { + // probe no found so remove it + // from new state + next_pr = probe_list_rm_element(p, pr); + pr = next_pr; + } + } + // rm lib if it is empty + if (sch->list == NULL) { + data_list_rm_data((struct data_list_t **)cur, sch); + } + next_l = p->next; + } + } + p = next_l; + } + return 1; +} + +//--------------------------------------pack ---------------------------------- + +static char *pack_lib_head_to_array(char *to, void *data) +{ + struct us_lib_inst_t *lib = data; + pack_str(to, lib->bin_path); + return to; +} + +static char *pack_app_head_to_array(char *to, void *data) +{ + struct app_info_t *app = data; + pack_int32(to, app->app_type); + pack_str(to, app->app_id); + pack_str(to, app->exe_path); + return to; +} + +static char *pack_data_to_array(struct data_list_t *data, char *to, pack_head_t pack_head) +{ + struct probe_list_t *p; + + to = pack_head(to, data->data); + pack_int32(to, data->func_num); + for (p = data->list; p != NULL; p = p->next) { + memcpy(to, p->func, p->size); + to += p->size; + } + return to; +} + +static char *pack_data_list_to_array(struct data_list_t *list, uint32_t *len, uint32_t *count, pack_head_t pack) +{ + char *res = NULL; + char *to = NULL; + uint32_t size = 0; + uint32_t cnt = 0; + struct data_list_t *p = list; + + for (p = list; p != NULL; p = p->next) { + size += p->size; + cnt++; + } + + size += sizeof(uint32_t); + *len = size; + *count = cnt; + + if (size != 0) { + res = malloc(size); + to = res; + if (to != NULL) { + memset(to, '*', size); + pack_int32(to, cnt); + for (p = list; p != NULL; p = p->next) + to = pack_data_to_array(p, to, pack); + } else { + LOGE("can not malloc buffer for data list packing\n"); + } + } + return res; +} + +static char *pack_lib_list_to_array(struct lib_list_t *list, uint32_t *size, uint32_t *count) +{ + return pack_data_list_to_array((struct data_list_t *)list, size, + count, pack_lib_head_to_array); +} + +static char *pack_app_list_to_array(struct app_list_t *list, uint32_t *size, uint32_t *count) +{ + return pack_data_list_to_array((struct data_list_t *)list, size, + count, pack_app_head_to_array); +} + +static int generate_msg(struct msg_t **msg, struct lib_list_t *lib_list, struct app_list_t *app_list) +{ + uint32_t i, + size = 0, + libs_size = 0, + apps_size = 0, + libs_count = 0, + apps_count = 0; + char *p = NULL; + + + // print_lib_inst_list(lib_list); + packed_lib_list = pack_lib_list_to_array(lib_list, &libs_size, &libs_count); + // print_buf(packed_lib_list, libs_size, "LIBS"); + + packed_app_list = pack_app_list_to_array(app_list, &apps_size, &apps_count); + // print_buf(packed_app_list, apps_size, "APPS"); + + size = apps_count * libs_size + apps_size; + + LOGI("size = %d, apps= %d, libs = %d\n", size, apps_count, libs_count); + + // add header size + *msg = malloc(size + sizeof(**msg)); + memset(*msg, '*', size); + + p = (char *)*msg; + pack_int32(p, 0); // msg id + pack_int32(p, size); // payload size + pack_int32(p, apps_count); + + struct app_list_t *app = app_list; + char *app_p = packed_app_list + sizeof(((struct user_space_inst_t *)0)->app_num); + + for (i = 0; i < apps_count; i++) { + memcpy(p, app_p, app->size); + p += app->size; + memcpy(p, packed_lib_list, libs_size); + p += libs_size; + + app_p += app->size; + app = app->next; + } + + // print_buf((char *)*msg, size, "ANSWER"); + return 1; +} + +//----------------------------------------------------------------------------- +struct app_info_t *app_info_get_first(struct app_list_t **app_list) +{ + *app_list = prof_session.user_space_inst.app_inst_list; + if (*app_list == NULL) { + return NULL; + } + + return (*app_list)->app; +} + +struct app_info_t *app_info_get_next(struct app_list_t **app_list) +{ + if (*app_list == NULL) + return NULL; + + if ((*app_list = (*app_list)->next) == NULL) + return NULL; + + return (*app_list)->app; +} + +//----------------------------------------------------------------------------- +int msg_start(struct msg_buf_t *data, struct user_space_inst_t *us_inst, struct msg_t **msg) +{ + char *p = NULL; + *msg = NULL; + if (!parse_app_inst_list(data, &us_inst->app_num, &us_inst->app_inst_list)) { + LOGE("parse app inst\n"); + return 1; + } + // print_app_inst_list(app_inst_list); + generate_msg(msg, us_inst->lib_inst_list, us_inst->app_inst_list); + + if (*msg != NULL) { + p = (char *)*msg; + pack_int32(p, NMSG_START); + } else { + return 1; + } + return 0; +} + +int msg_swap_inst_add(struct msg_buf_t *data, struct user_space_inst_t *us_inst, struct msg_t **msg) +{ + uint32_t lib_num = 0; + char *p = NULL; + + if (!parse_lib_inst_list(data, &lib_num, &us_inst->lib_inst_list)) { + LOGE("parse lib inst list fail\n"); + return 1; + } + // rm probes from new if its presents in cur + if (!resolve_collisions_for_add_msg(&us_inst->lib_inst_list, &new_lib_inst_list)) { + LOGE("resolve collision\n"); + return 1; + }; + + // generate msg to send + if (us_inst->app_inst_list != NULL) { + generate_msg(msg, new_lib_inst_list, us_inst->app_inst_list); + p = (char *)*msg; + pack_int32(p, NMSG_SWAP_INST_ADD); + } + // apply changes to cur state + if (!data_list_move_with_hash( + (struct data_list_t **)&us_inst->lib_inst_list, + (struct data_list_t **)&new_lib_inst_list, + cmp_libs)) + { + LOGE("data move\n"); + return 1; + }; + + // free new_list + free_data_list((struct data_list_t **)&new_lib_inst_list); + new_lib_inst_list = NULL; + return 0; +} + +int msg_swap_inst_remove(struct msg_buf_t *data, struct user_space_inst_t *us_inst, struct msg_t **msg) +{ + uint32_t lib_num = 0; + char *p = NULL; + + if (!parse_lib_inst_list(data, &lib_num, &new_lib_inst_list)) { + LOGE("parse lib inst\n"); + return 1; + } + + if (!resolve_collisions_for_rm_msg(&us_inst->lib_inst_list, &new_lib_inst_list)) { + LOGE("resolve collisions\n"); + return 1; + } + + if (us_inst->app_inst_list != NULL) { + if (!generate_msg(msg, new_lib_inst_list, us_inst->app_inst_list)) { + LOGE("generate msg\n"); + return 1; + } + p = (char *)*msg; + pack_int32(p, NMSG_SWAP_INST_ADD); + } + + free_data_list((struct data_list_t **)&new_lib_inst_list); + new_lib_inst_list = NULL; + return 0; +} diff --git a/daemon/da_inst.h b/daemon/da_inst.h new file mode 100644 index 0000000..4c211aa --- /dev/null +++ b/daemon/da_inst.h @@ -0,0 +1,89 @@ +/* + * DA manager + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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: + * - Samsung RnD Institute Russia + * + */ + +#ifndef __DA_INST_H__ +#define __DA_INST_H__ + +#include +#include +#include "da_protocol.h" + +//LISTS +struct probe_list_t { + void *next; + void *prev; + uint32_t size; //for message generate + struct us_func_inst_plane_t *func; +}; + +struct lib_list_t { + void *next; + void *prev; + uint32_t hash; + uint32_t size; //for message generate + struct us_lib_inst_t *lib; + uint32_t func_num; + struct probe_list_t *list; +}; + +struct app_list_t { + void *next; + void *prev; + uint32_t hash; + uint32_t size; //for message generate + struct app_info_t *app; + uint32_t func_num; + struct probe_list_t *list; +}; + + +struct data_list_t { + void *next; + void *prev; + uint32_t hash; + uint32_t size; //for message generate + void *data; + uint32_t func_num; + struct probe_list_t *list; +}; + +typedef int (cmp_data_f) (struct data_list_t *el_1, struct data_list_t *el_2); +typedef char *(*pack_head_t) (char *to, void *data); + +extern int msg_swap_inst_remove(struct msg_buf_t *data, struct user_space_inst_t *us_inst, struct msg_t **msg); +extern int msg_swap_inst_add(struct msg_buf_t *data, struct user_space_inst_t *us_inst, struct msg_t **msg); +extern int msg_start(struct msg_buf_t *data, struct user_space_inst_t *us_inst, struct msg_t **msg); + +struct probe_list_t *new_probe(); +struct lib_list_t *new_lib(); +struct app_list_t *new_app(); +int probe_list_append(struct data_list_t *to, struct probe_list_t *from); +int data_list_append(struct data_list_t **to, struct data_list_t *from); +void free_data_list(struct data_list_t **data); + +struct app_info_t *app_info_get_first(struct app_list_t **app_list); +struct app_info_t *app_info_get_next(struct app_list_t **app_list); +#endif /* __DA_INST_H__*/ diff --git a/daemon/da_protocol.c b/daemon/da_protocol.c index 9677856..ab6a400 100644 --- a/daemon/da_protocol.c +++ b/daemon/da_protocol.c @@ -38,6 +38,7 @@ #include #include "da_protocol.h" +#include "da_inst.h" #include "da_protocol_check.h" #include "daemon.h" #include "sys_stat.h" @@ -57,12 +58,11 @@ void inline free_msg(struct msg_t *msg) { free(msg); } -static uint32_t msg_size_with_out_replays = 0; struct prof_session_t prof_session; -static void print_app_info( struct app_info_t *app_info); -static void print_conf(struct conf_t * conf); +static void print_app_info(struct app_info_t *app_info); +static void print_conf(struct conf_t *conf); //DEBUG FUNCTIONS #define dstr(x) #x @@ -72,7 +72,7 @@ static void print_conf(struct conf_t * conf); #define check_8(a1,a2,a3,a4,a5,a6,a7,a8) check_4(a1,a2,a3,a4) else check_4(a5,a6,a7,a8) #define check_all(a1, ...) check_and_return(ID,a1) //#else check_all(__VA_ARGS__) -char* msg_ID_str ( enum HostMessageT ID) +char *msg_ID_str(enum HostMessageT ID) { check_8( NMSG_KEEP_ALIVE, @@ -181,7 +181,7 @@ static char *msgErrStr(enum ErrorCode err) to+=strlen( dstr(f) delim );\ } #define print_feature_a(f) print_feature(f,feature,to,", ") -void feature_code_str(uint32_t feature, char * to) +void feature_code_str(uint32_t feature, char *to) { print_feature_a(FL_CPU); print_feature_a(FL_MEMORY); @@ -217,7 +217,7 @@ inline uint32_t get_msg_cur_size(struct msg_buf_t *msg) return (uint32_t) (msg->cur_pos - msg->payload); } -static int parse_string(struct msg_buf_t *msg, char **str) +int parse_string(struct msg_buf_t *msg, char **str) { parse_deb("size = %d\n", get_avail_msg_size(msg)); int len = strlen(msg->cur_pos) + 1; @@ -226,7 +226,7 @@ static int parse_string(struct msg_buf_t *msg, char **str) return 0; *str = strdup(msg->cur_pos); - parse_deb("<%s>\n",*str); + parse_deb("<%s>\n", *str); msg->cur_pos += len; return 1; } @@ -249,7 +249,21 @@ static const char* parse_string_inplace(struct msg_buf_t *msg) return str; } -static int parse_int32(struct msg_buf_t *msg, uint32_t *val) +int parse_string_no_alloc(struct msg_buf_t *msg, char *str) +{ + parse_deb("size = %d\n", get_avail_msg_size(msg)); + int len = strlen(msg->cur_pos) + 1; + + if (get_avail_msg_size(msg) < len) + return 0; + + memcpy(str, msg->cur_pos, len); + parse_deb("<%s>\n", str); + msg->cur_pos += len; + return 1; +} + +int parse_int32(struct msg_buf_t *msg, uint32_t *val) { parse_deb("size = %d\n", get_avail_msg_size(msg)); if (get_avail_msg_size(msg) < sizeof(*val)) @@ -258,11 +272,12 @@ static int parse_int32(struct msg_buf_t *msg, uint32_t *val) msg->cur_pos += sizeof(uint32_t); - parse_deb("<%d><0x%08X>\n",*val,*val); + parse_deb("<%d><0x%08X>\n", *val, *val); return 1; } -static int parse_int64(struct msg_buf_t *msg, uint64_t *val) + +int parse_int64(struct msg_buf_t *msg, uint64_t *val) { parse_deb("size = %d\n", get_avail_msg_size(msg)); if (get_avail_msg_size(msg) < sizeof(*val)) @@ -270,7 +285,7 @@ static int parse_int64(struct msg_buf_t *msg, uint64_t *val) *val = *(uint64_t *)msg->cur_pos; - parse_deb("<%llu><0x%016llX>\n",*val,*val); + parse_deb("<%llu><0x%016llX>\n", *val, *val); msg->cur_pos += sizeof(uint64_t); return 1; } @@ -301,7 +316,6 @@ static int parse_app_info(struct msg_buf_t *msg, LOGE("app type error\n"); return 0; } - //Application ID if (!parse_string(msg, &app_info->app_id) || !check_app_id(app_info->app_type, app_info->app_id)) @@ -309,7 +323,6 @@ static int parse_app_info(struct msg_buf_t *msg, LOGE("app id parsing error\n"); return 0; } - //Applicaion exe path if (!parse_string(msg, &app_info->exe_path)) { LOGE("app info parsing error\n"); @@ -320,9 +333,7 @@ static int parse_app_info(struct msg_buf_t *msg, LOGE("app info parsing error\n"); return 0; } - // print_app_info(app_info); - return 1; } @@ -339,7 +350,6 @@ static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf) LOGE("use features1 parsing error\n"); return 0; } - //Check features value if (!check_conf_features(conf->use_features0, conf->use_features1)) { LOGE("check features fail\n"); @@ -363,180 +373,6 @@ static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf) return 1; } -static int parse_us_inst_func(struct msg_buf_t *msg , struct us_func_inst_t * dest) -{ - - if (!parse_int64(msg, &(dest->func_addr))) { - LOGE("func addr parsing error\n"); - return 0; - } - - if (!parse_string(msg, &dest->args) || - !check_us_inst_func_args(dest->args)) - { - LOGE("args format parsing error\n"); - return 0; - } - return 1; - -} - -static int parse_func_inst_list(struct msg_buf_t *msg, - uint32_t *num, - struct us_func_inst_t ** us_func_inst_list) -{ - uint32_t i = 0; - if (!parse_int32(msg, num) || - !check_us_app_inst_func_count(*num)) - { - LOGE("func num parsing error\n"); - return 0; - } - //parse user space function list - - parse_deb("us_func_inst_list size = %d * %d\n",(*num), - (int)sizeof(**us_func_inst_list)); - *us_func_inst_list = - (struct us_func_inst_t *) - malloc((*num) * sizeof(**us_func_inst_list)); - if (!*us_func_inst_list){ - LOGE("func alloc error\n"); - return 0; - }; - - for (i = 0; i < *num; i++){ - if (!parse_us_inst_func(msg, &((*us_func_inst_list)[i]))){ - // TODO maybe need to free allocated memory up there - LOGE("parse us inst func #%d failed\n", i + 1); - return 0; - } - } - - return 1; -} - -static int parse_us_inst_lib(struct msg_buf_t *msg, struct us_lib_inst_t * dest) -{ - - if (!parse_string(msg, &(dest)->bin_path) || - !check_exec_path(dest->bin_path)) - { - LOGE("bin path parsing error\n"); - return 0; - } - - if (!parse_func_inst_list(msg, &dest->func_num, &dest->us_func_inst_list)) { - LOGE("funcs parsing error\n"); - return 0; - } - return 1; - -} - -static int parse_lib_inst_list(struct msg_buf_t *msg, - uint32_t *num, - struct us_lib_inst_t ** us_lib_inst_list) -{ - uint32_t i = 0; - if (!parse_int32(msg, num) || - !check_lib_inst_count(*num)) - { - LOGE("lib num parsing error\n"); - return 0; - } - - parse_deb("lib_list size = %d\n", (*num) * (int)sizeof(**us_lib_inst_list) ); - *us_lib_inst_list = - (struct us_lib_inst_t *) - malloc( (*num) * sizeof(**us_lib_inst_list) ); - if (!*us_lib_inst_list){ - LOGE("lib alloc error\n"); - return 0; - }; - for (i = 0; i < *num; i++){ - if (!parse_us_inst_lib( msg, &( (*us_lib_inst_list)[i] ) )){ - // TODO maybe need free allocated memory up there - LOGE("parse is inst lib #%d failed\n", i + 1); - return 0; - } - } - return 1; -} - -static int parse_app_inst(struct msg_buf_t *msg, - struct app_inst_t *app_inst) -{ - if (!parse_int32(msg, &app_inst->app_type) || - !check_app_type(app_inst->app_type)) - { - LOGE("app type parsing error\n"); - return 0; - } - if (!parse_string(msg, &app_inst->app_id) || - !check_app_id(app_inst->app_type, app_inst->app_id)) - { - LOGE("app id parsing error\n"); - return 0; - } - if (!parse_string(msg, &app_inst->exec_path) || - !check_exec_path(app_inst->exec_path)) - { - LOGE("exec path parsing error\n"); - return 0; - } - if (!parse_func_inst_list(msg, &app_inst->func_num, &(app_inst->us_func_inst_list))) { - LOGE("funcs parsing error\n"); - return 0; - } - - parse_deb(">=%04X : %s, %s\n", - app_inst->app_type, app_inst->app_id, app_inst->exec_path); - - if (!parse_lib_inst_list( msg, &app_inst->lib_num , &app_inst->us_lib_inst_list)) { - LOGE("libs parsing error\n"); - return 0; - } - - return 1; -} - -int parse_user_space_inst(struct msg_buf_t *msg, - struct user_space_inst_t *user_space_inst) -{ - parse_deb("parse_user_space_inst\n"); - uint32_t num = 0 , i = 0; - struct app_inst_t * list = 0; - - if (!parse_int32 ( msg, &num ) || - !check_us_app_count(num)) - { - LOGE("app num error\n"); - return 0; - } - - parse_deb("%d * %d\n",(int) sizeof(*(user_space_inst->app_inst_list)), num); - if ( num != 0 ) { - list = (struct app_inst_t *) malloc ( - sizeof(*(user_space_inst->app_inst_list)) * num); - if ( !list ) { - LOGE("apps alloc error\n"); - return 0; - }; - - for ( i = 0; i < num; i++){ - if (!parse_app_inst( msg, &(list[i]) )){ - LOGE("parse app inst #%d failed\n", i + 1); - free(list); - return 0; - } - }; - - user_space_inst->app_num = num; - user_space_inst->app_inst_list = list; - } - return 1; -} - //REPLAY EVENTS PARSE static int parse_timeval(struct msg_buf_t *msg, struct timeval *tv) { @@ -599,11 +435,9 @@ void reset_replay_event_seq(struct replay_event_seq_t *res) res->event_num = 0; } -static int parse_replay_event_seq(struct msg_buf_t *msg, - struct replay_event_seq_t *res) +int parse_replay_event_seq(struct msg_buf_t *msg, + struct replay_event_seq_t *res) { - LOGI("parse_replay_event_seq\n"); - int i = 0; parse_deb("REPLAY\n"); if (!parse_int32(msg, &res->enabled)) { @@ -611,7 +445,7 @@ static int parse_replay_event_seq(struct msg_buf_t *msg, return 0; } - if(res->enabled == 0){ + if(res->enabled == 0) { parse_deb("disable\n"); return 1; } @@ -651,34 +485,6 @@ static int parse_replay_event_seq(struct msg_buf_t *msg, //*REPLAY EVENT PARSE -static int parse_prof_session(struct msg_buf_t *msg, - struct prof_session_t *prof_session) -{ - LOGI("parse_prof_session\n"); - if (!parse_app_info(msg, &prof_session->app_info)) { - LOGE("app info parsing error\n"); - return 1; - } - if (!parse_conf(msg, &prof_session->conf)) { - LOGE("conf parsing error\n"); - return 1; - } - - if (!parse_user_space_inst(msg, &prof_session->user_space_inst)) { - LOGE("user space inst parsing error\n"); - return 1; - } - - msg_size_with_out_replays = get_msg_cur_size(msg); - if (!parse_replay_event_seq(msg, &prof_session->replay_event_seq)) { - LOGE("replay parsing error\n"); - return 1; - } - - //print_prof_session(prof_session); - return 0; -} - int get_sys_mem_size(uint32_t *sys_mem_size){ struct sysinfo info; sysinfo(&info); @@ -686,8 +492,8 @@ int get_sys_mem_size(uint32_t *sys_mem_size){ return 0; } -static int parse_msg_config(struct msg_buf_t * msg_payload, - struct conf_t * conf) +static int parse_msg_config(struct msg_buf_t *msg_payload, + struct conf_t *conf) { if (!parse_conf(msg_payload, conf)) { LOGE("conf parsing error\n"); @@ -698,7 +504,7 @@ static int parse_msg_config(struct msg_buf_t * msg_payload, return 1; } -static int parse_msg_binary_info(struct msg_buf_t * msg_payload, +static int parse_msg_binary_info(struct msg_buf_t *msg_payload, struct app_info_t *app_info) { if (!parse_app_info(msg_payload, app_info)) { @@ -712,49 +518,10 @@ static int parse_msg_binary_info(struct msg_buf_t * msg_payload, static void init_parse_control(struct msg_buf_t *buf, struct msg_t *msg) { - LOGI("init parse control\n"); buf->payload = msg->payload; buf->len = msg->len; buf->end = msg->payload + msg->len; buf->cur_pos = msg->payload; - LOGI("init parse control done\n"); -} - -//This function concat 2 user space lists -// this function clean "from" pointer -static void concat_add_user_space_inst(struct user_space_inst_t *from, - struct user_space_inst_t *to) -{ - struct app_inst_t *new_app_inst_list = NULL; - uint32_t size; - void *p; - - if (from->app_num == 0) - return; - - new_app_inst_list = malloc((from->app_num + to->app_num) * sizeof(*new_app_inst_list)); - p = new_app_inst_list; - - size = from->app_num * sizeof(*new_app_inst_list); - memcpy(p, from->app_inst_list, size); - p +=size; - - size = to->app_num * sizeof(*new_app_inst_list); - memcpy(p, to->app_inst_list, size); - p +=size; - - free(to->app_inst_list); - to->app_inst_list = new_app_inst_list; - - to->app_num += from->app_num; - return; -} - -static void cut_replay_events(struct msg_t *msg){ - - LOGI("msg_size_with_out_replays = %d \n",msg_size_with_out_replays); - msg->len = msg_size_with_out_replays; - } static void reset_app_info(struct app_info_t *app_info) @@ -776,53 +543,24 @@ static void reset_conf(struct conf_t *conf) memset(conf, 0, sizeof(*conf)); } -static void reset_func_inst_list(uint32_t func_num, - struct us_func_inst_t *funcs) -{ - int i = 0; - - for (i = 0; i < func_num; i++) { - funcs[i].func_addr = 0; - free(funcs[i].args); - } -} - -static void reset_lib_inst_list(uint32_t lib_num, struct us_lib_inst_t *libs) +static void reset_app_inst(struct user_space_inst_t *us_inst) { - int i = 0; - - for (i = 0; i < lib_num; i++) { - free(libs[i].bin_path); - reset_func_inst_list(libs[i].func_num, - libs[i].us_func_inst_list); - } + free_data_list((struct data_list_t **)&us_inst->app_inst_list); + us_inst->app_num = 0; + us_inst->app_inst_list = NULL; } -static void reset_app_inst(struct app_inst_t *app_inst) +static void reset_lib_inst(struct user_space_inst_t *us_inst) { - app_inst->app_type = 0; - free(app_inst->app_id); - free(app_inst->exec_path); - reset_func_inst_list(app_inst->func_num, - app_inst->us_func_inst_list); - app_inst->func_num = 0; - free(app_inst->us_func_inst_list); - reset_lib_inst_list(app_inst->lib_num, app_inst->us_lib_inst_list); - app_inst->lib_num = 0; - free(app_inst->us_lib_inst_list); + free_data_list((struct data_list_t **)&us_inst->lib_inst_list); + us_inst->lib_num = 0; + us_inst->lib_inst_list = NULL; } -static void reset_user_space_inst(struct user_space_inst_t *us) +static void reset_user_space_inst(struct user_space_inst_t *us_inst) { - int i = 0; - - for (i = 0; i < us->app_num; i++) - reset_app_inst(&us->app_inst_list[i]); - if (us->app_inst_list != NULL){ - free(us->app_inst_list); - us->app_inst_list = NULL; - } - us->app_num = 0; + reset_app_inst(us_inst); + reset_lib_inst(us_inst); } void reset_system_info(struct system_info_t *sys_info) @@ -838,11 +576,16 @@ void reset_system_info(struct system_info_t *sys_info) memset(sys_info, 0, sizeof(*sys_info)); } +void init_prof_session(struct prof_session_t *prof_session) +{ + memset(prof_session, 0, sizeof(*prof_session)); +} + static void reset_prof_session(struct prof_session_t *prof_session) { - reset_app_info(&prof_session->app_info); reset_conf(&prof_session->conf); reset_user_space_inst(&prof_session->user_space_inst); + reset_replay_event_seq(&prof_session->replay_event_seq); } static struct msg_t *gen_binary_info_reply(struct app_info_t *app_info) @@ -939,7 +682,7 @@ static struct msg_t *gen_target_info_reply(struct target_info_t *target_info) static int send_reply(struct msg_t *msg) { - printBuf(msg, msg->len + sizeof (*msg)); + printBuf((char *)msg, msg->len + sizeof (*msg)); if (send(manager.host.control_socket, msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) { LOGE("Cannot send reply : %s\n", strerror(errno)); @@ -959,8 +702,7 @@ static void write_msg_error(const char *err_str) int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code, char *payload, int payload_size) { - if (manager.host.control_socket != -1) - { + if (manager.host.control_socket != -1) { struct msg_t *msg; uint32_t err = err_code; int loglen = sizeof(*msg) - sizeof(msg->payload) + @@ -1023,12 +765,12 @@ int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code, } free(msg); return 0; - } - else + } else return 1; } -struct msg_t *gen_stop_msg(void){ +struct msg_t *gen_stop_msg(void) +{ struct msg_t *res = malloc(sizeof(*res)); memset(res, 0, sizeof(*res)); res->id = NMSG_STOP; @@ -1045,18 +787,19 @@ enum ErrorCode stop_all(void) terminate_all(); stop_profiling(); - if (msg == NULL){ + if (msg == NULL) { LOGE("cannot generate stop message\n"); return ERR_UNKNOWN; } else { - if (ioctl_send_msg(msg) != 0){ + if (ioctl_send_msg(msg) != 0) { LOGE("ioctl send filed\n"); error_code = ERR_UNKNOWN; } free_msg(msg); } - reset_prof_session(&prof_session); + //we reset only app inst no lib no confing reset + reset_app_inst(&prof_session.user_space_inst); stop_transfer(); LOGI("finished\n"); @@ -1173,11 +916,10 @@ int host_message_handler(struct msg_t *msg) { struct app_info_t app_info; struct target_info_t target_info; - struct msg_t *msg_reply; + struct msg_t *msg_reply = NULL; struct msg_buf_t msg_control; - struct user_space_inst_t user_space_inst; struct conf_t conf; - enum ErrorCode error_code; + enum ErrorCode error_code = ERR_NO; int target_index; ssize_t sendlen; @@ -1191,45 +933,51 @@ int host_message_handler(struct msg_t *msg) sendACKToHost(msg->id, ERR_NO, 0, 0); break; case NMSG_START: - if (parse_prof_session(&msg_control, &prof_session) != 0) { - LOGE("prof session parsing error\n"); - sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0); - return -1; + if (!check_conf(&prof_session.conf)) { + error_code = ERR_CANNOT_START_PROFILING; + LOGE("wrong profile config\n"); + goto send_ack; + } + if (msg_start(&msg_control, &prof_session.user_space_inst, &msg_reply) != 0) { + LOGE("parse error\n"); + error_code = ERR_CANNOT_START_PROFILING; + goto send_ack; } if (start_transfer() != 0) { LOGE("Cannot start transfer\n"); - return -1; + error_code = ERR_CANNOT_START_PROFILING; + goto send_ack; + } + //response to control socket + if (msg_reply == NULL) { + LOGE("message for kernel is null\n"); + error_code = ERR_CANNOT_START_PROFILING; + goto send_ack; } - //response to control sockete - cut_replay_events(msg); - if (ioctl_send_msg(msg) != 0){ + if (ioctl_send_msg(msg_reply) != 0) { LOGE("cannot send message to device\n"); // response to control socket - sendACKToHost(msg->id, ERR_CANNOT_START_PROFILING, 0, 0); - return -1; + error_code = ERR_CANNOT_START_PROFILING; + goto send_ack; } if (start_profiling() < 0) { LOGE("cannot start profiling\n"); - sendACKToHost(msg->id, ERR_CANNOT_START_PROFILING, 0, 0); - return -1; + error_code = ERR_CANNOT_START_PROFILING; + goto send_ack; } - - // TODO: start app launch timer - - // success - sendACKToHost(msg->id, ERR_NO, 0, 0); - break; + error_code = ERR_NO; + goto send_ack; case NMSG_STOP: sendACKToHost(msg->id, ERR_NO, 0, 0); if (stop_all() != ERR_NO) write_msg_error("Stop failed"); break; case NMSG_CONFIG: - error_code=ERR_NO; + error_code = ERR_NO; if (!parse_msg_config(&msg_control, &conf)) { LOGE("config parsing error\n"); sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0); @@ -1240,13 +988,13 @@ int host_message_handler(struct msg_t *msg) return -1; } //write to device - if (ioctl_send_msg(msg) != 0){ + if (ioctl_send_msg(msg) != 0) { + LOGE("ioctl send error\n"); sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0); return -1; } //send ack to host sendACKToHost(msg->id, ERR_NO, 0, 0); - // send config message to target process sendlog.type = MSG_OPTION; sendlog.length = sprintf(sendlog.data, "%lu", @@ -1265,39 +1013,31 @@ int host_message_handler(struct msg_t *msg) case NMSG_BINARY_INFO: return process_msg_binary_info(&msg_control); case NMSG_SWAP_INST_ADD: - if (!parse_user_space_inst(&msg_control, - &user_space_inst)) { - LOGE("user space inst parsing error\n"); - sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0); - return -1; - } - // TODO: apply_prof_session() - // warning concat_add_user_space_inst free user_space_inst - // so, data will not be availible - concat_add_user_space_inst(&user_space_inst, &prof_session.user_space_inst); - //write to device - if (ioctl_send_msg(msg) != 0){ - sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0); - return -1; + if (msg_swap_inst_add(&msg_control, &prof_session.user_space_inst, &msg_reply) != 0) { + LOGE("swap inst add\n"); + error_code = ERR_UNKNOWN; + goto send_ack; } + if (msg_reply != NULL) + if (ioctl_send_msg(msg_reply) != 0) { + error_code = ERR_UNKNOWN; + LOGE("ioclt send error\n"); + } //send ack to host - sendACKToHost(msg->id, ERR_NO, 0, 0); - // TODO release user_space_inst - break; + goto send_ack; case NMSG_SWAP_INST_REMOVE: - if (!parse_user_space_inst(&msg_control, - &prof_session.user_space_inst)){ - sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0); - LOGE("user space inst parsing error\n"); - return -1; + if (msg_swap_inst_remove(&msg_control, &prof_session.user_space_inst, &msg_reply) != 0) { + LOGE("swap inst remove\n"); + error_code = ERR_UNKNOWN; + goto send_ack; } - if (ioctl_send_msg(msg) != 0){ - sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0); - return -1; + if (msg_reply != NULL) { + if (ioctl_send_msg(msg_reply) != 0) + error_code = ERR_UNKNOWN; + } else { + error_code = ERR_UNKNOWN; } - // TODO: apply_prof_session() - sendACKToHost(msg->id, ERR_NO, 0, 0); - break; + goto send_ack; case NMSG_GET_TARGET_INFO: fill_target_info(&target_info); msg_reply = gen_target_info_reply(&target_info); @@ -1318,11 +1058,17 @@ int host_message_handler(struct msg_t *msg) } return 0; + +send_ack: + sendACKToHost(msg->id, error_code, 0, 0); + if (msg_reply != NULL) + free(msg_reply); + return (error_code == ERR_NO); } // testing -static void print_app_info( struct app_info_t *app_info) +static void print_app_info(struct app_info_t *app_info) { LOGI("application info=\n"); LOGI("\tapp_type=<%d><0x%04X>\n" @@ -1335,10 +1081,10 @@ static void print_app_info( struct app_info_t *app_info) ); } -static void print_conf(struct conf_t * conf) +static void print_conf(struct conf_t *conf) { char buf[1024]; - memset(&buf[0],0,1024); + memset(&buf[0], 0, 1024); feature_code_str(conf->use_features0, buf); LOGI("conf = \n"); LOGI("\tuse_features0 = 0x%016LX (%s)\n", conf->use_features0, buf); @@ -1351,7 +1097,7 @@ static void print_conf(struct conf_t * conf) ); } -void print_replay_event( struct replay_event_t *ev, uint32_t num, char *tab) +void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab) { LOGW("%s\t#%04d:time=0x%08X %08X, " " id=0x%08X," @@ -1368,10 +1114,10 @@ void print_replay_event( struct replay_event_t *ev, uint32_t num, char *tab) ); } -void print_replay_event_seq( struct replay_event_seq_t *event_seq) +void print_replay_event_seq(struct replay_event_seq_t *event_seq) { uint32_t i = 0; - char *tab="\t"; + char *tab = "\t"; LOGI( "%senabled=0x%08X; "\ "time_start=0x%08X %08X; "\ diff --git a/daemon/da_protocol.h b/daemon/da_protocol.h index dbce0c9..f909b84 100644 --- a/daemon/da_protocol.h +++ b/daemon/da_protocol.h @@ -150,7 +150,7 @@ enum feature_code{ IS_OPT_SET(FL_DEVICE) || \ IS_OPT_SET(FL_ENERGY)) -enum app_type{ +enum app_type { AT_TIZEN =0x01, AT_LAUNCHED =0x02, AT_COMMON =0x03 @@ -179,8 +179,8 @@ struct msg_data_t { }; #define MSG_CMD_HDR_LEN 8 - -struct msg_buf_t{ +//conf +struct msg_buf_t { char *payload; char *cur_pos; char *end; @@ -194,17 +194,6 @@ struct msg_t { }; -enum app_type_t { - APP_TYPE_TIZEN = 1, - APP_TYPE_RUNNING = 2, - APP_TYPE_COMMON = 3, -}; -struct app_info_t { - uint32_t app_type; - char *app_id; - char *exe_path; -}; - struct conf_t { uint64_t use_features0; uint64_t use_features1; @@ -214,45 +203,38 @@ struct conf_t { typedef uint32_t log_interval_t; -struct probe_t { - uint64_t addr; - uint32_t arg_num; - char *arg_fmt; +//app, libs, probes +enum app_type_t { + APP_TYPE_TIZEN = 1, + APP_TYPE_RUNNING = 2, + APP_TYPE_COMMON = 3, }; - -struct us_inst_t { - char * path; - uint32_t probe_num; - struct probe_t *probes; +struct app_info_t { + uint32_t app_type; + char *app_id; + char *exe_path; }; -struct us_func_inst_t { + + +struct us_func_inst_plane_t { uint64_t func_addr; - char *args; + char args[0]; }; struct us_lib_inst_t { - char * bin_path; - uint32_t func_num; - struct us_func_inst_t *us_func_inst_list; -}; - -struct app_inst_t { - uint32_t app_type; - char * app_id; - char * exec_path; - uint32_t func_num; - struct us_func_inst_t *us_func_inst_list; - uint32_t lib_num; - struct us_lib_inst_t *us_lib_inst_list; + char *bin_path; }; struct user_space_inst_t { uint32_t app_num; - struct app_inst_t *app_inst_list; + struct app_list_t *app_inst_list; + uint32_t lib_num; + struct lib_list_t *lib_inst_list; }; +//replays struct replay_event_t { uint32_t id; struct input_event ev; @@ -266,16 +248,15 @@ struct replay_event_seq_t { }; struct prof_session_t { - struct app_info_t app_info; struct conf_t conf; struct user_space_inst_t user_space_inst; struct replay_event_seq_t replay_event_seq; }; -int parseHostMessage(struct msg_t *log, char* msg); +int parseHostMessage(struct msg_t *log, char *msg); int host_message_handler(struct msg_t *msg); -char* msg_ID_str ( enum HostMessageT ID); +char *msg_ID_str(enum HostMessageT ID); // testing #include @@ -283,12 +264,12 @@ char* msg_ID_str ( enum HostMessageT ID); #include //data protocol -struct thread_info_t{ +struct thread_info_t { uint32_t pid; float load; }; -struct process_info_t{ +struct process_info_t { uint32_t id; float load; }; @@ -333,7 +314,7 @@ struct system_info_t { uint32_t app_energy_per_device[supported_devices_count]; }; -struct recorded_event_t{ +struct recorded_event_t { uint32_t id; uint32_t type; uint32_t code; @@ -401,9 +382,16 @@ void reset_system_info(struct system_info_t *sys); extern struct prof_session_t prof_session; //debugs -void print_replay_event( struct replay_event_t *ev, uint32_t num, char *tab); +void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab); int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code, char *payload, int payload_size); +int parse_int32(struct msg_buf_t *msg, uint32_t *val); +int parse_int64(struct msg_buf_t *msg, uint64_t *val); +int parse_string(struct msg_buf_t *msg, char **str); +int parse_string_no_alloc(struct msg_buf_t *msg, char *str); +int parse_replay_event_seq(struct msg_buf_t *msg, struct replay_event_seq_t *res); + +void init_prof_session(struct prof_session_t *prof_session); #endif /* _DA_PROTOCOL_ */ diff --git a/daemon/da_protocol_check.c b/daemon/da_protocol_check.c index 1e184ff..0d03cf8 100644 --- a/daemon/da_protocol_check.c +++ b/daemon/da_protocol_check.c @@ -166,7 +166,7 @@ int check_us_inst_func_args(char *args) char *p; for (p = args; *p != 0; p++) if (strchr(args_avail, (int)*p) == NULL){ - LOGE("wrong args <%s> char <%c>\n", args, (int)*p); + LOGE("wrong args <%s> char <%c> <0x%02X>\n", args, (int)*p, (char)*p); return 0; } return 1; @@ -185,3 +185,24 @@ int check_lib_inst_count(uint32_t lib_count) return res; } + +int check_conf(struct conf_t *conf) +{ + //Check features value + if (!check_conf_features(conf->use_features0, conf->use_features1)) { + LOGE("check features fail\n"); + return 0; + } + + if (!check_conf_systrace_period(conf->system_trace_period)) { + LOGE("system trace period error\n"); + return 0; + } + + if (!check_conf_datamsg_period(conf->data_message_period)) { + LOGE("data message period error\n"); + return 0; + } + + return 1; +} diff --git a/daemon/da_protocol_check.h b/daemon/da_protocol_check.h index 1e2a5b2..df8c3e7 100644 --- a/daemon/da_protocol_check.h +++ b/daemon/da_protocol_check.h @@ -59,3 +59,4 @@ int check_us_app_count(uint32_t app_count); int check_us_app_inst_func_count(uint32_t func_count); int check_us_inst_func_args(char *args); int check_lib_inst_count(uint32_t lib_count); +int check_conf(struct conf_t *conf); diff --git a/daemon/da_protocol_inst.c b/daemon/da_protocol_inst.c new file mode 100644 index 0000000..be425cd --- /dev/null +++ b/daemon/da_protocol_inst.c @@ -0,0 +1,247 @@ +/* + * DA manager + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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: + * - Samsung RnD Institute Russia + * + */ + +#include "debug.h" +#include "da_protocol.h" +#include "da_inst.h" +#include "da_protocol_check.h" + +//----------------- hash +static uint32_t calc_lib_hash(struct us_lib_inst_t *lib) +{ + uint32_t hash = 0; + char *p = lib->bin_path; + while (*p != 0) { + hash <<= 1; + hash += *p; + p++; + } + return hash; +} + +static uint32_t calc_app_hash(struct app_info_t *app) +{ + uint32_t hash = 0; + char *p = app->exe_path; + while (*p != 0) { + hash <<= 1; + hash += *p; + p++; + } + return hash; +} + + +//----------------------------------- parse ----------------------------------- +int parse_us_inst_func(struct msg_buf_t *msg, struct probe_list_t **dest) +{ + uint32_t size = 0; + struct us_func_inst_plane_t *func; + + size = sizeof(*func) + strlen(msg->cur_pos + sizeof(func->func_addr) ) + 1; + func = malloc(size); + if (!parse_int64(msg, &(func->func_addr))) { + LOGE("func addr parsing error\n"); + free(func); + return 0; + } + + if (!parse_string_no_alloc(msg, func->args) || + !check_us_inst_func_args(func->args)) + { + LOGE("args format parsing error\n"); + free(func); + return 0; + } + + *dest = new_probe(); + if (*dest == NULL) { + LOGE("alloc new_probe error\n"); + free(func); + return 0; + } + (*dest)->size = size; + (*dest)->func = func; + return 1; +} + +int parse_func_inst_list(struct msg_buf_t *msg, + struct data_list_t *dest) +{ + uint32_t i = 0, num = 0; + struct probe_list_t *probe_el; + + if (!parse_int32(msg, &num) || + !check_us_app_inst_func_count(num)) + { + LOGE("func num parsing error\n"); + return 0; + } + //parse user space function list + + parse_deb("app_int_num = %d\n", num); + for (i = 0; i < num; i++) { + parse_deb("app_int #%d\n", i); + if (!parse_us_inst_func(msg, &probe_el)) { + // TODO maybe need to free allocated memory up there + LOGE("parse us inst func #%d failed\n", i + 1); + return 0; + } + probe_list_append(dest, probe_el); + } + dest->func_num = num; + return 1; +} + +int parse_inst_lib(struct msg_buf_t *msg, struct lib_list_t **dest) +{ + *dest = new_lib(); + if (*dest == NULL) { + LOGE("lib alloc error\n"); + return 0; + }; + + if (!parse_string(msg, &((*dest)->lib->bin_path)) || + !check_exec_path((*dest)->lib->bin_path)) + { + LOGE("bin path parsing error\n"); + return 0; + } + + if (!parse_func_inst_list(msg, (struct data_list_t *) *dest)) { + LOGE("funcs parsing error\n"); + return 0; + } + + (*dest)->size += strlen((*dest)->lib->bin_path) + 1 + sizeof((*dest)->func_num); + (*dest)->hash = calc_lib_hash((*dest)->lib); + return 1; + +} + +int parse_lib_inst_list(struct msg_buf_t *msg, + uint32_t *num, + struct lib_list_t **lib_list) +{ + uint32_t i = 0; + struct lib_list_t *lib = NULL; + if (!parse_int32(msg, num) || + !check_lib_inst_count(*num)) + { + LOGE("lib num parsing error\n"); + return 0; + } + + for (i = 0; i < *num; i++) { + if (!parse_inst_lib(msg, &lib)) { + // TODO maybe need free allocated memory up there + LOGE("parse is inst lib #%d failed\n", i + 1); + return 0; + } + data_list_append((struct data_list_t **)lib_list, + (struct data_list_t *)lib); + } + + return 1; +} + +int parse_inst_app(struct msg_buf_t *msg, struct app_list_t **dest) +{ + char *start, *end; + struct app_info_t *app_info = NULL; + *dest = new_app(); + + if (*dest == NULL) { + LOGE("lib alloc error\n"); + return 0; + }; + + app_info = (*dest)->app; + start = msg->cur_pos; + if (!parse_int32(msg, &app_info->app_type) || + !check_app_type(app_info->app_type)) + { + LOGE("app type parsing error <0x%X>\n", app_info->app_type); + return 0; + } + + if (!parse_string(msg, &app_info->app_id) || + !check_app_id(app_info->app_type, app_info->app_id)) + { + LOGE("app id parsing error\n"); + return 0; + } + if (!parse_string(msg, &app_info->exe_path) || + !check_exec_path(app_info->exe_path)) + { + LOGE("exec path parsing error\n"); + return 0; + } + end = msg->cur_pos; + + if (!parse_func_inst_list(msg, (struct data_list_t *)*dest)) { + LOGE("funcs parsing error\n"); + return 0; + } + + (*dest)->size += (end - start) + sizeof((*dest)->func_num); + (*dest)->hash = calc_app_hash((struct app_info_t *)&((*dest)->app)); + return 1; +} + +int parse_app_inst_list(struct msg_buf_t *msg, + uint32_t *num, + struct app_list_t **app_list) +{ + uint32_t i = 0; + struct app_list_t *app = NULL; + if (!parse_int32(msg, num) || + !check_lib_inst_count(*num)) + { + LOGE("app num parsing error\n"); + return 0; + } + + parse_deb("app_int_num = %d\n", *num); + for (i = 0; i < *num; i++) { + parse_deb("app_int #%d\n", i); + if (!parse_inst_app(msg, &app)) { + // TODO maybe need free allocated memory up there + LOGE("parse is inst app #%d failed\n", i + 1); + return 0; + } + data_list_append((struct data_list_t **)app_list, + (struct data_list_t *)app); + } + + if (!parse_replay_event_seq(msg, &prof_session.replay_event_seq)) { + LOGE("replay parsing error\n"); + return 0; + } + + return 1; +} + diff --git a/daemon/da_protocol_inst.h b/daemon/da_protocol_inst.h new file mode 100644 index 0000000..2d8ec18 --- /dev/null +++ b/daemon/da_protocol_inst.h @@ -0,0 +1,46 @@ +/* + * DA manager + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Cherepanov Vitaliy + * + * 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: + * - Samsung RnD Institute Russia + * + */ +#ifndef __DA_PROTOCOL_INST__ +#define __DA_PROTOCOL_INST__ + +int parse_us_inst_func(struct msg_buf_t *msg, struct probe_list_t **dest); + +int parse_func_inst_list(struct msg_buf_t *msg, + struct data_list_t *dest); + +int parse_inst_lib(struct msg_buf_t *msg, struct lib_list_t **dest); + +int parse_lib_inst_list(struct msg_buf_t *msg, + uint32_t *num, + struct lib_list_t **lib_list); + +int parse_inst_app(struct msg_buf_t *msg, struct app_list_t **dest); + +int parse_app_inst_list(struct msg_buf_t *msg, + uint32_t *num, + struct app_list_t **app_list); + +#endif /* __DA_PROTOCOL_INST__ */ diff --git a/daemon/daemon.c b/daemon/daemon.c index 888fad6..c053d25 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -59,6 +59,7 @@ #include "sys_stat.h" #include "utils.h" #include "da_protocol.h" +#include "da_inst.h" #include "da_data.h" #include "debug.h" #include "process_info.h" @@ -320,8 +321,11 @@ static int stop_app_launch_timer() static int exec_app(const struct app_info_t *app_info) { int res = 0; - static struct epoll_event ev; + if (app_info == NULL) { + LOGE("Cannot exec app. app_info is NULL"); + return -1; + } switch (app_info->app_type) { case APP_TYPE_TIZEN: @@ -350,7 +354,7 @@ static int exec_app(const struct app_info_t *app_info) } if (res == 0 && app_info->app_type != APP_TYPE_RUNNING) - if (start_app_launch_timer()<0) + if (start_app_launch_timer() < 0) res = -1; LOGI("ret=%d\n", res); @@ -405,9 +409,17 @@ static void epoll_del_input_events(); int start_profiling() { - const struct app_info_t *app_info = &prof_session.app_info; + struct app_list_t *app = NULL; + const struct app_info_t *app_info = NULL; int res = 0; + app_info = app_info_get_first(&app); + if (app_info == NULL) { + LOGE("No app info found\n"); + return -1; + } + + // remove previous screen capture files remove_indir(SCREENSHOT_DIR); if (mkdir(SCREENSHOT_DIR, 0777) == -1 && errno != EEXIST) @@ -557,8 +569,7 @@ static int deviceEventHandler(input_dev* dev, int input_type) struct input_event in_ev[MAX_EVENTS_NUM]; struct msg_data_t *log; - if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY) - { + if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY) { do { size = read(dev->fd, &in_ev[count], sizeof(*in_ev) ); if (size >0) @@ -574,9 +585,7 @@ static int deviceEventHandler(input_dev* dev, int input_type) write_to_buf(log); free_msg_data(log); } - } - else - { + } else { LOGW("unknown input_type\n"); ret = 1; // it is not error } @@ -585,12 +594,25 @@ static int deviceEventHandler(input_dev* dev, int input_type) static int target_event_pid_handler(int index, uint64_t msg) { + struct app_list_t *app = NULL; + struct app_info_t *app_info = NULL; if (index == 0) { // main application - if (!is_same_app_process(prof_session.app_info.exe_path, - manager.target[index].pid)) { - LOGE("is same error: '%s' is not %d\n", - prof_session.app_info.exe_path, - manager.target[index].pid); + app_info = app_info_get_first(&app); + if (app_info == NULL) { + LOGE("No app info found\n"); + return -1; + } + + while (app_info != NULL) { + if (is_same_app_process(app_info->exe_path, + manager.target[index].pid)) + break; + app_info = app_info_get_next(&app); + } + + if (app_info == NULL) { + LOGE("pid %d not found in app list\n", + manager.target[index].pid); return -1; } @@ -845,7 +867,7 @@ static int controlSocketHandler(int efd) if (recv_len == -1) return -11; } - printBuf(msg, MSG_DATA_HDR_LEN + msg->len); + printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len); res = host_message_handler(msg); free(msg); } @@ -955,6 +977,8 @@ int daemonLoop() goto END_EFD; } + init_prof_session(&prof_session); + // handler loop while (1) { diff --git a/daemon/debug.c b/daemon/debug.c index 648b31c..00e584e 100644 --- a/daemon/debug.c +++ b/daemon/debug.c @@ -35,7 +35,7 @@ void print_buf(char * buf, int len, const char *info) { int i,j; - char local_buf[3*16 + 2*16 + 1 + 8]; + char local_buf[3*17 + 2*16 + 1 + 8]; char * p1, * p2; LOGI("BUFFER [%d] <%s>:\n", len, info); diff --git a/daemon/process_info.c b/daemon/process_info.c index c007e77..77dbab0 100644 --- a/daemon/process_info.c +++ b/daemon/process_info.c @@ -30,6 +30,7 @@ #include #include "da_protocol.h" #include "da_data.h" +#include "da_inst.h" #include "utils.h" #include "elf.h" #include "debug.h" @@ -40,16 +41,19 @@ #define AWK_END_PROCESS "/maps | grep 'r-x' | awk '{print $1, $6}' | grep " #define AWK_SYSTEM_UP_TIME "cat /proc/uptime | awk '{print $1}'" +// TODO don't make me cry void write_process_info(int pid, uint64_t starttime) { // TODO refactor this code char buf[1024]; - struct msg_data_t *msg = malloc(64 * 1024); + struct msg_data_t *msg = NULL; char *p = msg->payload; char *dep_count_p = NULL; int dep_count = 0; + struct app_list_t *app = NULL; + struct app_info_t *app_info = NULL; // TODO: add check for unknown type - uint32_t binary_type = get_binary_type(prof_session.app_info.exe_path); + uint32_t binary_type = BINARY_TYPE_UNKNOWN; char binary_path[PATH_MAX]; uint64_t start, end; float process_up_time; @@ -60,10 +64,19 @@ void write_process_info(int pid, uint64_t starttime) int fields; FILE *f; + app_info = app_info_get_first(&app); + if (app_info == NULL) { + LOGE("No app info found\n"); + return; + } + binary_type = get_binary_type(app_info->exe_path); + // TODO need check this result and return error - dereference_tizen_exe_path(prof_session.app_info.exe_path, path); - get_build_dir(binary_path, prof_session.app_info.exe_path); + dereference_tizen_exe_path(app_info->exe_path, path); + get_build_dir(binary_path, app_info->exe_path); + msg = malloc(64 * 1024); + p = msg->payload; fill_data_msg_head(msg, NMSG_PROCESS_INFO, 0, 0); sprintf(buf, "%s%d%s%s", AWK_START, pid, AWK_END_PROCESS,path); -- 2.7.4