From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 58874 invoked by alias); 5 Nov 2019 15:19:28 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 58863 invoked by uid 89); 5 Nov 2019 15:19:28 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-5.8 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: simark.ca Received: from simark.ca (HELO simark.ca) (158.69.221.121) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Nov 2019 15:19:27 +0000 Received: from [10.0.0.11] (unknown [192.222.164.54]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 8D26F1E47D; Tue, 5 Nov 2019 10:19:24 -0500 (EST) Subject: Re: [RFC PATCH] Support debuginfo and source file fetching via debuginfo server To: "Frank Ch. Eigler" Cc: Aaron Merey , Tom Tromey , Christian Biesinger via gdb-patches , Christian Biesinger References: <87pnj6dl3k.fsf@tromey.com> <87sgn71ji6.fsf@tromey.com> <87lfsye5l5.fsf@redhat.com> <87bltrelab.fsf@redhat.com> <20191104162616.GA13319@redhat.com> <6f3fb81a-09ef-ab07-eef4-0460181bcaa0@simark.ca> <20191105102519.GA18724@redhat.com> From: Simon Marchi Message-ID: Date: Tue, 05 Nov 2019 15:19:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.0 MIME-Version: 1.0 In-Reply-To: <20191105102519.GA18724@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-SW-Source: 2019-11/txt/msg00118.txt.bz2 On 2019-11-05 5:25 a.m., Frank Ch. Eigler wrote: > Hi - > >> Maybe a user_data void pointer would be useful, to be able to get some >> context in the callback? > > In your case, with a single-threaded app with C++ lambda captured > variables, you wouldn't need the library to do that. In a > multithreaded app's case, __thread variables and the promise to call > those functions back from the calling thread should again let one get > context if required. Hmm does it actually work to capture some variables in the C++ lambda? Given that the callback is declared as a simple function pointer: 64 typedef int (*debuginfod_progressfn_t)(long a, long b); 65 debuginfod_progressfn_t debuginfod_set_progressfn(debuginfod_progressfn_t fn); I'm not sure that we can pass a lambda that captures stuff. Just like this program: static void func(void (*callback)(void)) { callback(); } int main() { int a; func([a] { }); return 0; } Generates this error: test.cpp: In function ‘int main()’: test.cpp:2:33: error: cannot convert ‘main()::’ to ‘void (*)()’ 2 | int main() { int a; func([a] { }); return 0; } | ^ | | | main():: test.cpp:1:25: note: initializing argument 1 of ‘void func(void (*)())’ 1 | static void func(void (*callback)(void)) { callback(); } | ~~~~~~~^~~~~~~~~~~~~~~ >> I am noticing that debuginfod calls don't have any "context" or "handle" >> parameters, which could suggest that the state of the library (if there >> is any) is kept as global variables. [...] I think that providing a void pointer for context is pretty standard thing for C libraries that accept callbacks. I would use __thread and the promise to call the function back in the same thread to "retro-fit" some thread-safety in an existing API that doesn't provide a context pointer, and that can't be changed. But if the API is new, I think the context pointer solution is more obvious for the user. > It turns out it's the opposite: except for this callback function > pointer, it's practically all local variables therefore multithread-safe. Ok, well I think it would be a good reason to adopt an API of the style: debuginfod_client *client = debuginfod_create_client (); debuginfod_set_progressfn (client, my_progress_cb); and where you pass `client` to all further calls. That client object would keep the callback for those calls, but also any other state that you might want to keep across in the future. Again, this is easy to add in the beginning, but hard to retro-fit later on. Simon