DMARC-Filter: OpenDMARC Filter v1.4.2 delorie.com 5A8C2w7d4145013 Authentication-Results: delorie.com; dmarc=pass (p=none dis=none) header.from=cygwin.com Authentication-Results: delorie.com; spf=pass smtp.mailfrom=cygwin.com DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 5A8C2w7d4145013 Authentication-Results: delorie.com; dkim=pass (1024-bit key, unprotected) header.d=cygwin.com header.i=@cygwin.com header.a=rsa-sha256 header.s=default header.b=uIpuAMgB X-Recipient: archive-cygwin AT delorie DOT com DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2A6EA3858C40 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com; s=default; t=1762603378; bh=izJ/b7ryQqmnwoWgQXW1UWtngbA6cNGCdvy5COXcxO0=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=uIpuAMgB/c1ZqgxL6tyBEcGYLe+iquRFLYpB/ZruFgY/BSo/Y4BYfGnzGjucsR9Fv NeC1TIZalbjsMIOkZ2wAvwjZxXgDkYxcUNExX9Mu0/bercyYuLwx6IlxAsnuRPN0PC jyj8T6ZW9AxdfTQny00es/bPDu3XsTzmaAkNkLJg= X-Original-To: cygwin AT cygwin DOT com Delivered-To: cygwin AT cygwin DOT com DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 120D63858C40 ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 120D63858C40 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1762603321; cv=none; b=LB2QbiP3XAFpJ40uylAuamkRW8xHX05c+EnRdfpHRIPO0vLgCXG68mP6wEGhqQBGNRoqKcmb0ljFYqA0TTgQ3sJ92SqplMVCAgU/e/JFFsKYM6txczISASMIyaokopZzokllOXH+XM+seV8a+MCCP7Y7pkL1jOZoiVb2sevQRDc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1762603321; c=relaxed/simple; bh=gW/JSr4q4mAOVucvbfvDli3dkYEVsDeV+l/822eOPPs=; h=Date:From:To:Subject:Message-Id:Mime-Version:DKIM-Signature; b=Ifu2qDTkFlqNwQylpNN3WNoSRGrZaPCP4b7OVOD3gRVp9i3AI7BBqZPTfrTQGTI39FlpYJoayKWhvB6emNTXKNexnSM9yvR+nbD3SYWFNoVz52vdXVxrUHOpKU0L3AGG5R5fHI7h86p+57khGBC8NNCVnikx3kIpzVJXzG9zlSg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 120D63858C40 Date: Sat, 8 Nov 2025 21:01:56 +0900 To: cygwin AT cygwin DOT com Subject: [gcc] Bug in emutls? Message-Id: <20251108210156.20eadc80a8161eece6810175@nifty.ne.jp> X-Mailer: Sylpheed 3.7.0 (GTK+ 2.24.30; i686-pc-mingw32) Mime-Version: 1.0 X-BeenThere: cygwin AT cygwin DOT com X-Mailman-Version: 2.1.30 List-Id: General Cygwin discussions and problem reports List-Archive: List-Post: List-Help: List-Subscribe: , From: Takashi Yano via Cygwin Reply-To: Takashi Yano Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Cygwin" Hi everyone, I encountered a problem with static thread_local in C++ program. The following simple reproducer does not work as expected if it runs under cygwin 3.7.0 (Test), while it works under cygwin 3.6.5. To conclude, this was not a bug in Cygwin 3.7.0. This is triggered by the commit: commit ebd92b128f62a0b3c270319487b8486abdfa405b Author: Takashi Yano Date: Fri Apr 4 21:22:27 2025 +0900 Cygwin: thread: Use simple array instead of List where the call order of the destructors for pthread_key was changed. The call order can depend on implementation. So the code using pthread_key should not expect any predetermined call order of the destuctors. The result of the following code is 1: 0xa00016938 2: 0xa00016b98 X::print(): 2 X::print(): 1 X::~X(): 1 X::~X(): 2 under cygwin 3.6.5, while it is 1: 0xa00016938 2: 0xa00016b98 X::print(): 2 X::print(): 1 X::~X(): 2133815816 X::~X(): 2133815816 under cygwin 3.7.0 (Test). I looked into the problem, and found that the executable for the following code registers two pthread_keys with each destructor; one is void emutls_destroy(void *ptr) in libgcc/emutls.c, and the other is void run(void *p) in libstdc++-v3/libsupc++/atexit_thread.cc. emutls_destroy() free's the memory erea of static thread_local X, that is accessed from X::~X() which is called from run(). As a result, if the emutls_destroy() is called before run(), run() referres to the memory erea already free'ed. I think this is a bug of gcc. This issue does not occur in Linux, because Linux does not use emutls. Any idea? #include #include #include class X { int n; public: X(int n1) : n(n1) {} ~X() { printf("X::~X(): %d\n", n); } void print() { printf("X::print(): %d\n", n); } }; void func(int n) { static thread_local X x(n); printf("%d: %p\n", n, &x); usleep(10000); x.print(); usleep(10000); } int main() { std::thread t1(func, 1); std::thread t2(func, 2); t1.join(); t2.join(); return 0; } Any idea? -- Takashi Yano -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple