From: Pedro Alves <palves@redhat.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: tromey@adacore.com, cbiesinger@google.com, gdb-patches@sourceware.org
Subject: Re: [PATCH 2/3] Consistently use BFD's time
Date: Mon, 20 Jan 2020 20:58:00 -0000 [thread overview]
Message-ID: <40fa6532-4440-d47b-63db-9485828c791f@redhat.com> (raw)
In-Reply-To: <8336caxciw.fsf@gnu.org>
On 1/20/20 5:28 PM, Eli Zaretskii wrote:
>> Cc: cbiesinger@google.com, gdb-patches@sourceware.org
>> From: Pedro Alves <palves@redhat.com>
>> Date: Mon, 20 Jan 2020 15:48:22 +0000
>>
>>> I guess this means some other Gnulib module pulls in 'stat', in which
>>> case --avoid=stat is the way to try to avoid it, yes. (My guess is
>>> that the 'largefile' module causes 'stat' to be pulled in.)
>>
>> I'm not sure about that solution -- won't --avoid=stat mean that
>> we disable any stat gnulib fix for all platforms, instead of just
>> for Windows?
>
> It would, but do we have any known problems with stat and fstat on
> other platforms?
There's the list of known problems in the gnulib pages:
https://www.gnu.org/software/gnulib/manual/html_node/fstat.html
https://www.gnu.org/software/gnulib/manual/html_node/stat.html
https://www.gnu.org/software/gnulib/manual/html_node/lstat.html
>
>> We only have one lstat call, but we also use fstat, for example, and
>> I assume that these *stat modules in gnulib are all intertwined.
>> Also, we may only have one lstat call nowadays, but who knows about
>> the future.
>
> Even having a gdb_lstat for that purpose will be simpler and more
> future-proof than the whole Gnulib stat module, I think.
I think one could use that argument for any piece of gnulib in
isolation. But fighting against use of some particular modules
ends up creating a larger burden over time IMO. I'd rather avoid
doing that if possible.
>
>> I did come up with a workaround though, it's just different.
>>
>> I noticed that gnulib's sys/stat.h replacement starts with a way to
>> bypass it:
>>
>> #if defined __need_system_sys_stat_h
>> /* Special invocation convention. */
>>
>> #include_next <sys/stat.h>
>>
>> #else
>> /* Normal invocation convention. */
>>
>> #ifndef _GL_SYS_STAT_H
>>
>> So I think we can take advantage of that to be able to make sure that
>> when we include "bfd.h", its functions are declared using the system's
>> stat, which is the same version that bfd is built against.
>
> But stat/fstat the functions will still shadow the system ones, would
> they not?
Let's look at the patch:
--- c/gdbsupport/common-types.h
+++ w/gdbsupport/common-types.h
@@ -32,8 +32,21 @@ typedef unsigned long long ULONGEST;
#else /* GDBSERVER */
+/* Gnulib may replace struct stat with its own version. Bfd does not
+ use gnulib, so when we call into bfd, we must use the system struct
+ stat. */
+#define __need_system_sys_stat_h 1
+
+#include <sys/stat.h>
+
#include "bfd.h"
+typedef struct stat sys_stat;
+
+#undef __need_system_sys_stat_h
+
+#include <sys/stat.h>
Currently, without that patch, because of the gnulib struct stat
replacement, when we include bfd.h, we end up with the following
function declared, if you expand the preprocessor macros:
extern int bfd_stat (bfd *, struct rpl_stat *);
This is incorrect, because that bfd function was not defined
that way. It is instead written as:
extern int bfd_stat (bfd *, struct stat *);
Given the stat replacement, we pass it a rpl_stat pointer, when it
is in reality expecting a "struct stat" one (or whatever that expands
in the system headers). So we get undefined behavior at run time.
By defining __need_system_sys_stat_h just before bfd.h is included,
we're sure that bfd's bfd_stat is declared with the system's
stat, just like when bfd itself was compiled.
extern int bfd_stat (bfd *, struct stat *);
We undef __need_system_sys_stat_h again just after including
"bfd.h", so that the gdb uses the gnulib struct stat. But we
also create the sys_stat typedef so that we can refer to the
system's stat type after __need_system_sys_stat_h is undefined
and gnulib's stat replacement is visible.
So the *stat functions will be shadowed by the gnulib ones
within gdb, yes. But we also get a compile error if we
call bfd_stat with a masked struct stat:
binutils-gdb/src/gdb/gdb_bfd.c: In constructor 'gdb_bfd_data::gdb_bfd_data(bfd*)':
binutils-gdb/src/gdb/gdb_bfd.c:72:29: error: cannot convert 'rpl_stat*' to '_stat64*' for argument '2' to 'int bfd_stat(bfd*, _stat64*)'
if (bfd_stat (abfd, &buf) == 0)
^
> And if they would, doesn't it mean subtle bugs where, e.g.,
> the Gnulib replacement implementations rely on wide-enough st_size,
> for example, or st_mtime?
I'm not sure what you mean here. When the replacement implementations
are called, they're passed a replaced struct stat pointer too. It's
only while the bfd.h header is being compiled that the gnulib replacements
aren't visible.
> Also, aren't some of the problems on platforms other than MinGW
> resolved by the Gnulib sys/stat.h header, as opposed to the
> replacement implementation of the functions themselves?
Some yes, but not all. But it's the sys/stat.h header replacement
that redefines struct stat, so I don't see the point you're making.
Now, the solution I came up with is reusable for any other library we
may end up depending on that is built with a different struct stat
and requires passing a struct stat in one of its entry pointers.
However, with all that said, bfd is always built along with gdb, so
we have a higher degree of control. Maybe a better solution for
this is really to make sure that bfd is compiled with largefile
support, as suggested in the bug-gnulib discussion.
So far, I was under the impression that you're reaching the
GNULIB_defined_struct_stat code, where gnulib defines its own
struct stat. But reading your description of the bug in gnulib
again, I see you're actually getting stat defined to _stati64.
So perhaps what we need is to enable largefile support by
default on bfd for mingw, to force use of the 64-bit stat?
Does the original issue go away if you configure
with --enable-largefile? Maybe we need a mingw-specific
tweak in gdb's src/config/largefile.m4?
Looking my mingw-w64's stat.h, I see:
#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
#ifdef _USE_32BIT_TIME_T
#define stat _stat32i64
#define fstat _fstat32i64
#else
#define stat _stat64
#define fstat _fstat64
#endif
#endif
So if BFD is compiled with _FILE_OFFSET_BITS == 64 and
_USE_32BIT_TIME_T is not defined, the mismatch ends up going
away? Is there a reason we _wouldn't_ want to enable largefile
support in bfd?
Thanks,
Pedro Alves
next prev parent reply other threads:[~2020-01-20 20:50 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-14 21:10 [PATCH 0/3] Fix gdb's BFD cache Tom Tromey
2020-01-14 21:10 ` [PATCH 1/3] Avoid hash table corruption in gdb_bfd.c Tom Tromey
2020-01-14 22:26 ` Christian Biesinger via gdb-patches
2020-01-14 21:10 ` [PATCH 2/3] Consistently use BFD's time Tom Tromey
2020-01-14 23:17 ` Christian Biesinger via gdb-patches
2020-01-15 17:51 ` Eli Zaretskii
2020-01-16 20:47 ` Pedro Alves
2020-01-16 21:58 ` Christian Biesinger via gdb-patches
2020-01-16 22:31 ` Pedro Alves
2020-01-17 8:48 ` Eli Zaretskii
2020-01-17 18:32 ` Tom Tromey
2020-01-17 21:03 ` Tom Tromey
2020-01-18 11:07 ` Eli Zaretskii
2020-01-20 15:52 ` Pedro Alves
2020-01-20 15:53 ` Pedro Alves
2020-01-20 20:50 ` Eli Zaretskii
2020-01-20 20:58 ` Pedro Alves [this message]
2020-01-21 15:50 ` Pedro Alves
2020-01-21 19:38 ` Eli Zaretskii
2020-01-21 17:56 ` Eli Zaretskii
2020-01-23 22:05 ` Tom Tromey
2020-06-19 17:51 ` Tom Tromey
2020-04-01 20:20 ` Tom Tromey
2020-06-18 14:14 ` Tom Tromey
2020-06-18 15:04 ` Eli Zaretskii
2020-06-18 16:00 ` Tom Tromey
2020-06-18 17:27 ` Eli Zaretskii
2020-06-18 17:32 ` Pedro Alves
2020-06-18 17:54 ` Eli Zaretskii
2020-06-19 12:02 ` Pedro Alves
2020-06-19 12:13 ` Eli Zaretskii
2020-06-19 17:09 ` Tom Tromey
2020-06-19 20:24 ` Tom Tromey
2020-06-19 23:05 ` Pedro Alves
2020-07-21 19:39 ` Tom Tromey
2020-07-28 19:31 ` Tom Tromey
2020-08-13 12:15 ` Tom de Vries
2020-08-14 23:40 ` Joel Brobecker
2020-08-23 16:09 ` Joel Brobecker
2020-08-23 23:32 ` Pedro Alves
2020-08-24 20:04 ` Joel Brobecker
2020-09-02 14:45 ` Tom Tromey
2020-09-02 14:59 ` Joel Brobecker
2020-06-18 17:57 ` Tom Tromey
2020-01-14 22:13 ` [PATCH 3/3] Further simplify gdb BFD caching Tom Tromey
2020-01-23 22:30 ` Tom Tromey
2020-09-02 18:45 ` Tom Tromey
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=40fa6532-4440-d47b-63db-9485828c791f@redhat.com \
--to=palves@redhat.com \
--cc=cbiesinger@google.com \
--cc=eliz@gnu.org \
--cc=gdb-patches@sourceware.org \
--cc=tromey@adacore.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