Skip to content
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

Make get_rcl_allocator a function family (not a template) #1324

Open
wants to merge 9 commits into
base: rolling
Choose a base branch
from

Conversation

stevewolter
Copy link

@stevewolter stevewolter commented Sep 22, 2020

As explained in #1254, there's conceptually no way to implement RCL
allocators in terms of C++ allocators. In order to fix this behavior, we
have to delete the generic version of get_rcl_allocator. Since some ROS
code depends on this, we need to allow users to write their own version
of get_rcl_allocator for allocators that support the C-style interface (most
do).

So this CL changes get_rcl_allocator from a template function into a
family of (potentially templated) functions, which allows users to add their
own overloads and rely on the "most specialized" mechanism for function
specialization to select the right one. See http://www.gotw.ca/publications/mill17.htm
for details. This also allows us to return get_rcl_default_allocator for all
specializations of std::allocator (previously, only for std::allocator),
which will already fix #1254 for pretty much all clients. I'll continue to work
on deleting the generic version, though, to make sure that nobody is accidentally
bitten by it.

I've tried to test this by doing a full ROS compilation following the
Dockerfile of the source Docker image, and all packages compile.

@stevewolter stevewolter changed the title Remove generation of RCL allocators from C++. Make get_rcl_allocator a function family (not a template) Sep 23, 2020
@stevewolter
Copy link
Author

Sorry for the noise. This is ready for review now.

Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got a few minor things to cleanup; otherwise looks pretty good to me. Pinging @wjwwood for any additional thoughts.

rclcpp/include/rclcpp/allocator/allocator_common.hpp Outdated Show resolved Hide resolved
rclcpp/include/rclcpp/publisher_options.hpp Outdated Show resolved Hide resolved
Copy link
Member

@wjwwood wjwwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes lgtm, with one comment. I think this approach makes sense.

rclcpp/include/rclcpp/allocator/allocator_common.hpp Outdated Show resolved Hide resolved
stevewolter and others added 9 commits October 2, 2020 07:54
As explained in ros2#1254, there's conceptually no way to implement RCL
allocators in terms of C++ allocators. In order to fix this behavior,
we have to delete the generic version of get_rcl_allocator. Since some
ROS code depends on this, we need to allow users to write their own
version of get_rcl_allocator for allocators that support the C-style
interface (most do).

So this CL changes get_rcl_allocator from a template function
into a family of (potentially templated) functions, which allows
users to add their own overloads and rely on the "most specialized"
mechanism for function specialization to select the right one. See
http://www.gotw.ca/publications/mill17.htm for details. This also
allows us to return get_rcl_default_allocator for all specializations
of std::allocator (previously, only for std::allocator), which will
already fix ros2#1254 for pretty much all clients. I'll continue to work
on deleting the generic version, though, to make sure that nobody is
accidentally bitten by it.

I've tried to test this by doing a full ROS compilation following the
Dockerfile of the source Docker image, and all packages compile.

Signed-off-by: Steve Wolter <swolter@google.com>
Signed-off-by: Steve Wolter <swolter@google.com>
Incidentally, this also reruns the flaky test suite, which
seems to be using the real DDS middleware and to be prone
to cross-talk.

Signed-off-by: Steve Wolter <swolter@google.com>
Signed-off-by: Steve Wolter <swolter@google.com>
Signed-off-by: Steve Wolter <swolter@google.com>
Signed-off-by: Steve Wolter <swolter@google.com>
This allows us to simplify a bunch of code as well.

Signed-off-by: Steve Wolter <swolter@google.com>
Co-authored-by: William Woodall <william+github@osrfoundation.org>
Signed-off-by: Steve Wolter <swolter@google.com>
Signed-off-by: Steve Wolter <swolter@google.com>
@wjwwood
Copy link
Member

wjwwood commented Oct 26, 2020

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@stevewolter
Copy link
Author

Thanks, and sorry for the delay. This will only build together with its companion changes ros2/demos#467 and ros2/realtime_support#103. Do you want to take a look at them as well, and I'll submit all three simultaneously?

@wjwwood
Copy link
Member

wjwwood commented Oct 26, 2020

Yeah we have to do them all at once.

* your own overload for this function.
*/
template<typename T>
rcl_allocator_t get_rcl_allocator(std::allocator<T> allocator)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be in the rclcpp::allocator namespace, so that it matches the folder structure include/rclcpp/allocator/....

@fujitatomoya
Copy link
Collaborator

@stevewolter can you rebase this? this should fix #1925.

@stevewolter
Copy link
Author

@fujitatomoya We've downprioritized our ROS efforts, so it will be while until I find time, sorry. Please feel free to clone the change & submit it under your name if you need it.

@wjwwood
Copy link
Member

wjwwood commented May 23, 2022

@fujitatomoya @stevewolter I think I can spend some time to revive this since it came up in one of my projects recently.

@AlexisTM
Copy link
Contributor

I just tested this change locally with ASAN and it fixes #1948 and #1925

The error fixed is:

==12240==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x625000002900 in thread T0:
  object passed to delete has wrong type:
  size of the allocated type:   8064 bytes;
  size of the deallocated type: 112 bytes.

@audrow audrow changed the base branch from master to rolling June 28, 2022 14:21
@tylerjw
Copy link
Contributor

tylerjw commented Oct 25, 2022

I'd again like to use ASAN in CI for libraries I use that depend on rclcpp. Is there anything I can do to help finish this?

As far as I can tell, this works, and I have tested it locally, but it seems there is some confusion around the namespace this should be in. Could I get some help understanding what changes are blocking this so maybe I could try to update it?

@clalancette
Copy link
Contributor

I'd again like to use ASAN in CI for libraries I use that depend on rclcpp. Is there anything I can do to help finish this?

Yes! If you had time to do it, it would be wonderful to rebase this onto the latest and get it compiling and working (it probably needs a few fixes before that happens).

As far as the namespace fixes, really we just need to move get_rcl_allocator back into the rclcpp::allocator namespace; that should be enough.

One other thing to note is that both ros2/realtime_support#103 and ros2/demos#467 may need to be updated along with this to make CI pass.

Thanks for taking a look, it is much appreciated!

/// Return the equivalent rcl_allocator_t for the C++ standard allocator.
/**
* This assumes that the user intent behind both allocators is the
* same: Using system malloc for allocation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK this is not exactly true: std::allocator is implemented in terms of new/delete. Although new/delete are often implemented in terms of malloc/free, it is not demanded by the C++ Standard (AFAIK, might be wrong), meaning that implementations are free to implement new/delete independently from malloc/free.

@tylerjw
Copy link
Contributor

tylerjw commented Jan 11, 2023

@clalancette I pushed my attempt at fixing this PR up here: #2046

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

allocator_common.hpp overallocates 100x memory & invokes UB on dealloc
7 participants