Compare commits
1 Commits
temp-deriv
...
fail-on-me
Author | SHA1 | Date | |
---|---|---|---|
3b93022e92 |
@@ -215,6 +215,11 @@ extern const char *(*MEM_name_ptr)(void *vmemh);
|
|||||||
* about memory leaks will be printed on exit. */
|
* about memory leaks will be printed on exit. */
|
||||||
void MEM_init_memleak_detection(void);
|
void MEM_init_memleak_detection(void);
|
||||||
|
|
||||||
|
/** When this has been called and memory leaks have been detected, the process will have an exit
|
||||||
|
* code that indicates failure. This can be used for when checking for memory leaks with automated
|
||||||
|
* tests. */
|
||||||
|
void MEM_enable_fail_on_memleak(void);
|
||||||
|
|
||||||
/* Switch allocator to slower but fully guarded mode. */
|
/* Switch allocator to slower but fully guarded mode. */
|
||||||
void MEM_use_guarded_allocator(void);
|
void MEM_use_guarded_allocator(void);
|
||||||
|
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
* \ingroup MEM
|
* \ingroup MEM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
#include "mallocn_intern.h"
|
#include "mallocn_intern.h"
|
||||||
|
|
||||||
@@ -28,6 +30,9 @@ char free_after_leak_detection_message[] =
|
|||||||
"error, use the 'construct on first use' idiom.";
|
"error, use the 'construct on first use' idiom.";
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
static bool fail_on_memleak = false;
|
||||||
|
|
||||||
class MemLeakPrinter {
|
class MemLeakPrinter {
|
||||||
public:
|
public:
|
||||||
~MemLeakPrinter()
|
~MemLeakPrinter()
|
||||||
@@ -42,6 +47,15 @@ class MemLeakPrinter {
|
|||||||
leaked_blocks,
|
leaked_blocks,
|
||||||
(double)mem_in_use / 1024 / 1024);
|
(double)mem_in_use / 1024 / 1024);
|
||||||
MEM_printmemlist();
|
MEM_printmemlist();
|
||||||
|
|
||||||
|
if (fail_on_memleak) {
|
||||||
|
/* There are many other ways to change the exit code to failure here:
|
||||||
|
* - Make the destructor noexcept(false) and throw an exception.
|
||||||
|
* - Call exit(EXIT_FAILURE).
|
||||||
|
* - Call terminate().
|
||||||
|
*/
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -59,3 +73,8 @@ void MEM_init_memleak_detection(void)
|
|||||||
*/
|
*/
|
||||||
static MemLeakPrinter printer;
|
static MemLeakPrinter printer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MEM_enable_fail_on_memleak(void)
|
||||||
|
{
|
||||||
|
fail_on_memleak = true;
|
||||||
|
}
|
||||||
|
@@ -751,6 +751,18 @@ static int arg_handle_abort_handler_disable(int UNUSED(argc),
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char arg_handle_fail_on_memleak_doc[] =
|
||||||
|
"\n\t"
|
||||||
|
"Exit with an exit code that indicates failure when memory leaks are detected.\n"
|
||||||
|
"This can be used to make automated tests fail.";
|
||||||
|
static int arg_handle_fail_on_memleak(int UNUSED(argc),
|
||||||
|
const char **UNUSED(argv),
|
||||||
|
void *UNUSED(data))
|
||||||
|
{
|
||||||
|
MEM_enable_fail_on_memleak();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const char arg_handle_background_mode_set_doc[] =
|
static const char arg_handle_background_mode_set_doc[] =
|
||||||
"\n\t"
|
"\n\t"
|
||||||
"Run in background (often used for UI-less rendering).";
|
"Run in background (often used for UI-less rendering).";
|
||||||
@@ -2267,6 +2279,8 @@ void main_args_setup(bContext *C, bArgs *ba)
|
|||||||
BLI_argsAdd(ba, 1, "-t", "--threads", CB(arg_handle_threads_set), NULL);
|
BLI_argsAdd(ba, 1, "-t", "--threads", CB(arg_handle_threads_set), NULL);
|
||||||
BLI_argsAdd(ba, 4, "-x", "--use-extension", CB(arg_handle_extension_set), C);
|
BLI_argsAdd(ba, 4, "-x", "--use-extension", CB(arg_handle_extension_set), C);
|
||||||
|
|
||||||
|
BLI_argsAdd(ba, 1, NULL, "--fail-on-memleak", CB(arg_handle_fail_on_memleak), NULL);
|
||||||
|
|
||||||
# undef CB
|
# undef CB
|
||||||
# undef CB_EX
|
# undef CB_EX
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ unset(_default_test_python_exe)
|
|||||||
|
|
||||||
# Standard Blender arguments for running tests.
|
# Standard Blender arguments for running tests.
|
||||||
# Specify exit code so that if a Python script error happens, the test fails.
|
# Specify exit code so that if a Python script error happens, the test fails.
|
||||||
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --python-exit-code 1)
|
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak --python-exit-code 1)
|
||||||
|
|
||||||
# Python CTests
|
# Python CTests
|
||||||
if(WITH_BLENDER AND WITH_PYTHON)
|
if(WITH_BLENDER AND WITH_PYTHON)
|
||||||
|
@@ -50,6 +50,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
MEM_use_guarded_allocator();
|
MEM_use_guarded_allocator();
|
||||||
MEM_init_memleak_detection();
|
MEM_init_memleak_detection();
|
||||||
|
MEM_enable_fail_on_memleak();
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
BLENDER_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
|
BLENDER_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
google::InitGoogleLogging(argv[0]);
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
@@ -36,12 +36,12 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_OUT_DIR})
|
|||||||
# all calls to blender use this
|
# all calls to blender use this
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
if(${CMAKE_GENERATOR} MATCHES "Xcode")
|
if(${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||||
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup)
|
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak)
|
||||||
else()
|
else()
|
||||||
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
|
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
|
set(TEST_BLENDER_EXE_PARAMS --background -noaudio --factory-startup --debug-memory --fail-on-memleak --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
|
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
|
||||||
|
@@ -20,6 +20,8 @@ def get_arguments(filepath, output_filepath):
|
|||||||
"-noaudio",
|
"-noaudio",
|
||||||
"--factory-startup",
|
"--factory-startup",
|
||||||
"--enable-autoexec",
|
"--enable-autoexec",
|
||||||
|
"--debug-memory",
|
||||||
|
"--fail-on-memleak",
|
||||||
filepath,
|
filepath,
|
||||||
"-E", "CYCLES",
|
"-E", "CYCLES",
|
||||||
"-o", output_filepath,
|
"-o", output_filepath,
|
||||||
|
@@ -103,6 +103,8 @@ def get_arguments(filepath, output_filepath):
|
|||||||
"-noaudio",
|
"-noaudio",
|
||||||
"--factory-startup",
|
"--factory-startup",
|
||||||
"--enable-autoexec",
|
"--enable-autoexec",
|
||||||
|
"--debug-memory",
|
||||||
|
"--fail-on-memleak",
|
||||||
filepath,
|
filepath,
|
||||||
"-E", "BLENDER_EEVEE",
|
"-E", "BLENDER_EEVEE",
|
||||||
"-P",
|
"-P",
|
||||||
|
@@ -79,6 +79,8 @@ class AbstractBlenderRunnerTest(unittest.TestCase):
|
|||||||
'-noaudio',
|
'-noaudio',
|
||||||
'--factory-startup',
|
'--factory-startup',
|
||||||
'--enable-autoexec',
|
'--enable-autoexec',
|
||||||
|
'--debug-memory',
|
||||||
|
'--fail-on-memleak',
|
||||||
]
|
]
|
||||||
|
|
||||||
if blendfile:
|
if blendfile:
|
||||||
|
@@ -39,6 +39,8 @@ def get_arguments(filepath, output_filepath):
|
|||||||
"-noaudio",
|
"-noaudio",
|
||||||
"--factory-startup",
|
"--factory-startup",
|
||||||
"--enable-autoexec",
|
"--enable-autoexec",
|
||||||
|
"--debug-memory",
|
||||||
|
"--fail-on-memleak",
|
||||||
filepath,
|
filepath,
|
||||||
"-P",
|
"-P",
|
||||||
os.path.realpath(__file__),
|
os.path.realpath(__file__),
|
||||||
|
@@ -30,7 +30,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_OUT_DIR})
|
|||||||
# endif()
|
# endif()
|
||||||
|
|
||||||
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
|
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
|
||||||
set(TEST_BLENDER_EXE $<TARGET_FILE:blender> --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
|
set(TEST_BLENDER_EXE $<TARGET_FILE:blender> --background -noaudio --factory-startup --debug-memory --fail-on-memleak --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@@ -39,6 +39,8 @@ def get_arguments(filepath, output_filepath):
|
|||||||
"-noaudio",
|
"-noaudio",
|
||||||
"--factory-startup",
|
"--factory-startup",
|
||||||
"--enable-autoexec",
|
"--enable-autoexec",
|
||||||
|
"--debug-memory",
|
||||||
|
"--fail-on-memleak",
|
||||||
filepath,
|
filepath,
|
||||||
"-E", "BLENDER_WORKBENCH",
|
"-E", "BLENDER_WORKBENCH",
|
||||||
"-P",
|
"-P",
|
||||||
|
Reference in New Issue
Block a user