public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Simon Marchi <simark@simark.ca>
To: Tom Tromey <tom@tromey.com>, "A. M. Miera via Gdb" <gdb@sourceware.org>
Cc: "A. M. Miera" <ammiera@hotmail.com>
Subject: Re: debugger-only log on Linux, equivalent of OutputDebugString
Date: Thu, 17 Sep 2020 15:01:50 -0400	[thread overview]
Message-ID: <d08e4439-827f-2ee4-6e5f-331079a946d7@simark.ca> (raw)
In-Reply-To: <87h7rw72il.fsf@tromey.com>

On 2020-09-17 1:10 p.m., Tom Tromey wrote:
>>>>>> ">" == A M Miera via Gdb <gdb@sourceware.org> 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

      reply	other threads:[~2020-09-17 19:01 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-17  8:48 A. M. Miera
2020-09-17 17:10 ` Tom Tromey
2020-09-17 19:01   ` Simon Marchi [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d08e4439-827f-2ee4-6e5f-331079a946d7@simark.ca \
    --to=simark@simark.ca \
    --cc=ammiera@hotmail.com \
    --cc=gdb@sourceware.org \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).