[v2] ld/pdb: Report failures to write the PDB file
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
Commit Message
The streams of a PDB file are only written out when it is closed, so
ignoring the return value of bfd_close means that write errors go
unreported: ld leaves a truncated PDB file behind and exits
successfully.
ld/
* pdb.c (create_pdb_file): Check the return value of bfd_close.
---
bfd/coffcode.h | 5 +++--
ld/pdb.c | 9 ++++++++-
2 files changed, 11 insertions(+), 3 deletions(-)
Comments
On 02.10.2026 19:45, Oleg Tolmatcev wrote:
> The streams of a PDB file are only written out when it is closed, so
> ignoring the return value of bfd_close means that write errors go
> unreported: ld leaves a truncated PDB file behind and exits
> successfully.
I continue to agree this wants correcting, yet ...
> --- a/bfd/coffcode.h
> +++ b/bfd/coffcode.h
> @@ -4325,8 +4325,9 @@ coff_write_object_contents (bfd * abfd)
> but before header is written so we can update it to point to debug directory. */
> struct pe_tdata *pe = pe_data (abfd);
>
> - if (pe->build_id.after_write_object_contents != NULL)
> - (*pe->build_id.after_write_object_contents) (abfd);
> + if (pe->build_id.after_write_object_contents != NULL
> + && !(*pe->build_id.after_write_object_contents) (abfd))
> + return false;
... there's more to propagating failure here than just the PDB writing. The
hook first and foremost writes the build ID. Likely it was never a good idea
to ignore the return value here, but the description then needs to cover this
aspect. Alternatively ...
> --- a/ld/pdb.c
> +++ b/ld/pdb.c
> @@ -5407,7 +5407,14 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
> ret = true;
>
> end:
> - bfd_close (pdb);
> + if (!bfd_close (pdb))
> + {
> + einfo (_("%P: cannot write PDB file: %E\n"));
... this could remain to be a warning, as v1 had it, just that now ...
> + ret = false;
> + }
> +
> + if (!ret)
> + unlink_if_ordinary (pdb_name);
>
> htab_delete (strings.hashmap);
... you properly delete the broken file. Let me know your preference, I'm
happy to make edits while committing whichever way you prefer.
Jan
пн, 5 окт. 2026 г. в 10:26, Jan Beulich <jbeulich@suse.com>:
>
> On 02.10.2026 19:45, Oleg Tolmatcev wrote:
> > The streams of a PDB file are only written out when it is closed, so
> > ignoring the return value of bfd_close means that write errors go
> > unreported: ld leaves a truncated PDB file behind and exits
> > successfully.
>
> I continue to agree this wants correcting, yet ...
>
> > --- a/bfd/coffcode.h
> > +++ b/bfd/coffcode.h
> > @@ -4325,8 +4325,9 @@ coff_write_object_contents (bfd * abfd)
> > but before header is written so we can update it to point to debug directory. */
> > struct pe_tdata *pe = pe_data (abfd);
> >
> > - if (pe->build_id.after_write_object_contents != NULL)
> > - (*pe->build_id.after_write_object_contents) (abfd);
> > + if (pe->build_id.after_write_object_contents != NULL
> > + && !(*pe->build_id.after_write_object_contents) (abfd))
> > + return false;
>
> ... there's more to propagating failure here than just the PDB writing. The
> hook first and foremost writes the build ID. Likely it was never a good idea
> to ignore the return value here, but the description then needs to cover this
> aspect. Alternatively ...
>
> > --- a/ld/pdb.c
> > +++ b/ld/pdb.c
> > @@ -5407,7 +5407,14 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
> > ret = true;
> >
> > end:
> > - bfd_close (pdb);
> > + if (!bfd_close (pdb))
> > + {
> > + einfo (_("%P: cannot write PDB file: %E\n"));
>
> ... this could remain to be a warning, as v1 had it, just that now ...
>
> > + ret = false;
> > + }
> > +
> > + if (!ret)
> > + unlink_if_ordinary (pdb_name);
> >
> > htab_delete (strings.hashmap);
>
> ... you properly delete the broken file. Let me know your preference, I'm
> happy to make edits while committing whichever way you prefer.
>
> Jan
Thanks, I'd prefer to keep it an error.
Oleg
@@ -4325,8 +4325,9 @@ coff_write_object_contents (bfd * abfd)
but before header is written so we can update it to point to debug directory. */
struct pe_tdata *pe = pe_data (abfd);
- if (pe->build_id.after_write_object_contents != NULL)
- (*pe->build_id.after_write_object_contents) (abfd);
+ if (pe->build_id.after_write_object_contents != NULL
+ && !(*pe->build_id.after_write_object_contents) (abfd))
+ return false;
}
#endif
@@ -5407,7 +5407,14 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
ret = true;
end:
- bfd_close (pdb);
+ if (!bfd_close (pdb))
+ {
+ einfo (_("%P: cannot write PDB file: %E\n"));
+ ret = false;
+ }
+
+ if (!ret)
+ unlink_if_ordinary (pdb_name);
htab_delete (strings.hashmap);