1
0
mirror of https://github.com/meekrosoft/fff synced 2026-01-23 00:15:59 +01:00

Return values saved in history

On some contexts, we need to call one function to free some resource
allocated by another function based on the return value of the second
function. For example, every time pthread_mutex_trylock suceeds, you
need to unlock it, and only in those cases. While this could be done
with the return value sequence, it does not really work for a sequence
of custom fakes. Now we save the return values in the member
return_val_history, which works pretty much like arg_history, only
for the return values.
This commit is contained in:
Paulo Antonio Alvarez
2017-08-15 23:36:49 -03:00
parent 74c07a8f66
commit 89ea0e10d8

View File

@@ -37,8 +37,10 @@ def output_internal_helper_macros
define_reset_fake_macro
define_declare_arg_helper
define_declare_all_func_common_helper
define_declare_return_value_history
define_save_arg_helper
define_room_for_more_history
define_save_ret_history_helper
define_save_arg_history_helper
define_history_dropped_helper
define_value_function_variables_helper
@@ -88,12 +90,25 @@ def define_declare_all_func_common_helper
putd " unsigned int arg_histories_dropped; \\"
end
def define_declare_return_value_history
putd ""
putd "#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \\"
putd " RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN];"
end
def define_save_arg_helper
putd ""
putd "#define SAVE_ARG(FUNCNAME, n) \\"
putd " memcpy((void*)&FUNCNAME##_fake.arg##n##_val, (void*)&arg##n, sizeof(arg##n));"
end
def define_save_ret_history_helper
putd ""
putd "#define SAVE_RET_HISTORY(FUNCNAME, RETVAL) \\"
putd " if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN) \\"
putd " memcpy((void *)&FUNCNAME##_fake.return_val_history[FUNCNAME##_fake.call_count - 1], (const void *) &RETVAL, sizeof(RETVAL)); \\"
end
def define_room_for_more_history
putd ""
putd "#define ROOM_FOR_MORE_HISTORY(FUNCNAME) \\"
@@ -139,10 +154,13 @@ def define_return_fake_result_helper
putd "#define RETURN_FAKE_RESULT(FUNCNAME) \\"
putd " if (FUNCNAME##_fake.return_val_seq_len){ /* then its a sequence */ \\"
putd " if(FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) { \\"
putd " SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx]) \\"
putd " return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++]; \\"
putd " } \\"
putd " SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]) \\"
putd " return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]; /* return last element */ \\"
putd " } \\"
putd " SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val) \\"
putd " return FUNCNAME##_fake.return_val; \\"
end
@@ -261,6 +279,7 @@ def output_variables(arg_count, has_varargs, is_value_function)
}
putd "DECLARE_ALL_FUNC_COMMON \\"
putd "DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \\" unless not is_value_function
putd "DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \\" unless not is_value_function
putd "DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \\"
output_custom_function_signature(arg_count, has_varargs, is_value_function)
output_custom_function_array(arg_count, has_varargs, is_value_function)
@@ -330,15 +349,22 @@ def output_function_body(arg_count, has_varargs, is_value_function)
putd " #{custom_fake_call}\\"
end
putd " va_end(ap);\\"
putd " SAVE_RET_HISTORY(FUNCNAME, ret); \\" unless not is_value_function
putd " return ret;\\" if is_value_function
putd "}\\"
else
return_type = is_value_function ? "return " : ""
putd "if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \\"
putd " if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \\"
putd " #{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}); \\"
putd " RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}); \\" unless not is_value_function
putd " SAVE_RET_HISTORY(FUNCNAME, ret); \\" unless not is_value_function
putd " return ret; \\" unless not is_value_function
putd " #{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}); \\" unless is_value_function
putd " } \\"
putd " else{ \\"
putd " RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](#{arg_list(arg_count)}); \\" unless not is_value_function
putd " SAVE_RET_HISTORY(FUNCNAME, ret); \\" unless not is_value_function
putd " return ret; \\" unless not is_value_function
putd " #{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](#{arg_list(arg_count)}); \\"
putd " } \\"
putd "} \\"