diff --git a/src/os/inc/osapi-error.h b/src/os/inc/osapi-error.h index c0af8e57e..b623292ca 100644 --- a/src/os/inc/osapi-error.h +++ b/src/os/inc/osapi-error.h @@ -84,6 +84,7 @@ typedef char os_err_name_t[OS_ERROR_NAME_LENGTH]; #define OS_ERR_STREAM_DISCONNECTED (-37) /**< @brief Stream disconnected */ #define OS_ERR_OPERATION_NOT_SUPPORTED (-38) /**< @brief Requested operation not support on supplied object(s) */ #define OS_ERR_INVALID_SIZE (-40) /**< @brief Invalid Size */ +#define OS_ERR_OUTPUT_TOO_LARGE (-41) /**< @brief Size of output exceeds limit */ /* ** Defines for File System Calls diff --git a/src/os/vxworks/src/os-impl-symtab.c b/src/os/vxworks/src/os-impl-symtab.c index ed4244761..3956f0541 100644 --- a/src/os/vxworks/src/os-impl-symtab.c +++ b/src/os/vxworks/src/os-impl-symtab.c @@ -175,7 +175,7 @@ BOOL OS_SymTableIterator_Impl(char *name, SYM_VALUE val, SYM_TYPE type, _Vx_usr_ if (memchr(name, 0, OS_MAX_SYM_LEN) == NULL) { OS_DEBUG("%s(): symbol name too long\n", __func__); - state->StatusCode = OS_ERROR; + state->StatusCode = OS_ERR_NAME_TOO_LONG; return (false); } @@ -190,6 +190,7 @@ BOOL OS_SymTableIterator_Impl(char *name, SYM_VALUE val, SYM_TYPE type, _Vx_usr_ ** However this is not considered an error, just a stop condition. */ OS_DEBUG("%s(): symbol table size exceeded\n", __func__); + state->StatusCode = OS_ERR_OUTPUT_TOO_LARGE; return (false); } @@ -264,6 +265,16 @@ int32 OS_SymbolTableDump_Impl(const char *filename, size_t size_limit) close(state->fd); } + /* + * If output size was zero this means a failure of the symEach call, + * in that it didn't iterate over anything at all. + */ + if (state->StatusCode == OS_SUCCESS && state->CurrSize == 0) + { + OS_DEBUG("%s(): No symbols found!\n", __func__); + state->StatusCode = OS_ERROR; + } + return (state->StatusCode); } /* end OS_SymbolTableDump_Impl */ diff --git a/src/unit-test-coverage/vxworks/adaptors/inc/ut-adaptor-symtab.h b/src/unit-test-coverage/vxworks/adaptors/inc/ut-adaptor-symtab.h index 9e8f1a32f..7a57eba32 100644 --- a/src/unit-test-coverage/vxworks/adaptors/inc/ut-adaptor-symtab.h +++ b/src/unit-test-coverage/vxworks/adaptors/inc/ut-adaptor-symtab.h @@ -31,5 +31,6 @@ #include "common_types.h" int32 UT_SymTabTest_CallIteratorFunc(const char *name, void *val, size_t TestSize, size_t SizeLimit); +int32 UT_SymTabTest_GetIteratorStatus(void); #endif /* UT_ADAPTOR_SYMTAB_H */ diff --git a/src/unit-test-coverage/vxworks/adaptors/src/ut-adaptor-symtab.c b/src/unit-test-coverage/vxworks/adaptors/src/ut-adaptor-symtab.c index 5cdbb8d10..7bce8bd23 100644 --- a/src/unit-test-coverage/vxworks/adaptors/src/ut-adaptor-symtab.c +++ b/src/unit-test-coverage/vxworks/adaptors/src/ut-adaptor-symtab.c @@ -47,3 +47,11 @@ int32 UT_SymTabTest_CallIteratorFunc(const char *name, void *val, size_t TestSiz */ return OS_SymTableIterator_Impl((char *)name, (OCS_SYM_VALUE)val, 0, 0, 0); } + +/* + * Gets the current status of the iterator function + */ +int32 UT_SymTabTest_GetIteratorStatus(void) +{ + return OS_VxWorks_SymbolDumpState.StatusCode; +} diff --git a/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c b/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c index 6bca6074b..85a37cc00 100644 --- a/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c +++ b/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c @@ -67,25 +67,51 @@ void Test_OS_SymTableIterator_Impl(void) */ uint32 Data = 0; + /* nominal case - nothing goes wrong */ OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 1000), true); + OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_SUCCESS); + + /* Check case where next entry will exceed size limit */ OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 101), false); + OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_ERR_OUTPUT_TOO_LARGE); + + /* Check case where entry has a name that is too long */ UT_SetDefaultReturnValue(UT_KEY(OCS_memchr), OS_ERROR); OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 1000), false); + OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_ERR_NAME_TOO_LONG); UT_ClearDefaultReturnValue(UT_KEY(OCS_memchr)); + + /* Check case where writing to file fails */ UT_SetDefaultReturnValue(UT_KEY(OCS_write), -1); OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 1000), false); + OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_ERROR); UT_ClearDefaultReturnValue(UT_KEY(OCS_write)); } +static int32 UT_symEachHook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context) +{ + uint32 Data = 0; + UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 1000); + return StubRetcode; +} + void Test_OS_SymbolTableDump_Impl(void) { /* Test Case For: * int32 OS_SymbolTableDump_Impl ( const char *filename, uint32 SizeLimit ) */ - OSAPI_TEST_FUNCTION_RC(OS_SymbolTableDump_Impl("file", 10000), OS_SUCCESS); + + /* With no action in symEach(), this will yield an empty file, which is an error */ + OSAPI_TEST_FUNCTION_RC(OS_SymbolTableDump_Impl("file", 10000), OS_ERROR); + + /* Check failure in open() */ UT_SetDefaultReturnValue(UT_KEY(OCS_open), -1); OSAPI_TEST_FUNCTION_RC(OS_SymbolTableDump_Impl("file", 10000), OS_ERROR); UT_ClearDefaultReturnValue(UT_KEY(OCS_open)); + + /* Set up a hook function for symEach() to provide at least one entry */ + UT_SetHookFunction(UT_KEY(OCS_symEach), UT_symEachHook, NULL); + OSAPI_TEST_FUNCTION_RC(OS_SymbolTableDump_Impl("file", 10000), OS_SUCCESS); } /* ------------------- End of test cases --------------------------------------*/