Merge branch '10-fix-symbols-resolution' into 'master'
Resolve "Fix symbol resolution for callbacks" Closes #10 See merge request ros_tracing/ros2_tracing!38
This commit is contained in:
commit
13da072929
6 changed files with 138 additions and 25 deletions
|
@ -57,7 +57,7 @@ if(TRACING_ENABLED)
|
||||||
list(APPEND SOURCES ${LTTNG_TP_FILES})
|
list(APPEND SOURCES ${LTTNG_TP_FILES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} ${SOURCES})
|
add_library(${PROJECT_NAME} SHARED ${SOURCES})
|
||||||
if(TRACING_ENABLED)
|
if(TRACING_ENABLED)
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC TRACETOOLS_LTTNG_ENABLED)
|
target_compile_definitions(${PROJECT_NAME} PUBLIC TRACETOOLS_LTTNG_ENABLED)
|
||||||
target_link_libraries(${PROJECT_NAME} ${LTTNG_LIBRARIES} -ldl)
|
target_link_libraries(${PROJECT_NAME} ${LTTNG_LIBRARIES} -ldl)
|
||||||
|
@ -87,8 +87,14 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
|
find_package(ament_cmake_gtest REQUIRED)
|
||||||
find_package(ament_lint_auto REQUIRED)
|
find_package(ament_lint_auto REQUIRED)
|
||||||
ament_lint_auto_find_test_dependencies()
|
ament_lint_auto_find_test_dependencies()
|
||||||
|
|
||||||
|
ament_add_gtest(test_utils test/test_utils.cpp)
|
||||||
|
if(TARGET test_utils)
|
||||||
|
target_link_libraries(test_utils ${PROJECT_NAME} -rdynamic)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ament_package()
|
ament_package()
|
||||||
|
|
|
@ -18,18 +18,24 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#define SYMBOL_UNKNOWN "UNKNOWN"
|
||||||
|
|
||||||
|
const char * _demangle_symbol(const char * mangled);
|
||||||
|
|
||||||
|
const char * _get_symbol_funcptr(void * funcptr);
|
||||||
|
|
||||||
template<typename T, typename ... U>
|
template<typename T, typename ... U>
|
||||||
void * get_address(std::function<T(U...)> f)
|
const char * get_symbol(std::function<T(U...)> f)
|
||||||
{
|
{
|
||||||
typedef T (fnType)(U...);
|
typedef T (fnType)(U...);
|
||||||
fnType ** fnPointer = f.template target<fnType *>();
|
fnType ** fnPointer = f.template target<fnType *>();
|
||||||
// Might be a lambda
|
// If we get an actual address
|
||||||
if (fnPointer == nullptr) {
|
if (fnPointer != nullptr) {
|
||||||
return 0;
|
void * funcptr = reinterpret_cast<void *>(*fnPointer);
|
||||||
|
return _get_symbol_funcptr(funcptr);
|
||||||
}
|
}
|
||||||
return reinterpret_cast<void *>(*fnPointer);
|
// Otherwise we have to go through target_type()
|
||||||
|
return _demangle_symbol(f.target_type().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * get_symbol(void * funptr);
|
|
||||||
|
|
||||||
#endif // TRACETOOLS__UTILS_HPP_
|
#endif // TRACETOOLS__UTILS_HPP_
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
<depend>liblttng-ust-dev</depend>
|
<depend>liblttng-ust-dev</depend>
|
||||||
|
|
||||||
|
<test_depend>ament_cmake_gtest</test_depend>
|
||||||
<test_depend>ament_lint_auto</test_depend>
|
<test_depend>ament_lint_auto</test_depend>
|
||||||
<test_depend>ament_lint_common</test_depend>
|
<test_depend>ament_lint_common</test_depend>
|
||||||
|
|
||||||
|
|
|
@ -18,28 +18,31 @@
|
||||||
#endif
|
#endif
|
||||||
#include "tracetools/utils.hpp"
|
#include "tracetools/utils.hpp"
|
||||||
|
|
||||||
const char * get_symbol(void * funptr)
|
const char * _demangle_symbol(const char * mangled)
|
||||||
{
|
{
|
||||||
#define SYMBOL_UNKNOWN "UNKNOWN"
|
|
||||||
#if defined(TRACETOOLS_LTTNG_ENABLED) && !defined(_WIN32)
|
#if defined(TRACETOOLS_LTTNG_ENABLED) && !defined(_WIN32)
|
||||||
#define SYMBOL_LAMBDA "[lambda]"
|
|
||||||
if (funptr == 0) {
|
|
||||||
return SYMBOL_LAMBDA;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dl_info info;
|
|
||||||
if (dladdr(funptr, &info) == 0) {
|
|
||||||
return SYMBOL_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * demangled = nullptr;
|
char * demangled = nullptr;
|
||||||
int status;
|
int status;
|
||||||
demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
|
demangled = abi::__cxa_demangle(mangled, NULL, 0, &status);
|
||||||
// Use demangled symbol if possible
|
// Use demangled symbol if possible
|
||||||
const char * demangled_val = (status == 0 ? demangled : info.dli_sname);
|
const char * demangled_val = (status == 0 ? demangled : mangled);
|
||||||
return demangled_val != 0 ? demangled_val : SYMBOL_UNKNOWN;
|
return demangled_val != 0 ? demangled_val : "UNKNOWN_demangling_failed";
|
||||||
#else
|
#else
|
||||||
(void)funptr;
|
(void)mangled;
|
||||||
return SYMBOL_UNKNOWN;
|
return "DISABLED__demangle_symbol";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * _get_symbol_funcptr(void * funcptr)
|
||||||
|
{
|
||||||
|
#if defined(TRACETOOLS_LTTNG_ENABLED) && !defined(_WIN32)
|
||||||
|
Dl_info info;
|
||||||
|
if (dladdr(funcptr, &info) == 0) {
|
||||||
|
return SYMBOL_UNKNOWN;
|
||||||
|
}
|
||||||
|
return _demangle_symbol(info.dli_sname);
|
||||||
|
#else
|
||||||
|
(void)funcptr;
|
||||||
|
return "DISABLED__get_symbol_funcptr";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
79
tracetools/test/test_utils.cpp
Normal file
79
tracetools/test/test_utils.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright 2019 Robert Bosch GmbH
|
||||||
|
//
|
||||||
|
// 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 <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "tracetools/utils.hpp"
|
||||||
|
|
||||||
|
void function_shared(const std::shared_ptr<int> p)
|
||||||
|
{
|
||||||
|
(void)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SomeClassWithCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SomeClassWithCallback() {}
|
||||||
|
|
||||||
|
void my_callback(int some_number, std::string some_string)
|
||||||
|
{
|
||||||
|
(void)some_number;
|
||||||
|
(void)some_string;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Testing symbol resolution for std::function object created from a function pointer.
|
||||||
|
*/
|
||||||
|
TEST(TestUtils, valid_symbol_funcptr) {
|
||||||
|
std::function<void(std::shared_ptr<int>)> f = &function_shared;
|
||||||
|
EXPECT_STREQ(get_symbol(f), "function_shared(std::shared_ptr<int>)") <<
|
||||||
|
"invalid symbol";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Testing symbol resolution for std::function object created from a lambda.
|
||||||
|
*/
|
||||||
|
TEST(TestUtils, valid_symbol_lambda) {
|
||||||
|
std::function<int(int)> l = [](int num) {return num + 1;};
|
||||||
|
EXPECT_STREQ(
|
||||||
|
get_symbol(l),
|
||||||
|
"TestUtils_valid_symbol_lambda_Test::TestBody()::{lambda(int)#1}") <<
|
||||||
|
"invalid symbol";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Testing symbol resolution for std::function object created from std::bind.
|
||||||
|
*/
|
||||||
|
TEST(TestUtils, valid_symbol_bind) {
|
||||||
|
SomeClassWithCallback scwc;
|
||||||
|
std::function<void(int, std::string)> fscwc = std::bind(
|
||||||
|
&SomeClassWithCallback::my_callback,
|
||||||
|
&scwc,
|
||||||
|
std::placeholders::_1,
|
||||||
|
std::placeholders::_2
|
||||||
|
);
|
||||||
|
EXPECT_STREQ(
|
||||||
|
get_symbol(
|
||||||
|
fscwc),
|
||||||
|
"std::_Bind<void (SomeClassWithCallback::*(SomeClassWithCallback*, "
|
||||||
|
"std::_Placeholder<1>, std::_Placeholder<2>))(int, std::__cxx11::basic_string"
|
||||||
|
"<char, std::char_traits<char>, std::allocator<char> >)>")
|
||||||
|
<<
|
||||||
|
"invalid symbol";
|
||||||
|
}
|
|
@ -25,62 +25,80 @@ if(BUILD_TESTING)
|
||||||
ament_target_dependencies(test_publisher
|
ament_target_dependencies(test_publisher
|
||||||
rclcpp
|
rclcpp
|
||||||
std_msgs
|
std_msgs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_publisher -rdynamic)
|
||||||
add_executable(test_subscription
|
add_executable(test_subscription
|
||||||
src/test_subscription.cpp
|
src/test_subscription.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_subscription
|
ament_target_dependencies(test_subscription
|
||||||
rclcpp
|
rclcpp
|
||||||
std_msgs
|
std_msgs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_subscription -rdynamic)
|
||||||
add_executable(test_intra
|
add_executable(test_intra
|
||||||
src/test_intra.cpp
|
src/test_intra.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_intra
|
ament_target_dependencies(test_intra
|
||||||
rclcpp
|
rclcpp
|
||||||
std_msgs
|
std_msgs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_intra -rdynamic)
|
||||||
add_executable(test_ping
|
add_executable(test_ping
|
||||||
src/test_ping.cpp
|
src/test_ping.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_ping
|
ament_target_dependencies(test_ping
|
||||||
rclcpp
|
rclcpp
|
||||||
std_msgs
|
std_msgs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_ping -rdynamic)
|
||||||
add_executable(test_pong
|
add_executable(test_pong
|
||||||
src/test_pong.cpp
|
src/test_pong.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_pong
|
ament_target_dependencies(test_pong
|
||||||
rclcpp
|
rclcpp
|
||||||
std_msgs
|
std_msgs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_pong -rdynamic)
|
||||||
add_executable(test_timer
|
add_executable(test_timer
|
||||||
src/test_timer.cpp
|
src/test_timer.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_timer
|
ament_target_dependencies(test_timer
|
||||||
rclcpp
|
rclcpp
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_timer -rdynamic)
|
||||||
add_executable(test_service
|
add_executable(test_service
|
||||||
src/test_service.cpp
|
src/test_service.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_service
|
ament_target_dependencies(test_service
|
||||||
rclcpp
|
rclcpp
|
||||||
std_srvs
|
std_srvs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_service -rdynamic)
|
||||||
add_executable(test_service_ping
|
add_executable(test_service_ping
|
||||||
src/test_service_ping.cpp
|
src/test_service_ping.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_service_ping
|
ament_target_dependencies(test_service_ping
|
||||||
rclcpp
|
rclcpp
|
||||||
std_srvs
|
std_srvs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_service_ping -rdynamic)
|
||||||
add_executable(test_service_pong
|
add_executable(test_service_pong
|
||||||
src/test_service_pong.cpp
|
src/test_service_pong.cpp
|
||||||
)
|
)
|
||||||
ament_target_dependencies(test_service_pong
|
ament_target_dependencies(test_service_pong
|
||||||
rclcpp
|
rclcpp
|
||||||
std_srvs
|
std_srvs
|
||||||
|
tracetools
|
||||||
)
|
)
|
||||||
|
target_link_libraries(test_service_pong -rdynamic)
|
||||||
|
|
||||||
install(TARGETS
|
install(TARGETS
|
||||||
test_intra
|
test_intra
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue