diff --git a/boards/boardctl.c b/boards/boardctl.c index caf459c4f3..c116883a9c 100644 --- a/boards/boardctl.c +++ b/boards/boardctl.c @@ -26,11 +26,12 @@ #include -#include #include +#include +#include #include #include -#include +#include #include #include diff --git a/libs/libbuiltin/Kconfig b/libs/libbuiltin/Kconfig index c48cc613e7..16a5479d3a 100644 --- a/libs/libbuiltin/Kconfig +++ b/libs/libbuiltin/Kconfig @@ -66,6 +66,25 @@ config COVERAGE_NONE endchoice +config COVERAGE_GCOV_DUMP_REBOOT + bool "Dump gcov data on reboot" + default n + ---help--- + Dump gcov data on reboot, this will cause the gcov data to be + dumped to the default path when the system is rebooted. + +config COVERAGE_DEFAULT_PREFIX_STRIP + string "Default gcov dump path prefix strip" + default "99" + ---help--- + The default prefix strip of the gcov data + +config COVERAGE_DEFAULT_PREFIX + string "Default gcov dump path prefix" + default "/data" + ---help--- + The default prefix to store the gcov data + choice prompt "Builtin profile support" default PROFILE_NONE diff --git a/libs/libbuiltin/libgcc/gcov.c b/libs/libbuiltin/libgcc/gcov.c index 914fbdc50d..2b0edec71a 100644 --- a/libs/libbuiltin/libgcc/gcov.c +++ b/libs/libbuiltin/libgcc/gcov.c @@ -22,15 +22,16 @@ * Included Files ****************************************************************************/ -#include #include +#include +#include #include #include -#include -#include #include +#include #include +#include /**************************************************************************** * Pre-processor Definitions @@ -246,7 +247,7 @@ static int gcov_process_path(FAR char *prefix, int strip, strcat(new_path, tokens[i]); if (access(new_path, F_OK) != 0) { - ret = mkdir(new_path, 0644); + ret = mkdir(new_path, 0777); if (ret != 0) { return -errno; @@ -297,12 +298,50 @@ static int gcov_write_file(FAR const char *filename, return ret; } +#ifdef CONFIG_COVERAGE_GCOV_DUMP_REBOOT +static int gcov_reboot_notify(FAR struct notifier_block *nb, + unsigned long action, FAR void *data) +{ + __gcov_dump(); + return 0; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ void __gcov_init(FAR struct gcov_info *info) { +#ifdef CONFIG_COVERAGE_GCOV_DUMP_REBOOT + static struct notifier_block nb; +#endif + char path[PATH_MAX] = CONFIG_COVERAGE_DEFAULT_PREFIX; + static int inited = 0; + struct tm *tm_info; + time_t cur; + + if (!inited) + { + cur = time(NULL); + tm_info = localtime(&cur); + + strftime(path + strlen(path), + PATH_MAX, + "/gcov_%Y%m%d_%H%M%S", + tm_info); + + setenv("GCOV_PREFIX_STRIP", CONFIG_COVERAGE_DEFAULT_PREFIX_STRIP, 1); + setenv("GCOV_PREFIX", path, 1); + +#ifdef CONFIG_COVERAGE_GCOV_DUMP_REBOOT + nb.notifier_call = gcov_reboot_notify; + register_reboot_notifier(&nb); +#endif + + inited++; + } + info->next = __gcov_info_start; __gcov_info_start = info; }