On 9/16/20 11:05 AM, H.J. Lu wrote: > On Wed, Sep 16, 2020 at 9:53 AM Jeff Law via Gcc-patches > wrote: >> >> Consider a TU with file scoped "static const object utf8_sb_map". A >> routine within the TU will stuff &utf8_sb_map into an object, something >> like: >> >> fu (...) >> >> { >> >> if (cond) >> >> dfa->sb_char = utf8_sb_map; >> >> else >> >> dfa->sb_char = malloc (...); >> >> } >> >> >> There is another routine in the TU which looks like >> >> bar (...) >> >> { >> >> if (dfa->sb_char != utf8_sb_map) >> >> free (dfa->sb_char); >> >> } >> >> >> Now imagine that the TU is compiled (with LTO) into a static library, >> libgl.a and there's a DSO (libdso.so) which gets linked against libgl.a >> and references the first routine (fu). We get a copy of fu in the DSO >> along with a copy of utf8_sb_map. >> >> >> Then imagine there's a main executable that dynamicly links against >> libdso.so, then links statically against libgl.a. Assume the main >> executable does not directly reference fu(), but does call a routine in >> libdso.so which eventually calls fu(). Also assume the main executable >> directly calls bar(). Again, remember we're compiling with LTO, so we >> don't suck in the entire TU, just the routines/data we need. >> >> >> In this scenario, both libdso.so and the main executable are going to a >> copy of utf8_sb_map and they'll be at different addresses. So when the >> main executable calls into libdso.so which in turn calls libdso's copy >> of fu() which stuffs the address of utf8_sb_map from the DSO into >> dfa->sb_char. Later the main executable calls bar() that's in the main >> executable. It does the comparison to see if dfa->sb_char is equal to >> utf8_sb_map -- but it's using the main executable's copy of utf8_sb_map >> and naturally free() blows us because it was passed a static object, not >> a malloc'd object. >> >> >> ISTM this is a lot like the problem we have where we inline functions >> with static data. To fix those we use STB_GNU_UNIQUE. But I don't see >> any code in the C front-end which would utilize STB_GNU_UNIQUE. It's >> support seems limited to C++. >> >> >> How is this supposed to work for C? >> >> >> Jeff >> >> > Can you group utf8_sb_map, fu and bar together so that they are defined > together? They're all defined within the same TU in gnulib.  It's the LTO dead/unreachable code elimination that results in just parts of the TU being copied into the DSO and a different set copied into the main executable.  In many ways LTO makes this look a lot like the static data member problems we've had to deal with in the C++ world. jeff