-
Notifications
You must be signed in to change notification settings - Fork 34
Added a check to ensure memory tools is working #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| // Copyright 2018 Open Source Robotics Foundation, Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #ifndef OSRF_TESTING_TOOLS_CPP__MEMORY_TOOLS__IS_WORKING_HPP_ | ||
| #define OSRF_TESTING_TOOLS_CPP__MEMORY_TOOLS__IS_WORKING_HPP_ | ||
|
|
||
| #include <string> | ||
| #include <cstdlib> | ||
|
|
||
| #include "./visibility_control.hpp" | ||
|
|
||
| namespace osrf_testing_tools_cpp | ||
| { | ||
| namespace memory_tools | ||
| { | ||
|
|
||
| /// Return true if memory tools is enabled, installed (LD_PRELOAD was done), and working. | ||
| /** | ||
| * This works by temporarily installing a on_malloc hook and then calling | ||
| * malloc in a way that cannot be optimized out by the compiler. | ||
| */ | ||
| OSRF_TESTING_TOOLS_CPP_MEMORY_TOOLS_PUBLIC | ||
| bool | ||
| is_working(); | ||
|
|
||
| /// Copy an input string into allocated memory, guaranteeing malloc is called. | ||
| /** | ||
| * Makes sure that the compiler doesn't optimize the malloc and free out. | ||
| * The content of the input string doesn't matter, but should be non-empty. | ||
| */ | ||
| OSRF_TESTING_TOOLS_CPP_MEMORY_TOOLS_PUBLIC | ||
| void | ||
| guaranteed_malloc(const std::string & str); | ||
|
|
||
| } // namespace memory_tools | ||
| } // namespace osrf_testing_tools_cpp | ||
|
|
||
| #endif // OSRF_TESTING_TOOLS_CPP__MEMORY_TOOLS__IS_WORKING_HPP_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| // Copyright 2018 Open Source Robotics Foundation, Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #include "osrf_testing_tools_cpp/memory_tools/is_working.hpp" | ||
|
|
||
| #include <string> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. |
||
|
|
||
| #include "osrf_testing_tools_cpp/memory_tools/register_hooks.hpp" | ||
|
|
||
| namespace osrf_testing_tools_cpp | ||
| { | ||
| namespace memory_tools | ||
| { | ||
|
|
||
| volatile char side_effect[1024]; | ||
|
|
||
| void | ||
| guaranteed_malloc(const std::string & str) | ||
| { | ||
| void * some_memory = std::malloc(1024); | ||
| // We need to do something with the malloc'ed memory to make sure this | ||
| // function doesn't get optimized away. memset isn't enough, so we do a | ||
| // memcpy from a passed in string, and then copy *that* out to an array that | ||
| // is globally visible (assuring we have a side-effect). This is enough to | ||
| // keep the optimizer away. | ||
| memcpy(some_memory, str.c_str(), str.length()); | ||
| memcpy((void *)side_effect, some_memory, str.length()); | ||
| std::free(some_memory); | ||
| } | ||
|
|
||
| bool | ||
| is_working() | ||
| { | ||
| auto original_on_malloc = get_on_malloc(); | ||
| bool malloc_was_called = false; | ||
| on_malloc([&]() {malloc_was_called = true;}); | ||
| std::string tmp("doesn't matter"); | ||
| guaranteed_malloc(tmp); | ||
| on_malloc(original_on_malloc); | ||
| return malloc_was_called; | ||
| } | ||
|
|
||
| } // namespace memory_tools | ||
| } // namespace osrf_testing_tools_cpp | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,18 +21,9 @@ | |
| #include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp" | ||
| #include "osrf_testing_tools_cpp/scope_exit.hpp" | ||
|
|
||
| volatile char side_effect[1024]; | ||
| void my_first_function(const std::string& str) | ||
| void my_first_function(const std::string & str) | ||
| { | ||
| void * some_memory = std::malloc(1024); | ||
| // We need to do something with the malloc'ed memory to make sure this | ||
| // function doesn't get optimized away. memset isn't enough, so we do a | ||
| // memcpy from a passed in string, and then copy *that* out to an array that | ||
| // is globally visible (assuring we have a side-effect). This is enough to | ||
| // keep the optimizer away. | ||
| memcpy(some_memory, str.c_str(), str.length()); | ||
| memcpy((void *)side_effect, some_memory, str.length()); | ||
| std::free(some_memory); | ||
| osrf_testing_tools_cpp::memory_tools::guaranteed_malloc(str); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI, the same pattern exists in https://github.com/osrf/osrf_testing_tools_cpp/blob/master/osrf_testing_tools_cpp/test/memory_tools/test_memory_tools.cpp#L152 , so we'll want to call the new function there as well.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, I'll update it to modify that instance as well, thanks! |
||
| } | ||
|
|
||
| int my_second_function(int a, int b) | ||
|
|
@@ -68,6 +59,7 @@ TEST(TestMemoryTools, test_example) { | |
| // enabling monitoring will allow checking to begin, but the default state is | ||
| // that dynamic memory calls are expected, so again either function will pass | ||
| osrf_testing_tools_cpp::memory_tools::enable_monitoring(); | ||
| ASSERT_TRUE(osrf_testing_tools_cpp::memory_tools::is_working()); | ||
| my_first_function(dummy); | ||
| EXPECT_EQ(my_second_function(1, 2), 3); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| // Copyright 2015 Open Source Robotics Foundation, Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #include <gtest/gtest.h> | ||
| #include <gtest/gtest-spi.h> | ||
|
|
||
| #include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp" | ||
| #include "osrf_testing_tools_cpp/scope_exit.hpp" | ||
|
|
||
| TEST(TestMemoryTools, test_is_not_working) { | ||
|
|
||
| // you must initialize memory tools, but uninitialization is optional | ||
| osrf_testing_tools_cpp::memory_tools::initialize(); | ||
| OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ | ||
| osrf_testing_tools_cpp::memory_tools::uninitialize(); | ||
| }); | ||
|
|
||
| osrf_testing_tools_cpp::memory_tools::enable_monitoring(); | ||
|
|
||
| ASSERT_FALSE(osrf_testing_tools_cpp::memory_tools::is_working()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we don't actually use
get_on_realloc/get_on_calloc/get_on_free, should we bother exposing them? I generally like to only expose the things that I'm using, to keep the API smaller.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered the same thing, but I errored on the side of symmetry. So unless there's some other reason I'd opt to not touch it again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine, we can leave it.