-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Fix a stack-use-after-scope in Arr_polycurve_basic_traits_2 #4012
Fix a stack-use-after-scope in Arr_polycurve_basic_traits_2 #4012
Conversation
Before this patch, `Arr_polycurve_basic_traits_2` was holding a const reference to a temporary object. Here was the result of ctest, with the address sanitizer: ```shellsession $ make && ASAN_OPTIONS=detect_leaks=0 ctest -L Arr -j6 [...] The following tests FAILED: 144 - execution___of__generic_curve_data (Failed) 170 - execution___of__polycurve_circular_arc (Failed) 172 - execution___of__polycurve_conic (Failed) 176 - execution___of__polycurves_basic (Failed) 178 - execution___of__polylines (Failed) 2166 - test_traits_test_polylines__data_polylines_compare_y_at_x__polyline_traits (Failed) 2168 - test_traits_test_polylines__data_polylines_intersect__polyline_traits (Failed) 2169 - test_traits_test_polylines__data_polylines_split__polyline_traits (Failed) 2171 - test_traits_test_polylines__data_polylines_assertions__polyline_traits (Failed) 2175 - test_traits_conic_polycurve__data_polycurves_conics_compare_y_at_x__polycurve_conic_traits (Failed) 2176 - test_traits_conic_polycurve__data_polycurves_conics_compare_y_at_x_left__polycurve_conic_traits (Failed) 2177 - test_traits_conic_polycurve__data_polycurves_conics_compare_y_at_x_right__polycurve_conic_traits (Failed) 2179 - test_traits_conic_polycurve__data_polycurves_conics_intersect__polycurve_conic_traits (Failed) 2180 - test_traits_conic_polycurve__data_polycurves_conics_split__polycurve_conic_traits (Failed) 2193 - test_traits_circular_arc_polycurve__data_Polycurves_circular_arcs_compare_y_at_x__polycurve_circular_arc_traits (Failed) 2198 - test_traits_circular_arc_polycurve__data_Polycurves_circular_arcs_split__polycurve_circular_arc_traits (Failed) 2221 - test_traits_non_caching_polylines__data_polylines_compare_y_at_x__non_caching_polyline_traits (Failed) 2223 - test_traits_non_caching_polylines__data_polylines_intersect__non_caching_polyline_traits (Failed) 2224 - test_traits_non_caching_polylines__data_polylines_split__non_caching_polyline_traits (Failed) 2226 - test_traits_non_caching_polylines__data_polylines_assertions__non_caching_polyline_traits (Failed) 2400 - execution___of__test_construction_polylines (Failed) 2477 - execution___of__test_io (Failed) ``` This is fixed rather easily, by copying the traits class, instead of holding a reference to it.
Note that I have used AddressSanitizer with the option |
Those errors are because of my other PR #4013. But let's block both PRs, until I can find a solution. |
Hi Laurent,
I think that I've managed to skip your request from 2 weeks ago, but at
least I see it now.
The fix is somehow incorrect.
Some of our traits have state data; thus, we do not copy traits (only pass
references).
Frankly, I don't understand why does the tool you used reports an error,
but perhaps you can try skipping the definition and usage of the local
variable 'geom_traits'.
In particular:
Instead of:
const Subcurve_traits_2* geom_traits = subcurve_traits_2();
Compare_points<Compare_x_2> compare(geom_traits, compare_x_2_object(), q);
Do:
Compare_points<Compare_x_2> compare(subcurve_traits_2(),
compare_x_2_object(), q);
I was trying your command:
make && ASAN_OPTIONS=detect_leaks=0 ctest -L Arr -j6
but did not get errors. How do I reproduce?
Efi
____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
…On Mon, 1 Jul 2019 at 10:28, Laurent Rineau ***@***.***> wrote:
Those errors are because of my other PR #4013
<#4013>. But let's block both PRs, until
I can find a solution.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#4012?email_source=notifications&email_token=ABVBNODLRZ2ALWG5AHPUQJDP5GW2TA5CNFSM4HY6D3GKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODY5HXVY#issuecomment-507149271>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABVBNOD3KZPOVSR3MDB7KB3P5GW2TANCNFSM4HY6D3GA>
.
|
@efifogel commented on Jul 1, 2019, 2:04 PM GMT+2:
I understand that traits can have state data, but I thought they are probably constant state data, that can be copied.
I do not understand the suggestion. The reason AddressSanitizer reported an error is that the
You have to enable first the AddressSanitizer. It can be used with any non-ancient versions of gcc and clang, by adding |
On Mon, 1 Jul 2019 at 15:12, Laurent Rineau ***@***.***> wrote:
***@***.**** <https://github.com/efifogel> commented on Jul 1, 2019, 2:04
PM GMT+2 <#4012 (comment)>:
Hi Laurent,
I think that I've managed to skip your request from 2 weeks ago, but at
least I see it now.
The fix is somehow incorrect.
Some of our traits have state data; thus, we do not copy traits (only pass
references).
I understand that traits can have state data, but I thought they are
probably constant state data, that can be copied.
You might be right, but I would like to avoid it anyway.
Frankly, I don't understand why does the tool you used reports an error,
but perhaps you can try skipping the definition and usage of the local
variable 'geom_traits'.
In particular:
Instead of:
const Subcurve_traits_2* geom_traits = subcurve_traits_2();
Compare_points<Compare_x_2> compare(geom_traits, compare_x_2_object(), q);
Do:
Compare_points<Compare_x_2> compare(subcurve_traits_2(),
compare_x_2_object(), q);
I do not understand the suggestion. The reason AddressSanitizer reported
an error is that the compare object was holding a reference to a
temporary object already destroyed.
The reference is to a pointer, which is definitely not destroyed. This is
why I think that my suggestion may work. (I might be completely off...)
I was trying your command:
make && ASAN_OPTIONS=detect_leaks=0 ctest -L Arr -j6
but did not get errors. How do I reproduce?
You have to enable first the AddressSanitizer
<https://github.com/google/sanitizers/wiki/AddressSanitizer>. It can be
used with any non-ancient versions of gcc and clang, by adding
-fsanitize=adress to the compilation flags.
I wasn't able to reproduce.
My gcc version is 5.4.0.
When I build CGAL I use:
cmake \
-DBUILD_DOC:BOOL=ON \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS=-frounding-math -Wall -fsanitize=adress \
-DWITH_GMP=true \
-DWITH_CGAL_Qt5=ON \
-DBUILD_TESTING=ON -DWITH_examples=ON -DWITH_tests=ON \
${HOME}/trees/cgal/cgal_master
and then your command. What am I missing?
—
… You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#4012?email_source=notifications&email_token=ABVBNOFQQUBAPC3NG5N6FPLP5HYBPA5CNFSM4HY6D3GKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODY55SSQ#issuecomment-507238730>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABVBNOGVE7FPYRXPRGDWGILP5HYBPANCNFSM4HY6D3GA>
.
|
|
On a run of:
then the full error from AddressSanitizer is:
As the report says, the temporary object on the stack is created here in cgal/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h Lines 2696 to 2715 in 12da8d1
The problem is that the type of the pointer CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > const* and it is passed as first argument to the constructor of cgal/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h Lines 2545 to 2550 in 12da8d1
and the first parameter is a CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > > So, how does that work?! The argument is a pointer, and the parameter is an cgal/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h Lines 102 to 103 in 12da8d1
So, on the fly, a temporary My patch makes the
so at most that is two words to copy (16 octets in case of a 64 bits architecture). |
I'd like to fix it in a different way.
I'm trying to avoid copying traits (even if it is harmless).
What do I need to do in order to reproduce?
I did try, but failed.
…____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
On Tue, 2 Jul 2019 at 15:02, Laurent Rineau ***@***.***> wrote:
On a run of:
test_traits_test_polylines "data/polylines/compare_y_at_x.pt" "data/polylines/compare_y_at_x.xcv" "data/empty.zero" "data/polylines/compare_y_at_x" "polyline_traits"
then the full error from AddressSanitizer is:
Performing test: traits type is polyline_traits, input files are data/polylines/compare_y_at_x.pt data/polylines/compare_y_at_x.xcv data/empty.zero data/polylines/compare_y_at_x
case number : 1
Test: compare_y_at_x( 0/1 0/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
case number : 2
Test: compare_y_at_x( 0/1 1/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
case number : 3
Test: compare_y_at_x( 0/1 2/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
case number : 4
Test: compare_y_at_x( 0/1 3/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
case number : 5
Test: compare_y_at_x( 0/1 4/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
case number : 6
Test: compare_y_at_x( 0/1 5/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
case number : 7
Test: compare_y_at_x( 0/1 6/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
case number : 8
Test: compare_y_at_x( 0/1 -1/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 4294967295 Passed
case number : 9
Test: compare_y_at_x( 0/1 7/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 1 Passed
case number : 10
Test: compare_y_at_x( 0/1 -1/1,2 0/1 0/1 2/1 2/1 4/1 4/1 ) ? 4294967295
=================================================================
==20046==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fffffffbcc0 at pc 0x00000055ee41 bp 0x7fffffffb7f0 sp 0x7fffffffb7e8
READ of size 8 at 0x7fffffffbcc0 thread T0
#0 0x55ee40 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::subcurve_traits_2() const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:128:12
#1 0x5721eb in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_points<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_x_2>::operator()(CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> > const&, CGAL::Arr_curve_end) /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2559:60
#2 0x571892 in unsigned long CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate_gen<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_points<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_x_2> >(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_points<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_x_2>) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2485:34
#3 0x5705a3 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2723:12
#4 0x56f878 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate_impl(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&, CGAL::Arr_all_sides_oblivious_tag) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2696:12
#5 0x56f3f0 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_y_at_x_2::operator()(CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&, CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:749:25
#6 0x54c18d in Traits_test<CGAL::Arr_polyline_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > > >::compare_y_at_x_wrapper(std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >&) /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Traits_test.h:815:5
#7 0x552e6e in Traits_test<CGAL::Arr_polyline_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > > >::exec(std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&) /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Traits_test.h:63:14
#8 0x544290 in Traits_base_test<CGAL::Arr_polyline_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > > >::perform() /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Traits_base_test.h:306:21
#9 0x53ffd2 in main /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits.cpp:116:13
#10 0x7ffff77a9f32 in __libc_start_main /usr/src/debug/glibc-2.29-24-g2ec0b166bf/csu/../csu/libc-start.c:308:16
#11 0x42315d in _start (/home/lrineau/Git/other-cgal2/build-address-sanitizer/test/Arrangement_on_surface_2/test_traits_test_polylines+0x42315d)
Address 0x7fffffffbcc0 is located in stack of thread T0 at offset 384 in frame
#0 0x56fd2f in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2700
This frame has 12 object(s):
[32, 40) 'geom_traits' (line 2701)
[64, 65) 'ref.tmp' (line 2702)
[80, 81) 'min_vertex' (line 2704)
[96, 104) 'compare_x' (line 2706)
[128, 152) 'compare' (line 2714)
[192, 208) 'ref.tmp17' (line 2714)
[224, 232) 'agg.tmp'
[256, 280) 'agg.tmp22'
[320, 344) 'compare34' (line 2722)
[384, 400) 'ref.tmp35' (line 2722) <== Memory access at offset 384 is inside this variable
[416, 424) 'agg.tmp36'
[448, 472) 'agg.tmp43'
As the report says, the temporary object on the stack is created here in
CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<K>>::locate:
https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L2696-L2715
The problem is that the type of the pointer geom_traits is:
CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > const*
and it is passed as first argument to the constructor of compare,
https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L2545-L2550
and the first parameter is a const& to a type:
CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >
So, how does that work?! The argument is a pointer, and the parameter is
an const& to an object! The reason is that
CGAL::Arr_polycurve_basic_traits_2 has an implicit constructor with one
argument:
https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L102-L103
So, on the fly, a temporary CGAL::Arr_polycurve_basic_traits_2 is
created, bound to a const reference, and then automatically destroyed just
after that! Once we unfold all that, I am surprise that the compiler does
not warn about that issue.
My patch makes the CGAL::Arr_polycurve_basic_traits_2 be copied instead
of hold as a const reference. And I think that is fine, because that class
CGAL::Arr_polycurve_basic_traits_2 only contains a pointer and a bool:
https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L84-L86
so at most that is two words to copy (16 octets in case of a 64 bits
architecture).
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#4012?email_source=notifications&email_token=ABVBNOH2ONAQ77R7FUIF4GTP5M7VTA5CNFSM4HY6D3GKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZBBE2A#issuecomment-507646568>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABVBNOB2PKP5DZE2RJ56NPTP5M7VTANCNFSM4HY6D3GA>
.
|
I've tried
cmake -DCMAKE_CXX_FLAGS="-frounding-math -Wall -g -fsanitize=address
-fno-omit-frame-pointer"
and
cmake -DCMAKE_BUILD_TYPE=ASAN
but, nothing
I'm using g++ 5.4.0.
Do I have to use clang?
…____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
On Tue, 2 Jul 2019 at 21:31, Efi Fogel ***@***.***> wrote:
I'd like to fix it in a different way.
I'm trying to avoid copying traits (even if it is harmless).
What do I need to do in order to reproduce?
I did try, but failed.
____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
On Tue, 2 Jul 2019 at 15:02, Laurent Rineau ***@***.***>
wrote:
> On a run of:
>
> test_traits_test_polylines "data/polylines/compare_y_at_x.pt" "data/polylines/compare_y_at_x.xcv" "data/empty.zero" "data/polylines/compare_y_at_x" "polyline_traits"
>
>
> then the full error from AddressSanitizer is:
>
> Performing test: traits type is polyline_traits, input files are data/polylines/compare_y_at_x.pt data/polylines/compare_y_at_x.xcv data/empty.zero data/polylines/compare_y_at_x
>
>
>
> case number : 1
>
> Test: compare_y_at_x( 0/1 0/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
>
> case number : 2
>
> Test: compare_y_at_x( 0/1 1/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
>
> case number : 3
>
> Test: compare_y_at_x( 0/1 2/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
>
> case number : 4
>
> Test: compare_y_at_x( 0/1 3/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
>
> case number : 5
>
> Test: compare_y_at_x( 0/1 4/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
>
> case number : 6
>
> Test: compare_y_at_x( 0/1 5/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
>
> case number : 7
>
> Test: compare_y_at_x( 0/1 6/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 0 Passed
>
> case number : 8
>
> Test: compare_y_at_x( 0/1 -1/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 4294967295 Passed
>
> case number : 9
>
> Test: compare_y_at_x( 0/1 7/1,3 0/1 0/1 0/1 2/1 0/1 4/1 0/1 6/1 ) ? 1 Passed
>
> case number : 10
>
> Test: compare_y_at_x( 0/1 -1/1,2 0/1 0/1 2/1 2/1 4/1 4/1 ) ? 4294967295
>
> =================================================================
>
> ==20046==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fffffffbcc0 at pc 0x00000055ee41 bp 0x7fffffffb7f0 sp 0x7fffffffb7e8
>
> READ of size 8 at 0x7fffffffbcc0 thread T0
>
> #0 0x55ee40 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::subcurve_traits_2() const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:128:12
>
> #1 0x5721eb in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_points<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_x_2>::operator()(CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> > const&, CGAL::Arr_curve_end) /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2559:60
>
> #2 0x571892 in unsigned long CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate_gen<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_points<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_x_2> >(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_points<CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_x_2>) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2485:34
>
> #3 0x5705a3 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2723:12
>
> #4 0x56f878 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate_impl(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&, CGAL::Arr_all_sides_oblivious_tag) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2696:12
>
> #5 0x56f3f0 in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::Compare_y_at_x_2::operator()(CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&, CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:749:25
>
> #6 0x54c18d in Traits_test<CGAL::Arr_polyline_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > > >::compare_y_at_x_wrapper(std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >&) /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Traits_test.h:815:5
>
> #7 0x552e6e in Traits_test<CGAL::Arr_polyline_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > > >::exec(std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&) /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Traits_test.h:63:14
>
> #8 0x544290 in Traits_base_test<CGAL::Arr_polyline_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > > >::perform() /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Traits_base_test.h:306:21
>
> #9 0x53ffd2 in main /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits.cpp:116:13
>
> #10 0x7ffff77a9f32 in __libc_start_main /usr/src/debug/glibc-2.29-24-g2ec0b166bf/csu/../csu/libc-start.c:308:16
>
> #11 0x42315d in _start (/home/lrineau/Git/other-cgal2/build-address-sanitizer/test/Arrangement_on_surface_2/test_traits_test_polylines+0x42315d)
>
>
>
> Address 0x7fffffffbcc0 is located in stack of thread T0 at offset 384 in frame
>
> #0 0x56fd2f in CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >::locate(CGAL::internal::X_monotone_polycurve_2<CGAL::Arr_segment_2<CGAL::Cartesian<CGAL::Gmpq> >, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > > const&, CGAL::Point_2<CGAL::Cartesian<CGAL::Gmpq> > const&) const /home/lrineau/Git/other-cgal2/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h:2700
>
>
>
> This frame has 12 object(s):
>
> [32, 40) 'geom_traits' (line 2701)
>
> [64, 65) 'ref.tmp' (line 2702)
>
> [80, 81) 'min_vertex' (line 2704)
>
> [96, 104) 'compare_x' (line 2706)
>
> [128, 152) 'compare' (line 2714)
>
> [192, 208) 'ref.tmp17' (line 2714)
>
> [224, 232) 'agg.tmp'
>
> [256, 280) 'agg.tmp22'
>
> [320, 344) 'compare34' (line 2722)
>
> [384, 400) 'ref.tmp35' (line 2722) <== Memory access at offset 384 is inside this variable
>
> [416, 424) 'agg.tmp36'
>
> [448, 472) 'agg.tmp43'
>
>
> As the report says, the temporary object on the stack is created here in
> CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<K>>::locate
> :
>
> https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L2696-L2715
>
> The problem is that the type of the pointer geom_traits is:
>
> CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > const*
>
> and it is passed as first argument to the constructor of compare,
>
> https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L2545-L2550
>
> and the first parameter is a const& to a type:
>
> CGAL::Arr_polycurve_basic_traits_2<CGAL::Arr_segment_traits_2<CGAL::Cartesian<CGAL::Gmpq> > >
>
> So, how does that work?! The argument is a pointer, and the parameter is
> an const& to an object! The reason is that
> CGAL::Arr_polycurve_basic_traits_2 has an implicit constructor with one
> argument:
>
> https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L102-L103
>
> So, on the fly, a temporary CGAL::Arr_polycurve_basic_traits_2 is
> created, bound to a const reference, and then automatically destroyed just
> after that! Once we unfold all that, I am surprise that the compiler does
> not warn about that issue.
>
> My patch makes the CGAL::Arr_polycurve_basic_traits_2 be copied instead
> of hold as a const reference. And I think that is fine, because that class
> CGAL::Arr_polycurve_basic_traits_2 only contains a pointer and a bool:
>
> https://github.com/CGAL/cgal/blob/12da8d1344c2de2f1b85e0cb4e62d3d02f88eafb/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_basic_traits_2.h#L84-L86
>
> so at most that is two words to copy (16 octets in case of a 64 bits
> architecture).
>
> —
> You are receiving this because your review was requested.
> Reply to this email directly, view it on GitHub
> <#4012?email_source=notifications&email_token=ABVBNOH2ONAQ77R7FUIF4GTP5M7VTA5CNFSM4HY6D3GKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZBBE2A#issuecomment-507646568>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABVBNOB2PKP5DZE2RJ56NPTP5M7VTANCNFSM4HY6D3GA>
> .
>
|
@efifogel commented on Jul 2, 2019, 9:16 PM GMT+2:
AddressSanitizer is part of gcc since version 4.8 and part of LLVM/clang since version 3.1. Your version 5.4 of gcc should be sufficient. But maybe its copy of AddressSanitizer is too old to detect the issue. If you have a more recent version of gcc, or clang, try it. To enable it, you just have to add cmake -DCMAKE_CXX_FLAGS="-frounding-math -Wall -g -fsanitize=address -fno-omit-frame-pointer" However |
I cannot seem to enable the test on my machine with the versions I have.
The fix that I proposed in my previous message, thought, is necessary, and
perhaps it also fixes the problem.
Please try it, and let me know whether further actions are necessary.
(I mean, if the issue remains, I'll try to upgrade the tools and reproduce.)
____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
…On Wed, 3 Jul 2019 at 10:06, Laurent Rineau ***@***.***> wrote:
***@***.**** <https://github.com/efifogel> commented on Jul 2, 2019, 9:16
PM GMT+2 <#4012 (comment)>:
I've tried
cmake -DCMAKE_CXX_FLAGS="-frounding-math -Wall -g -fsanitize=address
-fno-omit-frame-pointer"
and
cmake -DCMAKE_BUILD_TYPE=ASAN
but, nothing
I'm using g++ 5.4.0.
Do I have to use clang?
AddressSanitizer is part of gcc since version 4.8 and part of LLVM/clang
since version 3.1
<https://github.com/google/sanitizers/wiki/AddressSanitizer#getting-addresssanitizer>.
Your version 5.4 of gcc should be sufficient. But maybe its copy of
AddressSanitizer is too old to detect the issue. If you have a more recent
version of gcc, or clang, try it.
To enable it, you just have to add -fsanitize=address to CMAKE_CXX_FLAGS,
as you did:
cmake -DCMAKE_CXX_FLAGS="-frounding-math -Wall -g -fsanitize=address -fno-omit-frame-pointer"
However ASAN is not a valid value for CMAKE_BUILD_TYPE. You can leave it
empty, or set it to Release or Debug.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#4012?email_source=notifications&email_token=ABVBNOHVX3RAUQFBFEP6UKTP5RFWJA5CNFSM4HY6D3GKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZDPZZY#issuecomment-507968743>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABVBNOHUKRIGEJN3RXNI4QDP5RFWJANCNFSM4HY6D3GA>
.
|
I have verified that your patch does not fix the issue. The temporary object of type |
ok, then let me handle it in a separate branch (including the patch I
provided).
____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
…On Tue, 9 Jul 2019 at 11:38, Laurent Rineau ***@***.***> wrote:
I have verified that your patch does not fix the issue. The temporary
object of type Arr_polycurve_basic_traits_2 is still created, and the
reference bound to it.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#4012?email_source=notifications&email_token=ABVBNOAEW7QHUMMYYZBEECTP6RFBNA5CNFSM4HY6D3GKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZPRP4Y#issuecomment-509548531>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABVBNOCO6ZXIWTXMPKU54RDP6RFBNANCNFSM4HY6D3GA>
.
|
I'm leaving for a vacation in a couple of days for 10 days, so I may do
finish it after I'm back.
____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
…On Tue, 9 Jul 2019 at 12:14, Efi Fogel ***@***.***> wrote:
ok, then let me handle it in a separate branch (including the patch I
provided).
____ _ ____ _
/_____/_) o /__________ __ //
(____ ( ( ( (_/ (_/-(-'_(/
_/
On Tue, 9 Jul 2019 at 11:38, Laurent Rineau ***@***.***>
wrote:
> I have verified that your patch does not fix the issue. The temporary
> object of type Arr_polycurve_basic_traits_2 is still created, and the
> reference bound to it.
>
> —
> You are receiving this because your review was requested.
> Reply to this email directly, view it on GitHub
> <#4012?email_source=notifications&email_token=ABVBNOAEW7QHUMMYYZBEECTP6RFBNA5CNFSM4HY6D3GKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZPRP4Y#issuecomment-509548531>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABVBNOCO6ZXIWTXMPKU54RDP6RFBNANCNFSM4HY6D3GA>
> .
>
|
Successfully tested in https://cgal.geometryfactory.com/CGAL/testsuite/results-5.0-Ic-95.shtml |
Successfully tested in https://cgal.geometryfactory.com/CGAL/testsuite/results-4.14.1-Ic-98.shtml |
This PR is still not yet approved by Efi. Let's stop testing it for the moment. |
Replaced by #4230. |
Summary of Changes
Before this patch,
Arr_polycurve_basic_traits_2
was holding a constreference to a temporary object.
Here was the result of ctest, with the address sanitizer:
This is fixed rather easily, by copying the traits class, instead of
holding a reference to it.
Release Management