4 Replies Latest reply on Nov 26, 2009 11:44 PM by sss4749

    Strange bug resulting from linking

    GertWollny
      std::string::empty() may report an empty string

      Hi,

      when I compile the attached program with openCC, the resulting program reports the string to be empty, although it certainly is not as compiling the same program with g++ and running it prooves. 

      g++ creates the following code:

      if (a.empty())
       1e3:   48 8d 7d e0             lea    -0x20(%rbp),%rdi
       1e7:   e8 00 00 00 00          callq  1ec <main+0x64>
       1ec:   84 c0                   test   %al,%al
       1ee:   74 2a                   je     21a <main+0x92>

      openCC does: 

       if (a.empty())
        d6:   48 8d bd 60 fe ff ff    lea    -0x1a0(%rbp),%rdi
        dd:   e8 00 00 00 00          callq  e2 <main+0x80>
        e2:   85 c0                   test   %eax,%eax
        e4:   74 33                   je     119 <main+0xb7>

      i.e. openCC expects string.empty() to set the full 32 bit of  %eax to zero and g++ only requires the lower 8 bits %al to be set to zero.

      Since the return type of empty() is bool, and sizeof(bool) is 1 for openCC, the code should most certainly do the same as g++ and only test  %al.

      Best,

      Ger t

      #include <iostream> #include <string> #include <sstream> using namespace std; int main(int argc, char *args[]) { const string a("1.0*ssd"); if (a.empty()) cout << "boned: the string '" << a << "' is considered to be empty\n"; else { cout << "Live is good\n"; return 0; } bool second_try = a.empty(); if (second_try) cout << "Well, at least the compile sticks to his opinion.\n"; else cout << "Arrg, now its correct\n"; return 0; }

        • Strange bug resulting from linking
          dgilmore

          Thanks for reporting this issue, I see the same problem with SLES11, which comes with gcc 4.3.2.

          Note that our next release will support SLES11, but not by using the default g++/gcc library includes since our front end only 4.2 based.  We will be supplying our own include files and C++ standard libraries that are 4.2 base.

          Note that we reported similar ABI issue in the release notes:

          ReleaseNotes.txt:
          8. Known Issues and Limitations
          ===============================

          ...

           o The x86 Open64 compiler ABI is designed to be compatible with
             the GNU ABI.  However, recently an ABI incompatibility
             has been uncovered.

             The 64-bit ABI used by gcc assumes that the high order 32
             bits in %rax are undefined for a function that returns a
             32-bit quantity; thus the caller is responsible for
             converting %eax into a 64-bit value when the result is
             used as an operand to a 64-bit operation.
           
             The ABI used by the Open64 compiler assumes that a
             function that returns a 32-bit value will produce a
             64-bit extended result in %rax; thus no conversion is
             needed when the result is used in a 64-bit operation.
           
             In practice this incompatibility will produce bad results
             in rare situations. This issue will be addressed in a
             future release of the x86 Open64 compiler.

          --------------------------------------

          As your example shows, it is not just 32-bit values are not being properly handled, when later versions of g++ are being used.

          Note that we don't see this error on SLES11 SP2 or RHEL 5.3, since the library code for empty zero extends the result:

          (gdb) x/5i _ZNKSs5emptyEv
          0x316089b5e0 <_ZNKSs5emptyEv>: mov    (%rdi),%rax
          0x316089b5e3 <_ZNKSs5emptyEv+3>: cmpq   $0x0,-0x18(%rax)
          0x316089b5e8 <_ZNKSs5emptyEv+8>: sete   %al
          0x316089b5eb <_ZNKSs5emptyEv+11>: movzbl %al,%eax
          0x316089b5ee <_ZNKSs5emptyEv+14>: retq  

          Your running on Ubuntu 9 right?  What version of the g++ are you using?

          Doug

            • Strange bug resulting from linking
              GertWollny

              openCC uses g++-4.2, but libstdc++ is most likely the version that comes with and is compiled with g++-4.3 since this is the standard c++ compiler.

              The g++ compile was done using version 4.2.

              ================================

              Out of curiosity: When you provide your own set of libraries, how do you ensure that using pre-compiled libraries with dependencies on the system provided stdc++ will not result in conflicting symbols?

               

                • Strange bug resulting from linking
                  dgilmore

                  Sorry for the late response.

                  Note that the major revision numbers of libstdc++.so hasn't changed so the interface as far as g++ is concerned hasn't changed.

                  Fortunately we have fixed this ABI incompatibility in the compiler that we are just about to release, so there shouldn't be, at least WRT this issue, any problem.

                  Thanks for reporting this problem, otherwise we probably won't have addressed the issue in time for the release.

                  Doug

                • Strange bug resulting from linking
                  sss4749

                  thanks you code