da_data.c \
da_debug.c \
da_protocol.c \
+ da_protocol_inst.c \
+ da_inst.c \
daemon.c \
debug.c \
elf.c \
--- /dev/null
+/*
+ * DA manager
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+// TODO check memory (malloc, free)
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#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> <p=0x%08lX c=0x%08lX n=0x%08lX>\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;
+}
--- /dev/null
+/*
+ * DA manager
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __DA_INST_H__
+#define __DA_INST_H__
+
+#include <stdint.h>
+#include <sys/types.h>
+#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__*/
#include <sys/sysinfo.h>
#include "da_protocol.h"
+#include "da_inst.h"
#include "da_protocol_check.h"
#include "daemon.h"
#include "sys_stat.h"
{
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
#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,
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);
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;
return 0;
*str = strdup(msg->cur_pos);
- parse_deb("<%s>\n",*str);
+ parse_deb("<%s>\n", *str);
msg->cur_pos += len;
return 1;
}
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))
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))
*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;
}
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))
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");
LOGE("app info parsing error\n");
return 0;
}
-
// print_app_info(app_info);
-
return 1;
}
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");
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)
{
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)) {
return 0;
}
- if(res->enabled == 0){
+ if(res->enabled == 0) {
parse_deb("disable\n");
return 1;
}
//*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);
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");
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)) {
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)
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)
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)
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));
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) +
}
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;
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");
{
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;
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);
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",
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);
}
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"
);
}
-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);
);
}
-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,"
);
}
-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; "\
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
};
#define MSG_CMD_HDR_LEN 8
-
-struct msg_buf_t{
+//conf
+struct msg_buf_t {
char *payload;
char *cur_pos;
char *end;
};
-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;
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;
};
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 <sys/stat.h>
#include <unistd.h>
//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;
};
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;
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_ */
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;
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;
+}
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);
--- /dev/null
+/*
+ * DA manager
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - 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;
+}
+
--- /dev/null
+/*
+ * DA manager
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Cherepanov Vitaliy <v.cherepanov@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:
+ * - 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__ */
#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"
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:
}
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);
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)
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)
write_to_buf(log);
free_msg_data(log);
}
- }
- else
- {
+ } else {
LOGW("unknown input_type\n");
ret = 1; // it is not error
}
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;
}
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);
}
goto END_EFD;
}
+ init_prof_session(&prof_session);
+
// handler loop
while (1) {
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);
#include <errno.h>
#include "da_protocol.h"
#include "da_data.h"
+#include "da_inst.h"
#include "utils.h"
#include "elf.h"
#include "debug.h"
#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;
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);