From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id 80CED3894C18 for ; Thu, 17 Sep 2020 19:01:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 80CED3894C18 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=simark.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=simark@simark.ca Received: from [10.0.0.11] (173-246-6-90.qc.cable.ebox.net [173.246.6.90]) (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 CE13C1E50D; Thu, 17 Sep 2020 15:01:50 -0400 (EDT) Subject: Re: debugger-only log on Linux, equivalent of OutputDebugString To: Tom Tromey , "A. M. Miera via Gdb" Cc: "A. M. Miera" References: <87h7rw72il.fsf@tromey.com> From: Simon Marchi Message-ID: Date: Thu, 17 Sep 2020 15:01:50 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0 MIME-Version: 1.0 In-Reply-To: <87h7rw72il.fsf@tromey.com> Content-Type: text/plain; charset=utf-8 Content-Language: fr Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3.8 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, NICE_REPLY_A, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Sep 2020 19:01:53 -0000 On 2020-09-17 1:10 p.m., Tom Tromey wrote: >>>>>> ">" == A M Miera via Gdb writes: > >>> The main question I'd like to ask though, is this: is that actually >>> the right way to go, or can this be done better in terms of operation >>> principles? I have several concerns here: >>> a. this might be very system-specific, e.g. for bare-metal Cortex-Mx >>> targets there's sth called "semihosting", which effectively does the >>> same (though is something different in principle). Windows already its >>> own call, too, etc. >>> b. most likely a simple pipe-based solution is not going to work with >>> remote targets, e.g. gdbserver? Should it be added? >>> c. and last but not least: maybe a mechanism already exists and I'm >>> reinventing the wheel now? > > I don't know of another existing implementation of this. > > Your approach sounds maybe a bit like what "libust" is doing. > That might be worth a look. > > Tom > Just to clarify, Tom is talking about the LTTng-UST project [1]. This is tracing, so not quite exactly what you describe, but perhaps it could cater to your use case. The overhead when tracing is quite low (and it doesn't use locking, so it stays good even with multiple threads) and essentially zero when tracing is disabled. Otherwise, if performance is not really a concern, you can easily implement something naive based on breakpoints in Python. This has the advantage that it would work with pretty much any target, remote or not. For example: ~~~ class OutputDebugStringBreakpoint(gdb.Breakpoint): def __init__(self): super().__init__("OutputDebugString", internal=True) def stop(self): s = gdb.parse_and_eval("str") print(s.string(), end='') # Return false: don't stop. return False OutputDebugStringBreakpoint() ~~~ With the script above, you just need to make sure your program contains an empty function "OutputDebugString" that isn't optimized away and is compiled with debug info, such that the script is able to find the value of the "str" argument. I read a bit on how OutputDebugString works on Windows [2]: it uses a shared memory mapping between the inferior and the debugger (or kernel?). It probably results in less overhead than an approach based on breakpoints like what I have shown above, because the process probably doesn't wait until the debugger has printed the string to keep going. We could imagine something similar in the GDB world, but it would require target-specific work. GDBserver could also implement the "host" side, collect the output strings and send them to GDB which will then print them. While writing this, I now notice that it sounds not too far from the fast tracepoints. Note that there already exists something for this in the remote protocol, the 'O' stop reply packet [3]. Maybe some debug stubs (even for debugging hardware like the Cortex-M) use it? I don't know. But according to the doc, it doesn't work with non-stop. Looking at the qemu source code, it looks like it supports sending the 'O' packet, but I don't know how it's used. I just looked in the gdb/gdbserver code [4][5], apparently gdb supports printing the strings passed to OutputDebugString on Windows. It arrives in the form a debug event containing the string to print, that's quite simple. GDBserver relays this string using the 'O' packet mentioned above. Simon [1] https://lttng.org/ [2] http://www.unixwiz.net/techtips/outputdebugstring.html#protocol [3] https://sourceware.org/gdb/current/onlinedocs/gdb/Stop-Reply-Packets.html [4] https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/windows-nat.c;h=188a920cbb061f0d8639340ffec40b7d9afd4b3b;hb=HEAD#l1720 [5] https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdbserver/win32-low.cc;h=a11cc740925a13edb7c2e689998cd215fc32abfa;hb=HEAD#l1571