Commit 34427d8b authored by Micha Müller's avatar Micha Müller
Browse files

Caliper-service:

-use variable length char arrays to store symbol names
-fix unnoticed bug in Pusher-plugin
parent de38e004
......@@ -81,12 +81,12 @@ using namespace cali;
namespace {
#define MAX_SYMBOL_SIZE 512 //symbol names are not limited by any means but our memory is
#define MAX_PATH_SIZE 4096 //linux paths are not allowed to be longer than 4096 chars
#define MSGQ_SIZE 8192
#define STR_PREFIX "/cali_dcdb_"
#define SHM_SIZE (32*1024*1024)
#define SOCK_NAME "DCDBPusherCaliSocket"
#define MAX_SYMBOL_SIZE 4096 //symbol names are not limited by any means but our memory is
#define MAX_PATH_SIZE 4096 //linux paths are not allowed to be longer than 4096 chars
#define MSGQ_SIZE 8192
#define STR_PREFIX "/cali_dcdb_"
#define SHM_SIZE (32*1024*1024)
#define SOCK_NAME "DCDBPusherCaliSocket"
typedef struct {
uintptr_t pc;
......@@ -95,10 +95,13 @@ typedef struct {
} snap_data;
/* Entry for an executable symbol in the symbol table */
//we cannot have variable length arrays in structs without mallocing them...
//therefore every symbol data entry is implicitly followed by a string
typedef struct {
uintptr_t start_addr;
uintptr_t end_addr;
char name[MAX_SYMBOL_SIZE];
size_t str_size; // including terminating NUL byte
//char name[str_size];
} fsym_data;
/* Defines a contiguous executable memory block */
......@@ -263,7 +266,9 @@ private:
char* symstr;
char* dsymstr;
int status = -1;
fsym_data symdat;
char symdat_name[MAX_SYMBOL_SIZE];
symstr = elf_strptr(elf, shdr.sh_link, sym.st_name);
......@@ -274,15 +279,19 @@ private:
}
if (status == 0) {
strncpy(symdat.name, dsymstr, 512);
strncpy(symdat_name, dsymstr, MAX_SYMBOL_SIZE);
free((void*) dsymstr);
} else {
strncpy(symdat.name, symstr, 512);
strncpy(symdat_name, symstr, MAX_SYMBOL_SIZE);
}
symdat.name[MAX_SYMBOL_SIZE-1] = '\0';
symdat_name[MAX_SYMBOL_SIZE-1] = '\0';
symdat.str_size = strlen(symdat_name) + 1;
} else {
symdat.name[0] = '\0';
symdat_name[0] = '\0';
symdat.str_size = 1;
}
//NOTE ensure that symdat_name is NUL terminated at this point
// and symdat.str_size is set accordingly
//resolve symbol value aka its address in this' process virtual memory
symdat.start_addr = sym_offset + sym.st_value;
......@@ -298,11 +307,18 @@ private:
// sym.st_size);
shm_bytes_written += sizeof(fsym_data);
shm_bytes_written += strlen(symdat_name) + 1;
if (shm_bytes_written <= SHM_SIZE) {
memcpy(dest_ptr, &symdat, sizeof(fsym_data));
++dest_ptr;
strcpy(reinterpret_cast<char*>(dest_ptr), symdat_name);
dest_ptr = reinterpret_cast<fsym_data*>(
reinterpret_cast<char*>(dest_ptr) + symdat.str_size);
++entryCnt;
} else {
//unlikely (at least it should be)
shm_bytes_written -= sizeof(fsym_data);
shm_bytes_written -= strlen(symdat_name) + 1;
Log(1).stream() << chn->name() << ": DcdbPusher: Not enough shared memory!" << std::endl;
elf_end(elf);
close(fd);
......@@ -391,6 +407,8 @@ private:
++addr_ptr;
++addr_cnt;
} else {
//VERY unlikely
shm_bytes_written -= sizeof(addr_data);
Log(1).stream() << chn->name() << ": DcdbPusher: Running out of shared memory!" << std::endl;
fclose(file);
return false;
......@@ -410,13 +428,14 @@ private:
if (addr_ptr->pathname[0] == '/') {
//debug
//printf("Parsing symbols for %s (%llx-%llx; %llx)\n", addr_ptr->pathname, addr_ptr->start_addr, addr_ptr->end_addr, addr_ptr->offset);
size_t tmp = shm_bytes_written;
addr_ptr->fsym_count = write_function_symbols(addr_ptr->pathname,
addr_ptr->start_addr,
addr_ptr->end_addr,
addr_ptr->offset,
fsym_ptr,
chn);
fsym_offset += addr_ptr->fsym_count * sizeof(fsym_data);
fsym_offset += shm_bytes_written - tmp;
}
//forward slashes are reserved for MQTT topics, use double colon instead
......@@ -451,10 +470,13 @@ private:
fsym_ptr = reinterpret_cast<const fsym_data*>(
reinterpret_cast<const char*>(addr_ptr) + addr_ptr->fsym_offset);
for (size_t j = 0; j < addr_ptr->fsym_count; ++j) {
printf("> %s (%llx-%llx)\n", fsym_ptr->name,
fsym_ptr->start_addr,
fsym_ptr->end_addr);
size_t str_size = fsym_ptr->str_size;
printf("> (%llx-%llx)", fsym_ptr->start_addr,
fsym_ptr->end_addr);
++fsym_ptr;
printf(" %s\n", reinterpret_cast<const char*>(fsym_ptr));
fsym_ptr = reinterpret_cast<const fsym_data*>(
reinterpret_cast<const char*>(fsym_ptr) + str_size);
}
printf("\n");
sym_cnt += addr_ptr->fsym_count;
......
......@@ -258,14 +258,19 @@ void CaliperSensorGroup::read() {
if (pc >= addrs[j].start_addr && pc <= addrs[j].end_addr) {
sName += addrs[j].pathname;
const fsym_data* const fsyms = reinterpret_cast<const fsym_data* const>(
reinterpret_cast<const char* const>(addrs) + addrs[j].fsym_offset);
const fsym_data* fsyms = reinterpret_cast<const fsym_data*>(
reinterpret_cast<const char*>(&addrs[j]) + addrs[j].fsym_offset);
for(size_t k = 0; k < addrs[j].fsym_count; ++k) {
if (pc >= fsyms[k].start_addr && pc <= fsyms[k].end_addr) {
if (pc >= fsyms->start_addr && pc <= fsyms->end_addr) {
++fsyms;
sName += "::";
sName += fsyms[k].name;
sName += reinterpret_cast<const char*>(fsyms);
break;
}
size_t str_size = fsyms->str_size;
++fsyms;
fsyms = reinterpret_cast<const fsym_data*>(
reinterpret_cast<const char*>(fsyms) + str_size);
} //It's OK if we found no symbol. There are possibly none
//store in sensors
......
......@@ -47,12 +47,12 @@ class CaliperSensorGroup : public SensorGroupTemplate<CaliperSensorBase> {
* Common defines. Keep in sync with DcdbPusher Caliper service
******************************************************************************/
#define SHM_MAX_RETRIES 15 //TODO make configurable
#define MAX_SYMBOL_SIZE 512 //symbol names are not limited by any means but our memory is
#define MAX_PATH_SIZE 4096 //linux paths are not allowed to be longer than 4096 chars
#define MSGQ_SIZE 8192
#define STR_PREFIX "/cali_dcdb_"
#define SHM_SIZE (32*1024*1024)
#define SOCK_NAME "DCDBPusherCaliSocket"
#define MAX_SYMBOL_SIZE 4096 //symbol names are not limited by any means but our memory is
#define MAX_PATH_SIZE 4096 //linux paths are not allowed to be longer than 4096 chars
#define MSGQ_SIZE 8192
#define STR_PREFIX "/cali_dcdb_"
#define SHM_SIZE (32*1024*1024)
#define SOCK_NAME "DCDBPusherCaliSocket"
typedef struct {
uintptr_t pc;
......@@ -61,10 +61,13 @@ typedef struct {
} snap_data;
/* Entry for an executable symbol in the symbol table */
//we cannot have variable length arrays in structs without mallocing them...
//therefore every symbol data entry is implicitly followed by a string
typedef struct {
uintptr_t start_addr;
uintptr_t end_addr;
char name[MAX_SYMBOL_SIZE];
size_t str_size; // including terminating NUL byte
//char name[str_size];
} fsym_data;
/* Defines a contiguous executable memory block */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment