-
Notifications
You must be signed in to change notification settings - Fork 229
Fix writes/reads outside allocated memory in resource constraints shortest paths #93
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
Conversation
|
Hi Mateusz. This sounds like a pretty serious bug and an important fix. I'm not an expert on this algorithm, but I've looked pretty closely through the code and it all looks good. |
| res_cont_2.marked.end() ); | ||
| } | ||
| }; | ||
|
|
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 think some brief comments on these new classes would help the reviewers understand what they do.
| // r_c_shortest_paths_label struct | ||
| template<class Graph, class Resource_Container> | ||
| struct r_c_shortest_paths_label | ||
| struct r_c_shortest_paths_label : public boost::enable_shared_from_this<r_c_shortest_paths_label<Graph, Resource_Container> > |
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've never used enable_shared_from_this; what does it do?
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.
enable_shared_from_this is a C++11 construct. See the link, it is better explained than I could.
|
Hi @jeremy-murphy, I answered to your questions below.
|
|
You're right, and I didn't mean to cast any doubt about performance, it's just a standard question. I assume you would have noticed if it was 10x slower, which is the kind of accidental performance bug I mean. |
|
@jeremy-murphy, it seems there is a ticket https://svn.boost.org/trac10/ticket/11723 with a similar issue. I asked the owner for a suggestion about next steps. |
|
I'm helping out with the PR backlog. Looks like you have a bugfix, test, and no new examples will be needed. This will be in the first batch of merged PR's. I will need to take time to understand this issue and fix more. This is to let you know and help me prioritize PR's. |
|
I'm having trouble building graph / develop following all these PR's. Do you, by chance, test each PR by building and running graph, graph parallel, and MPI tests before pushing it? It might be wise to slow down so we don't irreversibly break something. |
|
Right now I'm letting people know that something is happening, adding some documentation, and prioritizing PR's to mess with. Some of these old PR's need to be rebased so I'm stirring things up a little bit to get the submitters to check in and to know things are happening. I'll be reading, testing, merging, and testing again PR's I say will be in the first batch of merges |
| ( const unsigned long n, | ||
| const Resource_Container& rc = Resource_Container(), | ||
| const r_c_shortest_paths_label* const pl = 0, | ||
| const boost::shared_ptr<r_c_shortest_paths_label<Graph, Resource_Container> > pl = nullptr, |
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.
nullptr is C++11, the C++03 tests will fail.
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.
This was fixed in #114.
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.
It's better to fix it here, if possible. It's easier to review and merge PRs one by one (and it would be easier to revert them later if some prove problematic.)
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.
You can. I'm new and don't have write access so having one place to work on keeps things a tad more sane. It fixing commit was 6808062 .
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.
No, I can't fix people's PRs, they have to do that themselves. :-)
I'm trying to save you trouble in the long run. Batching up unrelated changes in one PR is not good workflow. It's better to either request the needed PR changes from the original submitters, who are usually happy to help, or, if you want to fix their PRs yourself, you could create one new PR per each original PR, so that the changes can be reviewed and applied in isolation.
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.
test/r_c_shortest_paths_test.cpp
Outdated
| if( this == &other ) | ||
| return *this; | ||
| this->~spp_spptw_marked_res_cont(); | ||
| new( this ) spp_spptw_marked_res_cont( other ); |
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.
Invoking the destructor and then the constructor is not a good way to write an assignment operator. Perhaps it works here, I haven't checked, but it's not a good practice and it would be better to rewrite it in a more conventional way.
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.
@pdimov, I agree. I implemented proper assignment operators in tests whenever possible. Only one has left in https://github.com/boostorg/graph/blob/develop/include/boost/graph/r_c_shortest_paths.hpp#L47. See this is part of released Boost. It was done by the original developer of the feature to allow reassignment of fields marked as const in the struct definition.
I was not changing it deliberately, because it has been already released and it is not causing any bugs as far as I am concerned. It is quite unusual construct to use without a reason.
|
Try rebasing on the current develop branch. I think some of your changes were already added so it won't be trivial to merge. |
…rind confirms reads/writes outside allocated memory.
…- explain a scenario where they do not work correctly.
…t shared pointer constructor
|
Recent TravisCI failure in a single build is a timeout in the mas_test.cpp test, which is unrelated to changes in this thread. |
|
I restarted the timed-out job and it passed, so it's all clear now. |
|
Are these changes in #114? If so it can be closed now. |
|
These changes were included in #114 and so this should be closed. |
Found an example where existing algorithm performs writes/reads outside allocated memory when using the default allocator. Implemented repo as a test included in the pull request. Valgrind reports 38 reads/writes outside allocated memory when running the test against the original version of the algorithm.
I did not get a segmentation fault on my machine, but the algorithm returned a list of edges that do not form a path (example: 1-5 5-2 2-3 4-0).
Investigation
If an existing label is found dominated it becomes immediately deallocated. However, pointers to that label still may exist in other partial paths. Further new allocations cause appearance of invalid paths. The assumption that a pareto optimal path consists only of non-dominated labels and therefore deallocating them is not correct (safe) if the dominance function performs weak inequality checks (as suggested by original author and presented in examples).
Fix
r_c_shortest_paths_labelwithboost::shared_ptr. The algorihtm finds shortest paths based on feasibility/dominance criteria specified by user, so there is a risk that pointers may form a cycle. Taking this into account the algorihtm resets pointers as the final step. I considered using weak pointers in ther_c_shortest_paths_label, but there are examples where such approach do not work. Provided it as a comment inside the algorithm code.ks_smart_pointerbyboost::shared_ptr. The former class did not offer the smart_pointer functionality and is not necessary.b_is_validchecks. It is possible to come up with examples, where this approach will report false negatives (provided an example in comments). It is the same reason why weak_pointers will not work.Valgrind does not detect any leaks or possible leaks when running the test against the fixed algorithm.