From owner-freebsd-current@FreeBSD.ORG Mon May 21 11:16:44 2012 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B47E41065674; Mon, 21 May 2012 11:16:44 +0000 (UTC) (envelope-from gperez@entel.upc.edu) Received: from dash.upc.es (dash.upc.es [147.83.2.50]) by mx1.freebsd.org (Postfix) with ESMTP id 2CE028FC1C; Mon, 21 May 2012 11:16:43 +0000 (UTC) Received: from ackerman2.upc.es (ackerman2.upc.es [147.83.2.244]) by dash.upc.es (8.14.1/8.13.1) with ESMTP id q4LBGaZF018875 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 21 May 2012 13:16:36 +0200 Received: from portgus.lan ([147.83.40.234]) (authenticated bits=0) by ackerman2.upc.es (8.14.4/8.14.4) with ESMTP id q4LBGWgr005030 (version=TLSv1/SSLv3 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Mon, 21 May 2012 13:16:36 +0200 Message-ID: <4FBA2430.6040301@entel.upc.edu> Date: Mon, 21 May 2012 13:17:04 +0200 From: =?UTF-8?B?R3VzdGF1IFDDqXJleiBpIFF1ZXJvbA==?= User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:12.0) Gecko/20120422 Thunderbird/12.0 MIME-Version: 1.0 To: davidxu@freebsd.org References: <4F9E9E06.4070004@entel.upc.edu> <4FB88925.4070008@gmail.com> <20120520172419.GQ2358@deviant.kiev.zoral.com.ua> <4FB9AE7E.6090109@gmail.com> <4FB9B649.8020906@gmail.com> In-Reply-To: <4FB9B649.8020906@gmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.70 on 147.83.2.244 X-Mail-Scanned: Criba 2.0 + Clamd X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-3.0 (dash.upc.es [147.83.2.50]); Mon, 21 May 2012 13:16:37 +0200 (CEST) Cc: Konstantin Belousov , Alberto Villa , FreeBSD current , David Xu Subject: Re: RFC: jemalloc: qdbus sigsegv in malloc_init X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 May 2012 11:16:44 -0000 >> > Now let me dig into qthread_unix.cpp, see how QThreadData::current() > works: > > QThreadData *QThreadData::current() > { > QThreadData *data = get_thread_data(); > if (!data) { > void *a; > if > (QInternal::activateCallbacks(QInternal::AdoptCurrentThread, &a)) { > QThread *adopted = static_cast(a); > Q_ASSERT(adopted); > data = QThreadData::get2(adopted); > set_thread_data(data); > adopted->d_func()->running = true; > adopted->d_func()->finished = false; > static_cast(adopted)->init(); > } else { > data = new QThreadData; > QT_TRY { > set_thread_data(data); > data->thread = new QAdoptedThread(data); > } QT_CATCH(...) { > clear_thread_data(); > data->deref(); > data = 0; > QT_RETHROW; > } > data->deref(); > } > if (!QCoreApplicationPrivate::theMainThread) > QCoreApplicationPrivate::theMainThread = data->thread; > } > return data; > } > > it calls get_thread_data(), if it returns NULL, it create a new > thread, and try to > set the new thread as "current thread data", it calls set_thread_data(). > > let's see how get_thread_data() and set_thread_data() work : > > static QThreadData *get_thread_data() > { > #ifdef Q_OS_SYMBIAN > return reinterpret_cast(Dll::Tls()); > #else > pthread_once(¤t_thread_data_once, > create_current_thread_data_key); > return reinterpret_cast *>(pthread_getspecific(current_thread_data_key)); > #endif > } > > static void set_thread_data(QThreadData *data) > { > #ifdef Q_OS_SYMBIAN > qt_symbian_throwIfError(Dll::SetTls(data)); > #endif > pthread_once(¤t_thread_data_once, > create_current_thread_data_key); > pthread_setspecific(current_thread_data_key, data); > } > > > They just use pthread_getspecific and pthread_setspecific, the > current_thread_data_key was only > created once which is guarded by pthread_once(), but as you know, the > key has already > been deleted by Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key) > which is a global > object which has been destructed early, the key is no longer > recreated, it is a stale key. > I was able to debug until the point where qthread_unix.cpp spawns a new thread because the get_thread_data call returns 0. I was unable to reach the full analysis, but now I get it. The explanation seems fine to me, thanks. What I don't get is why it works in stable. The functions registered to be executed at exit (atexit_register hasn't changed) get registered in same order in both branches (at least I checked them by printing the two atexit structures when calling exit in both stable and head). Wouldn't that mean that the problem of deleting the current_thread_data_key should happen in both branches? Gus