Test failures due to mysterious early return when a map is rendered twice and uses a shield symbolizer placement #1696

Closed
springmeyer opened this Issue Jan 19, 2013 · 6 comments

2 participants

@springmeyer
Mapnik member

On OS X with clang++ 3.3. in current master we've had for a while (ever since b7f4635) what I thought were minor test failures due to a buggy osm plugin or buggy tests. https://gist.github.com/74f36760c2f8f04dc8ba.

However, it turns out they are datasource independent and result from some truly bizarre behavior inside of symbolizer_helpers.cpp.

The key conditions appear to be:

  • Render a map with a shield symbolizer with placement=line clip="true" and allow-overlap="false"
  • You also need to render the map twice. Only the second time (or later times) will the bug show up. Yes, the first time the render is correct. And yes, this happens on the second render even if the maps are completely independent objects (separate variable in python and separate call to load_map).

The symptom is that an entire line (that renders fine with the line symbolizer) is ignored for placing shields. This is because the shield symbolizer's next() calls out to the text symbolizer's next_line_placement_clipped(). It appears that the compiler somehow optimizes away this entire function.

Oddly I can workaround the problem (and fix ALL of the failing tests) by simply putting some additional code into this loop:

diff --git a/src/symbolizer_helpers.cpp b/src/symbolizer_helpers.cpp
index a547e4d..6ef45c9 100644
--- a/src/symbolizer_helpers.cpp
+++ b/src/symbolizer_helpers.cpp
@@ -104,6 +104,8 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement_clippe
         typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
         clipped_geometry_type clipped(**geo_itr_);
         clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
+        std::ostringstream s;
+        s << query_extent_ << "\n";
         path_type path(t_, clipped, prj_trans_);

         finder_->clear_placements();
@springmeyer
Mapnik member

/cc @herm in case he has any ideas.

@herm
Mapnik member

Looks like a compiler bug. I had a similar issue with clang/LLVM some time ago.
A while(p) loop (p is a pointer) was optimized away.

@springmeyer
Mapnik member

upgrading clang to svn HEAD fixed it. I'm now at:

$ clang++ -v
clang version 3.3 (trunk 173227)
Target: x86_64-apple-darwin11.4.2
Thread model: posix

closing.

@springmeyer
Mapnik member

this seems to come back mysteriously, even without changing the clang++ version. re-opening.

@springmeyer springmeyer reopened this Mar 6, 2013
@springmeyer
Mapnik member

more info. still seeing this with latest clang++:

clang version 3.3 (trunk 177655)
Target: x86_64-apple-darwin11.4.2
Thread model: posix

Also present in 2.1.x branch, but goes away if I build with -O2 instead of -O3.

@springmeyer springmeyer was assigned May 9, 2013
@springmeyer
Mapnik member

no longer present with -03 and:

Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment