From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10796 invoked by alias); 19 Jun 2002 17:08:13 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 10763 invoked from network); 19 Jun 2002 17:08:10 -0000 Received: from unknown (HELO www.dberlin.org) (138.88.44.94) by sources.redhat.com with SMTP; 19 Jun 2002 17:08:10 -0000 Received: by www.dberlin.org (Postfix, from userid 503) id 37D09182D06E; Wed, 19 Jun 2002 13:08:10 -0400 (EDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by www.dberlin.org (Postfix) with ESMTP id 748E318005D1; Wed, 19 Jun 2002 13:08:04 -0400 (EDT) Date: Wed, 19 Jun 2002 10:08:00 -0000 From: Daniel Berlin To: Jim Blandy Cc: gdb@sources.redhat.com Subject: Re: GDB support for thread-local storage In-Reply-To: <20020619160004.38A625EA11@zwingli.cygnus.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Spam-Status: No, hits=-2.5 required=5.0 tests=IN_REP_TO,X_NOT_PRESENT,NO_MX_FOR_FROM,AWL version=2.30 X-Spam-Level: X-SW-Source: 2002-06/txt/msg00146.txt.bz2 On Wed, 19 Jun 2002, Jim Blandy wrote: > > I'd like to extend GDB to support thread-local variables. Richard > Henderson, Ulrich Drepper and I have come up with some pieces of the > solutions; pretty much everything outside GDB has been settled, but > I'm still trying to figure out how GDB will pull the pieces together. > > This post describes: > - the feature we're trying to support, > - the parts we've worked out so far, and > - the parts in GDB that I'm still trying to sort out. > > Some implementations of C and C++ support a ``__thread'' storage > class, for variables that occupy distinct memory in distinct threads. > For example, the definition: > > __thread int foo; > > declares an integer variable named ``foo'' which has a separate value > and address in each thread, much as a variable declared ``auto'' has a > separate value and address in each invocation of the function > containing its declaration. Creating a new thread creates a new > instance of ``foo'', and when the thread exits, the storage for > ``foo'' is freed. > > Typically, a program includes an ``initialization image'' --- a block > of memory containing the initial values for any thread-local variables > it defines. When the program creates a new thread, the run-time > system allocates a fresh block of memory for those thread-local > variables, and copies the initialization image into it to give the > variables their initialized values. > > A dynamically loaded library may also define thread-local variables. > Some implementations delay allocating memory for such variables until > the thread actually refers to them for the first time. This avoids > the overhead of allocating and initializing the library's thread-local > storage for all the threads present in a program when the library is > loaded, even though only a few threads might actually use the library. > > Thread-local storage requires support in the ABI, and support in the > dynamic linker, if you want reasonable performance. There's a > complete description of how it's done on the IA-32, IA-64, and SPARC > at http://people.redhat.com/drepper/tls.pdf. This is based on > specifications already written for the IA-64 and SPARC; I think the > IA-32 implementation is Ulrich Drepper's work. > > For GDB, the first question is: how should the debugging information > describe the location of a thread-local variable? We generally answer > this sort of question by looking at how the code generated by the > compiler finds the variable, and then emitting debugging information > that matches that. > > To allow the run-time system to allocate thread-local storage on > demand, the ABI in certain circumstances requires the compiler to emit > a call to a function, __tls_get_addr, to find the address of a > thread-local variable for the current thread and a particular module. > This function looks up the address in a table, allocates and > initializes the storage if necessary, and returns its address. > > Unfortunately, Dwarf 2 location expressions cannot perform function > calls in the inferior. Errr, buzz. See DW_OP_call_* in dwarf3 It's not just turing complete anymore, one could probably write useful application extensions in dwarf3. Scary. --Dan