From 559c88b36d0647e9f6372a73de0c64b56408f42e Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Wed, 9 Nov 2016 00:23:38 +0100 Subject: [PATCH] Adds runtime alignment assertions, see #3267 --- include/storage/shared_datatype.hpp | 1 + include/util/static_rtree.hpp | 4 +++- src/contractor/contractor.cpp | 20 +++++++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/storage/shared_datatype.hpp b/include/storage/shared_datatype.hpp index f38799fda..e48ad3041 100644 --- a/include/storage/shared_datatype.hpp +++ b/include/storage/shared_datatype.hpp @@ -106,6 +106,7 @@ struct DataLayout template inline void SetBlockSize(BlockID bid, uint64_t entries) { + static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer"); num_entries[bid] = entries; entry_size[bid] = sizeof(T); entry_align[bid] = alignof(T); diff --git a/include/util/static_rtree.hpp b/include/util/static_rtree.hpp index f979cd515..44f2c0bc1 100644 --- a/include/util/static_rtree.hpp +++ b/include/util/static_rtree.hpp @@ -373,7 +373,9 @@ class StaticRTree { m_leaves_region.open(leaf_file); std::size_t num_leaves = m_leaves_region.size() / sizeof(LeafNode); - m_leaves.reset(reinterpret_cast(m_leaves_region.data()), num_leaves); + auto data_ptr = m_leaves_region.data(); + BOOST_ASSERT(reinterpret_cast(data_ptr) % alignof(LeafNode) == 0); + m_leaves.reset(reinterpret_cast(data_ptr), num_leaves); } catch (const std::exception &exc) { diff --git a/src/contractor/contractor.cpp b/src/contractor/contractor.cpp index 9a7f38cc5..9fdced202 100644 --- a/src/contractor/contractor.cpp +++ b/src/contractor/contractor.cpp @@ -69,6 +69,15 @@ template <> struct hash> }; } +namespace +{ +template inline bool is_aligned(const void *pointer) +{ + static_assert(sizeof(T) % alignof(T) == 0, "pointer can not be used as an array pointer"); + return reinterpret_cast(pointer) % alignof(T) == 0; +} +} + namespace osrm { namespace contractor @@ -571,6 +580,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph( }; #pragma pack(pop, r1) + BOOST_ASSERT(is_aligned(edge_based_graph_region.get_address())); const EdgeBasedGraphHeader graph_header = *(reinterpret_cast(edge_based_graph_region.get_address())); @@ -669,6 +679,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph( auto region = mmap_file(rtree_leaf_filename.c_str()); region.advise(mapped_region::advice_willneed); + BOOST_ASSERT(is_aligned(region.get_address())); const auto bytes = region.get_size(); const auto first = static_cast(region.get_address()); @@ -850,16 +861,20 @@ EdgeID Contractor::LoadEdgeExpandedGraph( auto penaltyblock = reinterpret_cast( edge_penalty_region.get_address()); - auto edge_segment_byte_ptr = reinterpret_cast(edge_segment_region.get_address()); + BOOST_ASSERT(is_aligned(penaltyblock)); + auto edge_based_edge_ptr = reinterpret_cast( reinterpret_cast(edge_based_graph_region.get_address()) + sizeof(EdgeBasedGraphHeader)); + BOOST_ASSERT(is_aligned(edge_based_edge_ptr)); const auto edge_based_edge_last = reinterpret_cast( reinterpret_cast(edge_based_graph_region.get_address()) + sizeof(EdgeBasedGraphHeader) + sizeof(extractor::EdgeBasedEdge) * graph_header.number_of_edges); + auto edge_segment_byte_ptr = reinterpret_cast(edge_segment_region.get_address()); + while (edge_based_edge_ptr != edge_based_edge_last) { // Make a copy of the data from the memory map @@ -869,8 +884,10 @@ EdgeID Contractor::LoadEdgeExpandedGraph( if (update_edge_weights || update_turn_penalties) { bool skip_this_edge = false; + auto header = reinterpret_cast( edge_segment_byte_ptr); + BOOST_ASSERT(is_aligned(header)); edge_segment_byte_ptr += sizeof(extractor::lookup::SegmentHeaderBlock); auto previous_osm_node_id = header->previous_osm_node_id; @@ -879,6 +896,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph( auto segmentblocks = reinterpret_cast(edge_segment_byte_ptr); + BOOST_ASSERT(is_aligned(segmentblocks)); edge_segment_byte_ptr += sizeof(extractor::lookup::SegmentBlock) * (header->num_osm_nodes - 1);