helpGNU Libtool - Support: sr #108558, libtool nm test does not really...

 
 

sr #108558: libtool nm test does not really work for W32 versions of nm

Submitted by:  LRN <lrn>
Submitted on:  Fri 02 May 2014 05:10:04 AM UTC  
 
Category: NonePriority: 5 - Normal
Severity: 3 - NormalStatus: Done
Privacy: PublicAssigned to: None
Open/Closed: OpenOperating System: Microsoft Windows

Add a New Comment (Rich MarkupRich Markup):
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Fri 09 May 2014 09:14:55 PM UTC, comment #10:

Patch pushed.

Cheers,
Peter

Peter Rosin <pekberg>
Project Member
Tue 06 May 2014 01:49:16 PM UTC, comment #9:

> I have attached a patch that does the safe-safe-safe version.
> Does it work for you?


Yes, it seems that it does.

LRN <lrn>
Tue 06 May 2014 01:30:21 PM UTC, comment #8:

I have attached a patch that does the safe-safe-safe version.
Does it work for you?

Cheers,
Peter

(file #31318)

Peter Rosin <pekberg>
Project Member
Fri 02 May 2014 01:48:19 PM UTC, comment #7:

Ok, something like this seems safer:

mkdir conftest.dir
case `"$tmp_nm" -B conftest.dir/nofile` in
conftest.dir/nofile)
blablabla
esac
rm -rf conftest.dir

But I don't know how non-GNU nm behaves, so the safe-safe-safe
version only does the above on MSYS...

Crap again.

Cheers,
Peter

Peter Rosin <pekberg>
Project Member
Fri 02 May 2014 01:45:57 PM UTC, comment #6:

> Crap.


How about just opening a file that is known to not to exist?

Alternatively, give nm a real file that is at least 1 byte long (binutils nm checks for filesize being < 1 and fails quietly; having 1 byte makes it say filename (which is what we want) and "File truncated").

LRN <lrn>
Fri 02 May 2014 01:33:20 PM UTC, comment #5:

Hmm, on second thought, that depends on MSYS (and MSYS2) still
thinking that an argument starting with more than two slashes
is a UNC path (or a switch). That might change if someone
points out that ///foo and /foo should be equivalent and that
Posix only considers //foo special and that command line
switches starting with /// are really uncommon... Relying on
corner cases in the MSYS argument conversion heuristics does
not seem to be a very good idea...

But maybe it's the best option anyway?

Maybe use ////dev/null, to handle a future MSYS stripping one
leading slash as it currently does for command line switches?

Then again, accidentally (or otherwise) creating an empty
C:\dev\null file does not seem totally unlikely, so maybe
using ////dev/null isn't so bright after all...

Crap.

Cheers,
Peter

Peter Rosin <pekberg>
Project Member
Fri 02 May 2014 12:10:40 PM UTC, comment #4:

>> Well, in MSYS2 you can simply do:
>> nm -B /dev/thisfilebetternotexistotherwiseyoullbeintrouble
>> and get satisfactory results (file name and 'No such file'
>> in the output).


>> Can't say anything about MSYS1, haven't used it for some time.


> That would also work on MSYS1.


> However, I had an idea. Anyone against using
> "$tmp_nm" -B ///dev/null
> everywhere? "///foo" and "/foo" should be equivalent according to
> Posix. We should still check for "/dev/null" in the output,
> methinks...


Neat! I like that.

LRN <lrn>
Fri 02 May 2014 08:25:47 AM UTC, comment #3:

> Well, in MSYS2 you can simply do:
> nm -B /dev/thisfilebetternotexistotherwiseyoullbeintrouble
> and get satisfactory results (file name and 'No such file'
> in the output).


> Can't say anything about MSYS1, haven't used it for some time.


That would also work on MSYS1.

However, I had an idea. Anyone against using
"$tmp_nm" -B ///dev/null
everywhere? "///foo" and "/foo" should be equivalent according to
Posix. We should still check for "/dev/null" in the output,
methinks...

Cheers,
Peter

Peter Rosin <pekberg>
Project Member
Fri 02 May 2014 08:12:54 AM UTC, comment #2:

I was not aware of the extent to which Cygwin is mangling
commandlines of pure-W32 programs it runs (since i don't
really use Cygwin; i do know it does some kind of conversion;
apparently, only in one direction). Evidently, it does not
replace /dev/null with nul. In which case - yes, this only
affects MSYS.

> It would be easier to work around this if the native MinGW nm
> reported some kind of error message involving 'NUL', so that
> the case pattern could be extended.

