This is a copy of an issue from the closed cmock-forum.
inital post:
I mocked printf and used IgnoreAndReturn. Since then the test loops and never finishs.
Every time I stop the execution in gdb it is somewhere in CMock_Guts_MemChain.
Program received signal SIGINT, Interrupt.
0x0000000000423728 in CMock_Guts_MemChain (root_index=8, obj_index=272)
at /home/sschwarz/dev/COR4114/tools/Cmock/src/cmock.c:116
116 index = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE);
(gdb) where
#0 0x0000000000423728 in CMock_Guts_MemChain (root_index=8, obj_index=272)
at /home/sschwarz/dev/COR4114/tools/Cmock/src/cmock.c:116
#1 0x000000000040db0c in dbg_printf_CMockIgnoreAndReturn (cmock_line=55,
cmock_to_return=0 '\000')
(version is 2.0.203)
thx
first reply
Wow. that's a new one.
Can you post the function prototype you are using for printf (that is getting fed into the mock) and also the generated mock code? Out of curiosity, is that 32-bit or 64-it gcc? native?
Thanks
Mark
second reply
Hi Mark,
the prototype is:
uint8_t dbg_printf(const char* format, ...);
In my code I use macros like this to call it:
define DEBUG_PRINTF(...) dbg_printf(VA_ARGS)
The generated code is:
/* AUTOGENERATED FILE. DO NOT EDIT. */
include <string.h>
include <stdlib.h>
include <setjmp.h>
include "unity.h"
include "cmock.h"
include "Mockdebug.h"
typedef struct _CMOCK_dbg_setup_CALL_INSTANCE
{
UNITY_LINE_TYPE LineNumber;
int ReturnVal;
} CMOCK_dbg_setup_CALL_INSTANCE;
typedef struct _CMOCK_dbg_printf_CALL_INSTANCE
{
UNITY_LINE_TYPE LineNumber;
uint8_t ReturnVal;
char* Expected_format;
} CMOCK_dbg_printf_CALL_INSTANCE;
static struct MockdebugInstance
{
int dbg_setup_IgnoreBool;
int dbg_setup_FinalReturn;
CMOCK_dbg_setup_CALLBACK dbg_setup_CallbackFunctionPointer;
int dbg_setup_CallbackCalls;
CMOCK_MEM_INDEX_TYPE dbg_setup_CallInstance;
int dbg_printf_IgnoreBool;
uint8_t dbg_printf_FinalReturn;
CMOCK_dbg_printf_CALLBACK dbg_printf_CallbackFunctionPointer;
int dbg_printf_CallbackCalls;
CMOCK_MEM_INDEX_TYPE dbg_printf_CallInstance;
} Mock;
extern jmp_buf AbortFrame;
void Mockdebug_Verify(void)
{
UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
if (Mock.dbg_setup_IgnoreBool)
Mock.dbg_setup_CallInstance = CMOCK_GUTS_NONE;
UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.dbg_setup_CallInstance, cmock_line, "Function 'dbg_setup' called less times than expected.");
if (Mock.dbg_setup_CallbackFunctionPointer != NULL)
Mock.dbg_setup_CallInstance = CMOCK_GUTS_NONE;
if (Mock.dbg_printf_IgnoreBool)
Mock.dbg_printf_CallInstance = CMOCK_GUTS_NONE;
UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.dbg_printf_CallInstance, cmock_line, "Function 'dbg_printf' called less times than expected.");
if (Mock.dbg_printf_CallbackFunctionPointer != NULL)
Mock.dbg_printf_CallInstance = CMOCK_GUTS_NONE;
}
void Mockdebug_Init(void)
{
Mockdebug_Destroy();
}
void Mockdebug_Destroy(void)
{
CMock_Guts_MemFreeAll();
memset(&Mock, 0, sizeof(Mock));
Mock.dbg_setup_CallbackFunctionPointer = NULL;
Mock.dbg_setup_CallbackCalls = 0;
Mock.dbg_printf_CallbackFunctionPointer = NULL;
Mock.dbg_printf_CallbackCalls = 0;
}
int dbg_setup(void)
{
UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
CMOCK_dbg_setup_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_setup_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.dbg_setup_CallInstance);
Mock.dbg_setup_CallInstance = CMock_Guts_MemNext(Mock.dbg_setup_CallInstance);
if (Mock.dbg_setup_IgnoreBool)
{
if (cmock_call_instance == NULL)
return Mock.dbg_setup_FinalReturn;
Mock.dbg_setup_FinalReturn = cmock_call_instance->ReturnVal;
return cmock_call_instance->ReturnVal;
}
if (Mock.dbg_setup_CallbackFunctionPointer != NULL)
{
return Mock.dbg_setup_CallbackFunctionPointer(Mock.dbg_setup_CallbackCalls++);
}
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'dbg_setup' called more times than expected.");
cmock_line = cmock_call_instance->LineNumber;
return cmock_call_instance->ReturnVal;
}
void dbg_setup_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_setup_CALL_INSTANCE));
CMOCK_dbg_setup_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_setup_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_setup_CallInstance = CMock_Guts_MemChain(Mock.dbg_setup_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
cmock_call_instance->ReturnVal = cmock_to_return;
Mock.dbg_setup_IgnoreBool = (int)1;
}
void dbg_setup_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_setup_CALL_INSTANCE));
CMOCK_dbg_setup_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_setup_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_setup_CallInstance = CMock_Guts_MemChain(Mock.dbg_setup_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
cmock_call_instance->ReturnVal = cmock_to_return;
}
void dbg_setup_StubWithCallback(CMOCK_dbg_setup_CALLBACK Callback)
{
Mock.dbg_setup_CallbackFunctionPointer = Callback;
}
uint8_t dbg_printf(const char* format, ...)
{
UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_printf_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.dbg_printf_CallInstance);
Mock.dbg_printf_CallInstance = CMock_Guts_MemNext(Mock.dbg_printf_CallInstance);
if (Mock.dbg_printf_IgnoreBool)
{
if (cmock_call_instance == NULL)
return Mock.dbg_printf_FinalReturn;
Mock.dbg_printf_FinalReturn = cmock_call_instance->ReturnVal;
return cmock_call_instance->ReturnVal;
}
if (Mock.dbg_printf_CallbackFunctionPointer != NULL)
{
return Mock.dbg_printf_CallbackFunctionPointer(format, Mock.dbg_printf_CallbackCalls++);
}
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'dbg_printf' called more times than expected.");
cmock_line = cmock_call_instance->LineNumber;
UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_format, format, cmock_line, "Function 'dbg_printf' called with unexpected value for argument 'format'.");
return cmock_call_instance->ReturnVal;
}
void CMockExpectParameters_dbg_printf(CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance, const char* format)
{
cmock_call_instance->Expected_format = (char*)format;
}
void dbg_printf_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint8_t cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_printf_CALL_INSTANCE));
CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_printf_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_printf_CallInstance = CMock_Guts_MemChain(Mock.dbg_printf_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
cmock_call_instance->ReturnVal = cmock_to_return;
Mock.dbg_printf_IgnoreBool = (int)1;
}
void dbg_printf_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, const char* format, uint8_t cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_printf_CALL_INSTANCE));
CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_printf_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_printf_CallInstance = CMock_Guts_MemChain(Mock.dbg_printf_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
CMockExpectParameters_dbg_printf(cmock_call_instance, format);
cmock_call_instance->ReturnVal = cmock_to_return;
}
void dbg_printf_StubWithCallback(CMOCK_dbg_printf_CALLBACK Callback)
{
Mock.dbg_printf_CallbackFunctionPointer = Callback;
}
And the header:
/* AUTOGENERATED FILE. DO NOT EDIT. */
ifndef _MOCKDEBUG_H
define _MOCKDEBUG_H
include "debug.h"
void Mockdebug_Init(void);
void Mockdebug_Destroy(void);
void Mockdebug_Verify(void);
define dbg_setup_IgnoreAndReturn(cmock_retval) dbg_setup_CMockIgnoreAndReturn(LINE, cmock_retval)
void dbg_setup_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);
define dbg_setup_ExpectAndReturn(cmock_retval) dbg_setup_CMockExpectAndReturn(LINE, cmock_retval)
void dbg_setup_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);
typedef int (* CMOCK_dbg_setup_CALLBACK)(int cmock_num_calls);
void dbg_setup_StubWithCallback(CMOCK_dbg_setup_CALLBACK Callback);
define dbg_printf_IgnoreAndReturn(cmock_retval) dbg_printf_CMockIgnoreAndReturn(LINE, cmock_retval)
void dbg_printf_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint8_t cmock_to_return);
define dbg_printf_ExpectAndReturn(format, cmock_retval) dbg_printf_CMockExpectAndReturn(LINE, format, cmock_retval)
void dbg_printf_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, const char* format, uint8_t cmock_to_return);
typedef uint8_t (* CMOCK_dbg_printf_CALLBACK)(const char* format, int cmock_num_calls);
void dbg_printf_StubWithCallback(CMOCK_dbg_printf_CALLBACK Callback);
endif
It's 64bit:
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
third reply
Hmmm... That code looks right. Are you using the ruby scripts to generate a test runner for you? Can you verify that it is calling CMock_Init() and that function is calling Mockdebug_Init? I'm wondering if the Mock structure isn't getting cleared so that it's just following random memory locations or something? It seems unlikely, but maybe?
It's interesting that it's a function with a vararg that is giving you headaches, but at this point CMock just ignores the extra arguments (someday it will mock them... but not yet). Have you tried a different function in the same module? Does your dbg_setup have the same problem?
Thanks... sorry that I don't have any quick answers... hopefully we can work through this together.
Mark
rest
I was in vacation last week - sorry for the delay. Answer to your last post will follow soon.