Skip to content

Commit ca7597d

Browse files
lalawawaGitHub Enterprise
authored and
GitHub Enterprise
committed
balst_stacktracetestallocator: sun gcc opt bug workaround - use functor not func ptr (#5051)
1 parent 5d339be commit ca7597d

File tree

1 file changed

+95
-44
lines changed

1 file changed

+95
-44
lines changed

groups/bal/balst/balst_stacktracetestallocator.t.cpp

Lines changed: 95 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -605,22 +605,38 @@ void my_assertHandlerLongJmp(const char *, // text
605605
longjmp(my_setJmpBuf, true);
606606
}
607607

608-
void my_failureHandlerLongJmp()
609-
{
608+
struct my_FailureHandlerLongJmp {
609+
// The Solaris GNU compiler, when optimized in C++11 or beyond, somehow
610+
// corrupts memory if 'longjmp' is called from a d'tor. For reasons I
611+
// don't understand, the problem goes away if this handler is a functor and
612+
// not a free function.
613+
//
614+
// It was very hard to narrow down, but if the handler is a free function
615+
// in a 'bsl::function<void()>', it somehow corrupts the 'bsl::function'
616+
// object such that the next assignment to that 'bsl::function' object
617+
// results in either a segfault or an illegal instruction. The problem
618+
// mysteriously comes and goes as debug traces are added and removed. If
619+
// the 'bsl::function' contains a functor and not a ptr to a free function,
620+
// the problem somehow doesn't happen.
621+
622+
void operator()() {
610623
#ifdef BSLS_PLATFORM_OS_WINDOWS
611-
// setjmp / longjmp is flaky on Windows
624+
// setjmp / longjmp is flaky on Windows
612625

613-
ASSERT(0);
626+
ASSERT(0);
614627
#endif
615628

616-
longjmp(my_setJmpBuf, true);
617-
}
629+
longjmp(my_setJmpBuf, true);
630+
}
631+
};
618632

619633
bool my_failureHandlerFlag = false;
620-
void my_failureHandlerSetFlag()
621-
{
622-
my_failureHandlerFlag = true;
623-
}
634+
struct my_FailureHandlerSetFlag {
635+
void operator()()
636+
{
637+
my_failureHandlerFlag = true;
638+
}
639+
};
624640

625641
#ifdef BSLS_PLATFORM_OS_WINDOWS
626642
enum { ABORT_LIMIT = 1 };
@@ -1966,9 +1982,14 @@ int main(int argc, char *argv[])
19661982
ASSERT(ABORT);
19671983
}
19681984
else {
1969-
ta.setFailureHandler(ABORT
1970-
? &my_failureHandlerLongJmp
1971-
: &my_failureHandlerSetFlag);
1985+
if (ABORT) {
1986+
ta.setFailureHandler(
1987+
my_FailureHandlerLongJmp());
1988+
}
1989+
else {
1990+
ta.setFailureHandler(
1991+
my_FailureHandlerSetFlag());
1992+
}
19721993
my_failureHandlerFlag = false;
19731994

19741995
ta.deallocate(ptr);
@@ -2029,9 +2050,14 @@ int main(int argc, char *argv[])
20292050
ASSERT(ABORT);
20302051
}
20312052
else {
2032-
ta.setFailureHandler(ABORT
2033-
? &my_failureHandlerLongJmp
2034-
: &my_failureHandlerSetFlag);
2053+
if (ABORT) {
2054+
ta.setFailureHandler(
2055+
my_FailureHandlerLongJmp());
2056+
}
2057+
else {
2058+
ta.setFailureHandler(
2059+
my_FailureHandlerSetFlag());
2060+
}
20352061

20362062
my_failureHandlerFlag = false;
20372063

@@ -2161,8 +2187,14 @@ int main(int argc, char *argv[])
21612187
ASSERT(ABORT);
21622188
}
21632189
else {
2164-
tba.setFailureHandler(ABORT ? &my_failureHandlerLongJmp
2165-
: &my_failureHandlerSetFlag);
2190+
if (ABORT) {
2191+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2192+
tba.setFailureHandler(my_FailureHandlerLongJmp());
2193+
}
2194+
else {
2195+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2196+
tba.setFailureHandler(my_FailureHandlerSetFlag());
2197+
}
21662198

21672199
void *ptr = tba.allocate(6);
21682200

@@ -2209,8 +2241,12 @@ int main(int argc, char *argv[])
22092241
ASSERT(ABORT);
22102242
}
22112243
else {
2212-
ta.setFailureHandler(ABORT ? &my_failureHandlerLongJmp
2213-
: &my_failureHandlerSetFlag);
2244+
if (ABORT) {
2245+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2246+
}
2247+
else {
2248+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2249+
}
22142250

22152251
ASSERT(oss. str().empty());
22162252
ASSERT(oss2.str().empty());
@@ -2263,8 +2299,12 @@ int main(int argc, char *argv[])
22632299
ASSERT(ABORT);
22642300
}
22652301
else {
2266-
ta.setFailureHandler(ABORT ? &my_failureHandlerLongJmp
2267-
: &my_failureHandlerSetFlag);
2302+
if (ABORT) {
2303+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2304+
}
2305+
else {
2306+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2307+
}
22682308

22692309
ASSERT(oss.str().empty());
22702310

@@ -2307,8 +2347,12 @@ int main(int argc, char *argv[])
23072347
ASSERT(ABORT);
23082348
}
23092349
else {
2310-
ta.setFailureHandler(ABORT ? &my_failureHandlerLongJmp
2311-
: &my_failureHandlerSetFlag);
2350+
if (ABORT) {
2351+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2352+
}
2353+
else {
2354+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2355+
}
23122356

23132357
ASSERT(oss.str().empty());
23142358

@@ -2351,8 +2395,12 @@ int main(int argc, char *argv[])
23512395
ASSERT(ABORT);
23522396
}
23532397
else {
2354-
ta.setFailureHandler(ABORT ? &my_failureHandlerLongJmp
2355-
: &my_failureHandlerSetFlag);
2398+
if (ABORT) {
2399+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2400+
}
2401+
else {
2402+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2403+
}
23562404

23572405
ASSERT(oss.str().empty());
23582406

@@ -2397,8 +2445,12 @@ int main(int argc, char *argv[])
23972445
ASSERT(ABORT);
23982446
}
23992447
else {
2400-
ta.setFailureHandler(ABORT ? &my_failureHandlerLongJmp
2401-
: &my_failureHandlerSetFlag);
2448+
if (ABORT) {
2449+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2450+
}
2451+
else {
2452+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2453+
}
24022454

24032455
ASSERT(oss.str().empty());
24042456

@@ -2443,8 +2495,12 @@ int main(int argc, char *argv[])
24432495
ASSERT(ABORT);
24442496
}
24452497
else {
2446-
ta.setFailureHandler(ABORT ? &my_failureHandlerLongJmp
2447-
: &my_failureHandlerSetFlag);
2498+
if (ABORT) {
2499+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2500+
}
2501+
else {
2502+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2503+
}
24482504

24492505
ASSERT(oss.str().empty());
24502506

@@ -2493,8 +2549,12 @@ int main(int argc, char *argv[])
24932549
ASSERT(ABORT);
24942550
}
24952551
else {
2496-
ta.setFailureHandler(ABORT ?&my_failureHandlerLongJmp
2497-
:&my_failureHandlerSetFlag);
2552+
if (ABORT) {
2553+
ta.setFailureHandler(my_FailureHandlerLongJmp());
2554+
}
2555+
else {
2556+
ta.setFailureHandler(my_FailureHandlerSetFlag());
2557+
}
24982558

24992559
ASSERT(oss.str().empty());
25002560

@@ -2657,15 +2717,6 @@ int main(int argc, char *argv[])
26572717
#ifdef BSLS_PLATFORM_OS_WINDOWS
26582718
break;
26592719
#endif
2660-
#if defined(BSLS_PLATFORM_OS_SOLARIS) && defined(BSLS_PLATFORM_CMP_GNU) && \
2661-
defined(BDE_BUILD_TARGET_OPT)
2662-
// There seems to be a compiler bug in Solaris GNU compilers where,
2663-
// with the optimizer on, the `longjmp` here corrupts a nearby
2664-
// automatic variable. Let's face it -- doing a `longjmp` out of a
2665-
// d'tor is not a very important test.
2666-
2667-
break;
2668-
#endif
26692720

26702721
if (verbose) Q(Longjmp on destruction with blocks outstanding);
26712722
{
@@ -2710,7 +2761,7 @@ int main(int argc, char *argv[])
27102761
ASSERT(pta->numBlocksInUse() == numAllocs);
27112762
}
27122763
else {
2713-
pta->setFailureHandler(&my_failureHandlerLongJmp);
2764+
pta->setFailureHandler(my_FailureHandlerLongJmp());
27142765

27152766
if (veryVerbose) P(staBlocks);
27162767

@@ -3378,10 +3429,10 @@ int main(int argc, char *argv[])
33783429
}
33793430
else {
33803431
if (FAILURE_LONGJMP) {
3381-
ta.setFailureHandler(&my_failureHandlerLongJmp);
3432+
ta.setFailureHandler(my_FailureHandlerLongJmp());
33823433
}
33833434
else {
3384-
ta.setFailureHandler(&my_failureHandlerSetFlag);
3435+
ta.setFailureHandler(my_FailureHandlerSetFlag());
33853436
}
33863437

33873438
my_failureHandlerFlag = false;

0 commit comments

Comments
 (0)