Page MenuHomePhabricator

Provide a hook to customize missing library error handling

Authored by serge-sans-paille on Sep 16 2020, 6:09 AM.



It would be nice to be able to provide a custom script that would help users to find missing libraries. A possible scenario could be:

% clang /tmp/a.c -fuse-ld=lld -loauth -Wl,--error-handling-script=/tmp/
unable to find library -loauth
looking for relevant packages to provides that library

  • liboauth-0.9.7-4.el7.i686
  • liboauth-devel-0.9.7-4.el7.i686
  • liboauth-0.9.7-4.el7.x86_64
  • liboauth-devel-0.9.7-4.el7.x86_64
  • pix-1.6.1-3.el7.x86_64

Where addLibrary would be called with the missing library name as first argument (in that case oauth)

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
serge-sans-paille marked 5 inline comments as done.

Better error handling, more testing, take review into account.


I'm wondering why you prefer the string approach? I like the enum approach because it allows for compile-time checking, while nothing prevents someone from using an unsupported string.


But using push_back /emplace_back / insert implies a more complex machinery under the hood, while presizing the array + std::copy is easier on the generated code. But it implies some index/size book keeping so I understand your point and will change the code.

2 ↗(On Diff #294652)

I had to duplicate the test case, tried to forge a polyglot file... but that was a mess. I could also just echo "message" but I'd rather test the actual arguments, what do you think?

3 ↗(On Diff #294652)

It does, but is that pore portable?

Realease note + manpage update

jhenderson added inline comments.Oct 1 2020, 1:03 AM

Ping this. Have you considered the case where the error limit is hit and LLD exits? In that case the error handling script will not be called, which I don't think we want (we should call the script for each time an error is hit, not just each time except the last).


I don't have a strong argument either way, but one advantage of strings is precisely because it means there'll be no compile-time checking, making it easier to add new usages. However, the risk is that a call site will have a typo or similar - at least in the enum case, this point of failure is all in one place.


I'm not sure it indicates that to me at all. To me push/emplace_back is a standard way of creating a list of things at run time.


Sorry, maybe I caused confusion with my discussion of unsupported tags. I actually think unsupported tags should be allowed without an error being reported. Having thought more about it, I think that would work best if it's handled by the script. Thus a script can opt into or out of ignoring unsupported tags by returning non-zero for them or not.

The end result is that you can probably get away with deleting case 1.


How some variation of this for the default case:
"'" + errorHandlingScript + "': error handling script exited with code " + Twine(Res)

It's quite common for error messages to be prefixed with the file where the problem is, so perhaps the script could be the same. Also, I think it's useful to record the script's exit code in the error message.

You also need a test case for the default label, i.e. where the script exits with some non-zero exit code.

1 ↗(On Diff #295324)

Does this work with an extension other than .bat? It's fine either way, it's just that when I double-click the test in Windows when it has .bat as an extension, it runs the script, which isn't what I want!

Also, it might be worth naming this error-handling-script-windows.bat to make clear the distinction.

2 ↗(On Diff #294652)

Duplicate test case is the best way forward in this case, I think. We do similar things in other cases too.

3 ↗(On Diff #294652)

I believe lit special cases /dev/null to be the equivalent of an empty file stream. Certainly it's worked for me in the past.

serge-sans-paille marked 5 inline comments as done.Oct 6 2020, 5:55 AM
MaskRay added inline comments.Oct 6 2020, 2:40 PM

This needs to be the ELF Improvements section.


StringRef defaults to an empty string. Delete = "" @serge-sans-paille Perhaps create a thread on because not many people subscribe bugzilla..

You need a test case that shows what happens when the script returns a non-zero exit code.


Use FileCheck -D to make sure you get the script name right in the error message.


It's helpful to indent the spaces to make the checked-for text line up.


This looks like it's missing the script name?

Take review into account + add a document specifying the interface expected for the error handling script, so that binutils devs can use it as reference.

Looks like you missed context from the latest diff. It also looks like you didn't address my previous set of comments.


This needs to happen after the switch statement, or the original message won't be reported in the event of a non-zero exit code.

5–7 ↗(On Diff #296686)

(please reflow the suggestion)

16–17 ↗(On Diff #296686)

I don't think this paragraph is useful. I'd just delete it. The important bits of information in it are already mentioned elsewhere.

22 ↗(On Diff #296686)
29–30 ↗(On Diff #296686)
36 ↗(On Diff #296686)

This description looks stale to me.

serge-sans-paille marked 6 inline comments as done.

Update documentation and answer reviewers.

Development have started on ld side using the documentation bundled in that patch as reference.


The way I (tried to) address your comment issue was through aggregation of msg in the event of a non-zero exit code. That way there's always a single call to error whatever the error code.

22 ↗(On Diff #296686)

According to that's the way one introduces literal blocks in restructured text.

jhenderson added inline comments.Oct 13 2020, 5:35 AM

Oh, I missed that. Won't that result in only a single "error:" prefix though? The later lines will look a bit odd then, right?

For example:

error: some file: some error message error handling script failed to execute
MaskRay accepted this revision.Oct 13 2020, 10:06 AM

LGTM, but please wait for @jhenderson and Nick on binutils side:)


lowercase res

1 ↗(On Diff #297827)

If the SPHINX_EXECUTABLE cmake variable is set and SPHINX_OUTPUT_HTML is on, ninja docs-lld-html can build the doc. You can also use or similar tool too check whether the .rst renders nicely.

This revision is now accepted and ready to land.Oct 13 2020, 10:06 AM

Synchronize with binutils which also implements missing-symbol.

binutils implementation got commited recently;a=commit;h=23ae20f5e3afeeab9aa616c63ab3b357668476d5

Minor doc and format update

It looks like you've uploaded the wrong diff? Also, I'd recommend adding the missing symbol path in a separate patch, to keep this patch smaller.

Upload correct diff, with only the missing-lib part

jhenderson requested changes to this revision.Oct 20 2020, 12:44 AM

None of my most recent comments have been addressed. They need to be before I'm happy for this to land.

This revision now requires changes to proceed.Oct 20 2020, 12:44 AM
serge-sans-paille marked 10 inline comments as done.

Tackle (most of ?) @jhenderson comment

  • Change the way errors messages are formatted and aggregated, as pointed out
  • Update documentation
  • Use placeholder in testcase

Nearly there.

For some reason this patch doesn't seem to be triggering the pre-merge checks. @MaskRay, any idea why?


You might want to split these lines are they're getting quite long.


The message checked for here doesn't match what the script actually produces.

Split long test lines and update windows test

jhenderson accepted this revision.Nov 2 2020, 12:35 AM

Have you run this on Windows to confirm the Windows test works? If not, I can probably arrange to check that. LGTM once it's been checked.


FWIW, I prefer the format as indicated in my suggested edit, with the | on the first line, and the second line indented with a total of 3 spaces. This means that a user who is reading the first line doesn't need to check the next to see whether the command continues on the next line, whilst a user reading the second line can see from the indentation that it is a continuation of a sequence of commands from the previous line.

This revision is now accepted and ready to land.Nov 2 2020, 12:35 AM

Have you run this on Windows to confirm the Windows test works? If not, I can probably arrange to check that. LGTM once it's been checked.

Yeah, please do!

Update multi-line test formatting

jhenderson requested changes to this revision.Nov 2 2020, 5:26 AM

Requesting changes, since the test is failing on Windows. The problem is that Windows batch files print the command being run before actually running it, so the output is something like this:

C:\llvm\build\tools\lld\test\ELF>echo "script: info: called with missing-lib idontexist"
"script: info: called with missing-lib idontexist"
ld.lld: error: unable to find library -lidontexist

Note that this means the script message appears twice in the output, whilst the LLD error message appears after the second one, which means the CHECK-NEXT for the latter fails. To fix, you probably just want to add the line @echo off immediately before the current echo statement in the windows script.

This revision now requires changes to proceed.Nov 2 2020, 5:26 AM

@echo off in windows test.

jhenderson added inline comments.Nov 3 2020, 12:34 AM

This hasn't been addressed?


Nit: I'd add a blank line before this to make the script contents stand out from the lit and FileCheck stuff.

Update windows test file

jhenderson accepted this revision.Nov 3 2020, 1:37 AM

LGTM, thanks!

This revision is now accepted and ready to land.Nov 3 2020, 1:37 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 3 2020, 2:06 AM