Re: libtool, llvm-gcc, failing C++ exceptions

2010-01-10 Thread Ralf Wildenhues
Hi Bob,

* Bob Friesenhahn wrote on Sat, Jan 09, 2010 at 08:03:11PM CET:
 On Sat, 9 Jan 2010, Ralf Wildenhues wrote:
 We can only find out better if we have small examples to look at.
 Here is a proposed patch to try exception handling in libraries and
 modules.  Tested with g++ on GNU/Linux; it will certainly need fixes
 for other systems, and Libtool may as well.
 
 I'd appreciate a look over it for any obvious glitches, before I commit
 it.
 
 My main comment is that it would be useful if the thrown class is
 derived from std:exception (or one of its standard derived classes)
 in order to flush out any issues which may stem from possible
 partial template instantiation in libstdc++ (or pre-compiled
 headers) as well as in the test translation unit.

OK, sounds useful.  Would that entail more than just something like
this incremental addition?


diff --git a/tests/exceptions.at b/tests/exceptions.at
index d551cb8..77a94c1 100644
--- a/tests/exceptions.at
+++ b/tests/exceptions.at
@@ -29,7 +29,8 @@ AT_KEYWORDS([libltdl])
 CPPFLAGS=$LTDLINCL $CPPFLAGS
 
 AT_DATA([module.h],
-[[class modexc { };
+[[#include exception
+class modexc : public std::exception { };
 extern C int modfoo () throw (modexc);
 ]])
 
@@ -57,7 +58,8 @@ int modfoo (void) throw (modexc)
 ]])
 
 AT_DATA([lib.h],
-[[class libexc { };
+[[#include exception
+class libexc : public std::exception { };
 int libfoo () throw (libexc);
 ]])
 
@@ -87,10 +89,11 @@ AT_DATA([main.cpp],
 [[#include ltdl.h
 #include cstdlib
 #include iostream
+#include exception
 #include lib.h
 #include module.h
 
-class exc { };
+class exc : public std::exception { };
 
 int foo (void) throw (exc)
 {





Re: [PATCH] Enable runtime cwrapper debugging; add tests

2010-01-10 Thread Charles Wilson
Ralf Wildenhues wrote:
 * Charles Wilson wrote on Mon, Jun 22, 2009 at 03:50:42AM CEST:
 * libltdl/config/ltmain.m4sh (func_emit_cwrapperexe_src)
 [ltwrapper_debugprintf]: Renamed to...
 
 I think functions should still be put in (parens) in the ChangeLog
 entry, not in [brackets], according to GCS.

What about C functions that are emitted in a HERE document as part of
the execution of a SH function?  That's the distinction I was trying to
draw with the variant enclosures.

How about:

* libltdl/config/ltmain.m4sh
(func_emit_cwrapperexe_src:ltwrapper_debugprintf): Renamed to...
(func_emit_cwrapperexe_src:lt_debugprintf): this. Only

 [lt_debugprintf]: this. Only print messages if lt_debug != 0.
 [file scope]: Add constants and variables to support new --lt-debug
 option. Remove LTWRAPPER_DEBUGPRINTF macro.
 [main]: Consolidate option parsing. Ensure first use of lt_debugprintf
 occurs after option parsing. Add stanza to parse for --lt-debug and
 set lt_debug variable.
 [all]: Use lt_debugprintf () instead of LTWRAPPER_DEBUGPRINTF (()).
 * tests/cwrapper.at: Add new tests for --lt-debug and -DLT_DEBUGWRAPPER.

 The testsuite additions fail on GNU/Linux (with the respective patch for
 the shell wrapper applied), for several reasons, the first two of which
 are not fixed by your patch update:
 
 - the program is actually .libs/lt-usea there, (but it might also be
   .libs/usea, or just usea on other systems),

See next item.

 - the shell wrapper outputs 'lt_argv_zero' not 'argv[0]' in its debug
   output,

Actually, the problem is this: the binary wrapper does the following
(end of long lines deleted; unimportant lines deleted):

(main) argv[0]  : ./bmp2tiff
(main) program_name : bmp2tiff
(find_executable)   : ./bmp2tiff
(check_executable)  : [snipped]
(main) found exe (before symlink chase) at : [snipped]
checking path component for symlinks: ...
...
(main) found exe (after symlink chase) at : [snipped]
(main) libtool target name: bmp2tiff.exe
(lt_setenv) setting 'BIN_SH' to 'xpg4'
(lt_setenv) setting 'DUALCASE' to '1'
(lt_update_lib_path) modifying 'PATH' by prepending [snipped]
(lt_setenv) setting 'PATH' to [snipped]
(lt_update_exe_path) modifying 'PATH' by prepending [snipped]
(lt_setenv) setting 'PATH' to[snipped]
(main) lt_argv_zero : /full/path/to/./.libs/bmp2tiff.exe
(main) newargz[0]   : /full/path/to/./.libs/bmp2tiff.exe
(main) newargz[1]   : --help


While the shell wrapper only prints the last bit (and doesn't show both
lt_argz_zero and argv[0], because we really don't have access to any
data inside the shell or child process to determine if they WERE different).

$ ./bmp2tiff --lt-debug --help
(main) lt_argv_zero : /full/path/to/.libs/bmp2tiff
(main) newargz[1]   : --help

However, these precise details are not what that test is supposed to be
checking.  We're really only trying to determine that the debug output
HAPPENS, not what it IS.  I think the right approach is to modify both
the shell wrapper and C wrapper so that the FIRST thing they output, if
--lt-debug, is some unique magic. Maybe:

libtool wrapper (GNU libtool 1.3110 2009-07-01) 2.2.7a

(or maybe)

foo:lt-foo.c:25: libtool wrapper (GNU libtool 1.3110 2009-07-01) 2.2.7a

and then modify the test to check for that, instead of worrying about
platform idiosyncratic stuff like /-vs-\, [.exe], or [lt-].  I prefer
the former, but I don't really care. See GCS discussion below.

 - the cwrapper debugging activated at compile time, tested in the second
   half of cwrapper.at, does not enable debugging for the shell wrapper.

Hmm, ok. That's easy enough to fix.

 On w32 systems, the patch changes the API of many (but not all)
 uninstalled programs generated by libtool: those which get a cwrapper.
 The semantics of when a program gets a cwrapper is currently not
 documented, but you have posted another patch for this, so let's discuss
 this with that patch.

Right.

 More nits below.
 
 Thanks.  Apologies for the immense delay.
 
 --- a/libltdl/config/ltmain.m4sh
 +++ b/libltdl/config/ltmain.m4sh
 
 @@ -2881,6 +2873,7 @@ void lt_update_exe_path (const char *name, const char 
 *value);
  void lt_update_lib_path (const char *name, const char *value);
  char **prepare_spawn (char **argv);
  void lt_dump_script (FILE *f);
 +
 
 No need for this hunk.

Ack.

  EOF
  
  cat EOF
 @@ -2932,6 +2925,10 @@ static const size_t opt_prefix_len = 
 LTWRAPPER_OPTION_PREFIX_LENGTH;
  static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
  
  static const char *dumpscript_opt   = LTWRAPPER_OPTION_PREFIX 
 dump-script;
 +static const size_t dumpscript_opt_len  = LTWRAPPER_OPTION_PREFIX_LENGTH + 
 11;
 
 Why are we using these _len variables and strncmp in this code again?
 strcmp is fine and safe and portable and used already, and strncmp is
 needed only for the test of an unknown option in our domain, no?

OK. I was trying to prepare the way for a possible later improvement,
where we allow users to 

Re: [PATCH] Enable runtime cwrapper debugging; add tests

2010-01-10 Thread Charles Wilson
Ralf Wildenhues wrote:
 That's not how these ancient shells work.
[snip long explanation]

Oh, that's just...evil.  How could that EVER have been expected to work
properly, except in the most trivial of scripts?

 Oh yeah...ping? Is the HPUX problem a blocker for these three patches,
 
 No.

Good!

 or can they be considered before solving the HPUX issue?
 
 In any case, here's a quick-n-dirty set of test scripts to help narrow
 down the problem.  If someone with access to HPUX can unpack and run
 't.sh', and report back the results, we might be able to narrow down the
 cause of this problem. (Might need to change the shbang lines to use the
 same shell that's causing issues with libtool).
 
 The tests all pass with HP-UX /bin/sh and /bin/ksh.

Well, that's...good, I suppose. It means that the problem isn't
specifically in the fork/shell-func/HERE implementation, such that the
failure ALWAYS occurs.  But instead, it means that we have a race
condition or resource contention problem (where 'unique names' can be
considered a resource) -- or maybe my test case wasn't sufficiently
complex, and didn't capture the bug exposed by libtool-as-a-whole.

...
Unfortunately, I don't see a way to avoid this problem on HP/UX -- short
of requiring a less brain-dead shell.

1. every HERE document creates a temp file, whether that HERE document
   should or should not be emitted by the script.  If the script
   contains the magic EOF...EOF incantation even if it's inside an
   excluded block:
  if /bin/false; then
cat foo -EOF
blah blah
EOF
  fi
   We may not get a file named 'foo' but we WILL get a temp file, whose
   name we do not know, with the contents 'blah blah'.
2. there are only a limited number of unique temp file names
3. Sometimes these temp files don't get cleaned up. Eventually, we will
   try to reuse the temp file name of one of these non-cleaned pieces
   of litter. Boom.

We can't even pre-emptively clean up the temp files as the first line
of the script on HP/UX -- because we'd be cleaning up the ones
produced by parsing of THIS instance of the script -- some of which we
may actually need -- not to mention possibly others needed by other
in-progress instances.  What a mess.

--
Chuck




Re: libtool, llvm-gcc, failing C++ exceptions

2010-01-10 Thread Bob Friesenhahn

On Sun, 10 Jan 2010, Ralf Wildenhues wrote:


My main comment is that it would be useful if the thrown class is
derived from std:exception (or one of its standard derived classes)
in order to flush out any issues which may stem from possible
partial template instantiation in libstdc++ (or pre-compiled
headers) as well as in the test translation unit.


OK, sounds useful.  Would that entail more than just something like
this incremental addition?


I think that the virtual what() method needs to be provided or else 
you have only a partially implemented class:


class MyException : public std::exception
{
  public;
MyException() {}

  virtual const char *what() const throw()
  {
 return My message;
  }
};

But this is a better class to test with since it uses more standard 
library stuff and is therefore more likely to fail if something is 
wrong:


#include exception
#include string
class MyException : public std::exception
{
  public;
MyException(std::string str)
 : message(str)
{
}

  virtual const char *what() const throw()
  {
 return message.c_str();
  }

  private:
std::string message;
};

Which can be thrown with

  throw MyException(My message);

Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/