testsuite: coverage: allow gcov data dump directly on console
When there is no buffer for gcov hex data, dump them directly to console. This saves RAM which can be used to hold more gcov data. Reduce number of gcov hex data send by console - do not send space between every two digits. Signed-off-by: Piotr Kosycarz <piotr.kosycarz@nordicsemi.no>
This commit is contained in:
parent
b5bc088529
commit
bc8b7dd6dd
|
@ -78,7 +78,8 @@ config COVERAGE_GCOV_HEAP_SIZE
|
|||
default 16384
|
||||
help
|
||||
This option configures the heap size allocated for gcov coverage
|
||||
data to be dumped over serial.
|
||||
data to be dumped over serial. If the value is 0, no buffer will be used,
|
||||
data will be dumped directly over serial.
|
||||
|
||||
config COVERAGE_DUMP
|
||||
bool "Dump coverage data on exit"
|
||||
|
@ -86,6 +87,15 @@ config COVERAGE_DUMP
|
|||
help
|
||||
Dump collected coverage information to console on exit.
|
||||
|
||||
config FORCE_COVERAGE
|
||||
bool "Force coverage"
|
||||
select HAS_COVERAGE_SUPPORT
|
||||
help
|
||||
Regardless of platform support, it will enable coverage data production.
|
||||
If the platform does not support coverage by default, setting this config
|
||||
does not guarantee that coverage data will be gathered.
|
||||
Application may not fit memory or crash at runtime.
|
||||
|
||||
config TEST_USERSPACE
|
||||
bool "Indicate that this test exercises user mode"
|
||||
help
|
||||
|
|
|
@ -36,25 +36,54 @@ void __gcov_exit(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* buff_write_u64 - Store 64 bit data on a buffer and return the size
|
||||
* print_u8 - Print 8 bit of gcov data
|
||||
*/
|
||||
static inline void print_u8(uint8_t v)
|
||||
{
|
||||
printk("%02x", v);
|
||||
}
|
||||
|
||||
/**
|
||||
* print_u32 - Print 32 bit of gcov data
|
||||
*/
|
||||
static inline void print_u32(uint32_t v)
|
||||
{
|
||||
uint8_t *ptr = (uint8_t *)&v;
|
||||
|
||||
print_u8(*ptr);
|
||||
print_u8(*(ptr+1));
|
||||
print_u8(*(ptr+2));
|
||||
print_u8(*(ptr+3));
|
||||
}
|
||||
|
||||
/**
|
||||
* write_u64 - Store 64 bit data on a buffer and return the size
|
||||
*/
|
||||
|
||||
static inline void buff_write_u64(void *buffer, size_t *off, uint64_t v)
|
||||
static inline void write_u64(void *buffer, size_t *off, uint64_t v)
|
||||
{
|
||||
memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v));
|
||||
if (buffer != NULL) {
|
||||
memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v));
|
||||
} else {
|
||||
print_u32(*((uint32_t *)&v));
|
||||
print_u32(*(((uint32_t *)&v) + 1));
|
||||
}
|
||||
*off = *off + sizeof(uint64_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* buff_write_u32 - Store 32 bit data on a buffer and return the size
|
||||
* write_u32 - Store 32 bit data on a buffer and return the size
|
||||
*/
|
||||
static inline void buff_write_u32(void *buffer, size_t *off, uint32_t v)
|
||||
static inline void write_u32(void *buffer, size_t *off, uint32_t v)
|
||||
{
|
||||
memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v));
|
||||
if (buffer != NULL) {
|
||||
memcpy((uint8_t *)buffer + *off, (uint8_t *)&v, sizeof(v));
|
||||
} else {
|
||||
print_u32(v);
|
||||
}
|
||||
*off = *off + sizeof(uint32_t);
|
||||
}
|
||||
|
||||
|
||||
size_t calculate_buff_size(struct gcov_info *info)
|
||||
{
|
||||
uint32_t iter;
|
||||
|
@ -102,14 +131,13 @@ size_t calculate_buff_size(struct gcov_info *info)
|
|||
return size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* populate_buffer - convert from gcov data set (info) to
|
||||
* gcov_to_gcda - convert from gcov data set (info) to
|
||||
* .gcda file format.
|
||||
* This buffer will now have info similar to a regular gcda
|
||||
* format.
|
||||
*/
|
||||
size_t populate_buffer(uint8_t *buffer, struct gcov_info *info)
|
||||
size_t gcov_to_gcda(uint8_t *buffer, struct gcov_info *info)
|
||||
{
|
||||
struct gcov_fn_info *functions;
|
||||
struct gcov_ctr_info *counters_per_func;
|
||||
|
@ -119,22 +147,22 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info)
|
|||
size_t buffer_write_position = 0;
|
||||
|
||||
/* File header. */
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_DATA_MAGIC);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_DATA_MAGIC);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->version);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->version);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->stamp);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->stamp);
|
||||
|
||||
#ifdef GCOV_12_FORMAT
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->checksum);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->checksum);
|
||||
#endif
|
||||
|
||||
for (iter_functions = 0U;
|
||||
|
@ -144,25 +172,25 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info)
|
|||
functions = info->functions[iter_functions];
|
||||
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FUNCTION);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FUNCTION);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FUNCTION_LENGTH);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FUNCTION_LENGTH);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->ident);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->ident);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->lineno_checksum);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->lineno_checksum);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->cfg_checksum);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->cfg_checksum);
|
||||
|
||||
counters_per_func = functions->ctrs;
|
||||
|
||||
|
@ -174,29 +202,28 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info)
|
|||
continue;
|
||||
}
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FOR_COUNTER(iter_counts));
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FOR_COUNTER(iter_counts));
|
||||
|
||||
#ifdef GCOV_12_FORMAT
|
||||
/* GCOV 12 counts the length by bytes */
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->num * 2U * 4);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->num * 2U * 4);
|
||||
#else
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->num * 2U);
|
||||
write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->num * 2U);
|
||||
#endif
|
||||
|
||||
for (iter_counter_values = 0U;
|
||||
iter_counter_values < counters_per_func->num;
|
||||
iter_counter_values++) {
|
||||
|
||||
buff_write_u64(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->\
|
||||
values[iter_counter_values]);
|
||||
write_u64(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->values[iter_counter_values]);
|
||||
}
|
||||
|
||||
counters_per_func++;
|
||||
|
@ -205,20 +232,21 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info)
|
|||
return buffer_write_position;
|
||||
}
|
||||
|
||||
void dump_on_console(const char *filename, char *ptr, size_t len)
|
||||
void dump_on_console_start(const char *filename)
|
||||
{
|
||||
uint32_t iter;
|
||||
|
||||
printk("\n%c", FILE_START_INDICATOR);
|
||||
while (*filename != '\0') {
|
||||
printk("%c", *filename++);
|
||||
}
|
||||
printk("%c", GCOV_DUMP_SEPARATOR);
|
||||
}
|
||||
|
||||
/* Data dump */
|
||||
|
||||
for (iter = 0U; iter < len; iter++) {
|
||||
printk(" %02x", (uint8_t)*ptr++);
|
||||
void dump_on_console_data(char *ptr, size_t len)
|
||||
{
|
||||
if (ptr != NULL) {
|
||||
for (size_t iter = 0U; iter < len; iter++) {
|
||||
print_u8((uint8_t)*ptr++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,21 +265,22 @@ void gcov_coverage_dump(void)
|
|||
printk("\nGCOV_COVERAGE_DUMP_START");
|
||||
while (gcov_list) {
|
||||
|
||||
dump_on_console_start(gcov_list->filename);
|
||||
size = calculate_buff_size(gcov_list);
|
||||
|
||||
buffer = k_heap_alloc(&gcov_heap, size, K_NO_WAIT);
|
||||
if (!buffer) {
|
||||
if (CONFIG_COVERAGE_GCOV_HEAP_SIZE > 0 && !buffer) {
|
||||
printk("No Mem available to continue dump\n");
|
||||
goto coverage_dump_end;
|
||||
}
|
||||
|
||||
written_size = populate_buffer(buffer, gcov_list);
|
||||
written_size = gcov_to_gcda(buffer, gcov_list);
|
||||
if (written_size != size) {
|
||||
printk("Write Error on buff\n");
|
||||
goto coverage_dump_end;
|
||||
}
|
||||
|
||||
dump_on_console(gcov_list->filename, buffer, size);
|
||||
dump_on_console_data(buffer, size);
|
||||
|
||||
k_heap_free(&gcov_heap, buffer);
|
||||
gcov_list = gcov_list->next;
|
||||
|
|
Loading…
Reference in a new issue