Bug 1180633
Summary: | libitm: segfault for the simple testcase | ||
---|---|---|---|
Product: | Red Hat Enterprise Linux 7 | Reporter: | Miroslav Franc <mfranc> |
Component: | gcc | Assignee: | Jakub Jelinek <jakub> |
Status: | CLOSED ERRATA | QA Contact: | Michael Petlan <mpetlan> |
Severity: | medium | Docs Contact: | |
Priority: | unspecified | ||
Version: | 7.1 | CC: | jakub, lance, law, mcermak, mnewsome, mpetlan, mpolacek, msebor, ohudlick, qe-baseos-tools-bugs, rth, triegel |
Target Milestone: | rc | ||
Target Release: | --- | ||
Hardware: | ppc64 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | gcc-4.8.5-6.el7 | Doc Type: | No Doc Update |
Doc Text: |
undefined
|
Story Points: | --- |
Clone Of: | 1080486 | Environment: | |
Last Closed: | 2016-11-04 06:25:27 UTC | Type: | Bug |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: | |||
Bug Depends On: | 1080486 | ||
Bug Blocks: | 1110700, 1191021, 1297579, 1313485 |
Description
Miroslav Franc
2015-01-09 15:33:07 UTC
I've reproduced the issue on a RHEL7 box; gcc trunk seems to be fine. Let me see if I can perhaps bisect when it got fixed. (In reply to Marek Polacek from comment #1) > I've reproduced the issue on a RHEL7 box; gcc trunk seems to be fine. Let > me see if I can perhaps bisect when it got fixed. Some new observations. The above is incorrect; I reproduced the failure even with the FSF trunk and with 4.9/4.8 branches, but only on a RHEL7 system. On a Fedora 20 box I couldn't reproduce the segv at all. Both were power8 machines. Given c#2, I don't think we have any sense of what the real issue is. It's highly unlikely this will get fixed in RHEL 7.3. It's not even clear at this point if we have a bug in gcc or something else. I have added some debugging: --- libitm/beginend.cc.xx 2013-06-28 05:44:16.000000000 -0400 +++ libitm/beginend.cc 2015-12-16 09:13:52.722248313 -0500 @@ -32,6 +32,8 @@ using namespace GTM; extern __thread gtm_thread_tls _gtm_thr_tls; #endif +__thread char myflags[6]; + gtm_rwlock GTM::gtm_thread::serial_lock; gtm_thread *GTM::gtm_thread::list_of_threads = 0; unsigned GTM::gtm_thread::number_of_threads = 0; @@ -57,6 +59,12 @@ static pthread_once_t thr_release_once = // See gtm_thread::begin_transaction. uint32_t GTM::htm_fastpath = 0; +char * +getmyflags (void) +{ + return myflags; +} + /* Allocate a transaction structure. */ void * GTM::gtm_thread::operator new (size_t s) @@ -85,6 +93,7 @@ thread_exit_handler(void *) gtm_thread *thr = gtm_thr(); if (thr) delete thr; + myflags[0] = 1; set_gtm_thr(0); } @@ -189,6 +198,7 @@ GTM::gtm_thread::begin_transaction (uint // and thus do not trigger the standard retry handling). if (likely(htm_fastpath && (prop & pr_hasNoAbort))) { +myflags[3] = 1; for (uint32_t t = htm_fastpath; t; t--) { uint32_t ret = htm_begin(); @@ -219,6 +229,7 @@ GTM::gtm_thread::begin_transaction (uint { // See below. tx = new gtm_thread(); + myflags[1] = 1; set_gtm_thr(tx); } // Check whether there is an enclosing serial-mode transaction; @@ -245,6 +256,7 @@ GTM::gtm_thread::begin_transaction (uint // Create the thread object. The constructor will also set up automatic // deletion on thread termination. tx = new gtm_thread(); + myflags[2] = 1; set_gtm_thr(tx); } --- libitm/method-serial.cc.xx 2013-02-06 12:20:04.000000000 -0500 +++ libitm/method-serial.cc 2015-12-16 09:18:18.802254699 -0500 @@ -24,6 +24,9 @@ #include "libitm_i.h" +extern __thread char myflags[6]; +char myflags2[6]; + // Avoid a dependency on libstdc++ for the pure virtuals in abi_dispatch. extern "C" void HIDDEN __cxa_pure_virtual () @@ -223,12 +226,16 @@ struct htm_mg : public method_group // initially disabled. #ifdef USE_HTM_FASTPATH htm_fastpath = htm_init(); +myflags[4] = htm_fastpath + 1; +myflags2[0] = 1; #endif } virtual void fini() { // Disable the HTM fastpath. htm_fastpath = 0; +myflags[5] = 1; +myflags2[1] = 1; } }; and in the thread that crashed I see only myflags[3] being set, and in the global myflags2 array I see both myflags2[0] and myflags2[1] being set. So my suspicion is that the the first thread that encounters GTM::gtm_thread::begin_transaction (or whatever other routine) at some point invokes the htm_mg::init (), which sets a global variable, and later on for whatever reason performs htm_mg::fini (), which sets the global variable back to 0. But other threads access this global variable concurrently, and can e.g. see it being set while in beginTransaction, but already cleared when in commitTransaction. Should that variable be TLS too, or is some locking/whatever needed, or should it never be cleared? Tested against 4.8.5-4.el7 and 4.8.5-9.el7. Reproducible on POWER8 boxes only. New gcc passes everywhere. VERIFIED Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHBA-2016-2433.html |