I can come up with a fix for binutils. However, upstreaming it
would be difficult, i expect. In fact i did make a patch: right
now my hack makes it open the file, feed the fd to isatty(), and if
it turns to not to be a real file, it checks whether its name
is "nul" and replaces that with "/dev/null", so the script gets
the output it expects. As you may imagine, this is never going to
be accepted upstream.

The isatty() part might be acceptable (though i expect someone
to point out that opening files may be a performance hit), and
in that case libtool can just check for 'nul'.

> Granted, that would not fix
> the bug for old tool chains, but the bug has existed for a very
> long time and you can always work around it with an explicit
> NM=...

Yes. Not only NM=..., but you can also let it fall back to
*-pc-msys-nm, which totally worked, and may even continue to
work for most users (which have matching MSYS and MinGW toolchains).

> The alternative is for libtool use some other non-existant
> or otherwise special file on MSYS, when it is trying to work out
> if nm supports -B. I don't know what that file would be though,
> and it always feels a little bit icky to special case things.


Well, in MSYS2 you can simply do:
nm -B /dev/thisfilebetternotexistotherwiseyoullbeintrouble
and get satisfactory results (file name and 'No such file'
in the output).

Can't say anything about MSYS1, haven't used it for some time.

LRN <lrn>
Fri 02 May 2014 07:55:14 AM UTC, comment #1:

Thanks for the report.

Just a quick note, Cygwin is not affected. This happens on
MSYS/MinGW only. On Cygwin, the Windows (or should I say DOS?)
NUL device is never involved.

cygwin$ /bin/nm -B /dev/null
/bin/nm: Warning: '/dev/null' is not an ordinary file
cygwin$ /bin/i686-pc-mingw32-nm -B /dev/null
/bin/i686-pc-mingw32-nm: Warning: '/dev/null' is not an ordinary file

If you have native MinGW tools and run libtool from Cygwin
(i.e. if you are using a 'fake' or 'lying' cross setup, as
described in the libtool manual), the test check succeeds
like this:

cygwin$ /cygdrive/c/MinGW/mingw/bin/nm -B /dev/null
C:\mingw\bin\nm.exe: '/dev/null': No such file

But you are quite correct that the test falls over on MSYS:

msys$ /mingw/bin/nm -B /dev/null
msys$ echo $?
1

It would be easier to work around this if the native MinGW nm
reported some kind of error message involving 'NUL', so that
the case pattern could be extended. Granted, that would not fix
the bug for old tool chains, but the bug has existed for a very
long time and you can always work around it with an explicit
NM=... The alternative is for libtool use some other non-existant
or otherwise special file on MSYS, when it is trying to work out
if nm supports -B. I don't know what that file would be though,
and it always feels a little bit icky to special case things.

Cheers,
Peter

Peter Rosin <pekberg>
Project Member
Fri 02 May 2014 05:10:04 AM UTC, original submission:

libtool.m4 contains the following code:

# Check to see if the nm accepts a BSD-compat flag.
# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
# nm: unknown option "B" ignored
# Tru64's nm complains that /dev/null is an invalid object file
case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
/dev/null | 'Invalid file or object type')
lt_cv_path_NM="$tmp_nm -B"
break 2
;;
*)
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
/dev/null)
lt_cv_path_NM="$tmp_nm -p"
break 2
;;
*)
lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
continue # so that we can try to find one that supports BSD flags
;;
esac
;;
esac

This does not work if `nm' in question is built for W32, because `/dev/null' gets mangled into `nul', and `nul' does not behave the same way (it can be stat()'ed successfully and looks like a zero-size file to stat()).
Even if binutils are patched to do a more thorough check (for example, stricmp (file_name, "nul") or && isatty(open (file_name, ...))), the file name reported in the error message is `nul', not `/dev/null', so the case statement here won't match.

AFAIU, this bug is as old as this code (which, i guess, makes it quite old), but it was masked by the fact that /usr/bin/nm (MSYS/Cygwin nm) does pass this test, and it's sufficiently compatible (for the purpose of parsing object files) for this not to matter.

Things start to blow up when MinGW nm and MSYS/Cygwin nm are not completely compatible (for example, when MinGW binutils and gcc are built with LTO support, and MSYS/Cygwin binutils&gcc are not).

LRN <lrn>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

Attached Files

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by pekberg (Posted a comment)
  • -unavailable- added by lrn (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 2 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Fri 09 May 2014 09:14:55 PM UTCpekbergStatusNone=>Done
    Tue 06 May 2014 01:30:21 PM UTCpekbergAttached File-=>Added 0001-libtool-fix-nm-test-for-MSYS-MinGW.patch, #31318

    Back to the top


    Powered by Savane 3.1-cleanup