7 Replies Latest reply: May 6, 2011 1:35 PM by 853416 RSS

    Trying to catch on to using 'discover'

    859872
      I am upgrading our Solaris C++ compilation system all the way from SolStudio v6 Update 2 on Solaris 8 to SolarisStudio 12.2 on Solaris 10. (About time, huh?) Things seem to be going well enough but am struggling with the included 'discover' tool. The documentation seems a bit short and its reported "errors" seem rather dubious - but, hey, you learn something every day (especially with C++ ... ;) )

      Suggestions would be appreciated.

      Here is a rather abbreviate example of the type of oddity I am getting. I am writing a small application to test a class named CNCTimeStamp. The class has a fair number of features, but it can be boiled down to this

      nctimestamp.h
      class CNCTimeStamp {
      public:
        CNCTimeStamp();
        virtual ~CNCTimeStamp();
      protected:
        time_t m_timestamp;
        mutable struct tm* m_tm;
      }; // class CNCTimeStamp
      nctimestamp.cpp
      CNCTimeStamp::CNCTimeStamp() :
           m_timestamp(0),
           m_tm(0)
      {
           ::time( &m_timestamp );
      } // CNCTimeStamp
      When I build it, using dmake, I get
      berlin{devel}528: dmake test1
      dmake: defaulting to parallel mode.
      See the man page dmake(1) for more information on setting up the .dmakerc file.
      nervecenter --> 1 job
      /opt/solstudio12.2/bin/CC -g -xO2 -I.. -c timetoy.cpp
      nervecenter --> 2 jobs
      /opt/solstudio12.2/bin/CC -g -xO2 -I.. -c ../nctimestamp.cpp
      nervecenter --> 1 job
      /opt/solstudio12.2/bin/CC -g -xO2 -o timetoy timetoy.o nctimestamp.o
      /usr/bin/file timetoy
      /usr/bin/ldd timetoy
      nervecenter --> Job output
      /opt/solstudio12.2/bin/CC -g -xO2 -o timetoy timetoy.o nctimestamp.o
      /usr/bin/file timetoy
      timetoy:        ELF 32-bit LSB executable 80386 Version 1 [FPU], dynamically linked, not stripped
      /usr/bin/ldd timetoy
              libCstd.so.1 =>  /usr/lib/libCstd.so.1
              libCrun.so.1 =>  /usr/lib/libCrun.so.1
              libm.so.2 =>     /usr/lib/libm.so.2
              libc.so.1 =>     /usr/lib/libc.so.1
      nervecenter --> 1 job
      /opt/solstudio12.2/bin/discover -b /opt/firefox4/firefox -H timetoy.html -w timetoy.txt -o timetoy.disc timetoy
      berlin{devel}529:
      All looks good so far. When I run "timetoy.disc", I get a multitude of "errors". The first is this, which shows enough in its source listing that you can see what's going on. My trouble is in grasping what an "SBR" is and how it would apply. Thoughts?

      I tried this, btw, replacing the "CNCTimeStamp* start = new CNCTimeStamp();" with "CNCTimeStamp start;" to no avail. Same SBR errors. I make no claim to being an expert with C++, but all this seems over the top. Fortunately, I am wrong most of time. LOL
      ERROR 1 (SBR): read from 0x8046ea0 (4 bytes) is beyond stack frame bounds at:
              CNCTimeStamp::CNCTimeStamp #Nvariant 1() + 0x36  <nctimestamp.cpp:37>
                      34:    // -------------------------------------------------------------------
                      35:    // Constructors
                      36:
                      37:=>  CNCTimeStamp::CNCTimeStamp() :
                      38:     m_timestamp(0),
                      39:     m_tm(0)
                      40:    {
              void nap(int) + 0xfa  <timetoy.cpp:11>
                       8:
                       9:    void nap( int naptime )
                      10:    {
                      11:=>           CNCTimeStamp* start = new CNCTimeStamp();
                      12:
                      13:     std::cout << *start << ". Start time." << std::endl;
                      14:
              main() + 0x86  <timetoy.cpp:48>
                      45:
                      46:     for ( int i = 0; i<argc; ++i )
                      47:     {
                      48:=>           nap( argc );
                      49:     }
                      50:
                      51:     timeplus( argc );
              _start() + 0x7c
      ERROR 2 (SBR): read from 0x8046ea0 (4 bytes) is beyond stack frame bounds at:
              CNCTimeStamp::CNCTimeStamp #Nvariant 1() + 0x5c  <nctimestamp.cpp:37>
                      34:    // -------------------------------------------------------------------
                      35:    // Constructors
                      36:
                      37:=>  CNCTimeStamp::CNCTimeStamp() :
                      38:     m_timestamp(0),
                      39:     m_tm(0)
                      40:    {
              void nap(int) + 0xfa  <timetoy.cpp:11>
                       8:
                       9:    void nap( int naptime )
                      10:    {
                      11:=>           CNCTimeStamp* start = new CNCTimeStamp();
                      12:
                      13:     std::cout << *start << ". Start time." << std::endl;
                      14:
              main() + 0x86  <timetoy.cpp:48>
                      45:
                      46:     for ( int i = 0; i<argc; ++i )
                      47:     {
                      48:=>           nap( argc );
                      49:     }
                      50:
                      51:     timeplus( argc );
              _start() + 0x7c
      ERROR 3 (SBR): read from 0x8046ea0 (4 bytes) is beyond stack frame bounds at:
              CNCTimeStamp::CNCTimeStamp #Nvariant 1() + 0x84  <nctimestamp.cpp:39>
                      36:
                      37:    CNCTimeStamp::CNCTimeStamp() :
                      38:     m_timestamp(0),
                      39:=>   m_tm(0)
                      40:    {
                      41:     ::time( &m_timestamp );
                      42:    } // CNCTimeStamp
              void nap(int) + 0xfa  <timetoy.cpp:11>
                       8:
                       9:    void nap( int naptime )
                      10:    {
                      11:=>           CNCTimeStamp* start = new CNCTimeStamp();
                      12:
                      13:     std::cout << *start << ". Start time." << std::endl;
                      14:
              main() + 0x86  <timetoy.cpp:48>
                      45:
                      46:     for ( int i = 0; i<argc; ++i )
                      47:     {
                      48:=>           nap( argc );
                      49:     }
                      50:
                      51:     timeplus( argc );
              _start() + 0x7c
      ERROR 4 (SBR): read from 0x8046ea0 (4 bytes) is beyond stack frame bounds at:
              CNCTimeStamp::CNCTimeStamp #Nvariant 1() + 0xac  <nctimestamp.cpp:39>
                      36:
                      37:    CNCTimeStamp::CNCTimeStamp() :
                      38:     m_timestamp(0),
                      39:=>   m_tm(0)
                      40:    {
                      41:     ::time( &m_timestamp );
                      42:    } // CNCTimeStamp
              void nap(int) + 0xfa  <timetoy.cpp:11>
                       8:
                       9:    void nap( int naptime )
                      10:    {
                      11:=>           CNCTimeStamp* start = new CNCTimeStamp();
                      12:
                      13:     std::cout << *start << ". Start time." << std::endl;
                      14:
              main() + 0x86  <timetoy.cpp:48>
                      45:
                      46:     for ( int i = 0; i<argc; ++i )
                      47:     {
                      48:=>           nap( argc );
                      49:     }
                      50:
                      51:     timeplus( argc );
              _start() + 0x7c
      ERROR 5 (SBR): read from 0x8046ea0 (4 bytes) is beyond stack frame bounds at:
              CNCTimeStamp::CNCTimeStamp #Nvariant 1() + 0xe4  <nctimestamp.cpp:41>
                      38:     m_timestamp(0),
                      39:     m_tm(0)
                      40:    {
                      41:=>   ::time( &m_timestamp );
                      42:    } // CNCTimeStamp
                      43:
                      44:    CNCTimeStamp::CNCTimeStamp( time_t timestamp ) :
              void nap(int) + 0xfa  <timetoy.cpp:11>
                       8:
                       9:    void nap( int naptime )
                      10:    {
                      11:=>           CNCTimeStamp* start = new CNCTimeStamp();
                      12:
                      13:     std::cout << *start << ". Start time." << std::endl;
                      14:
              main() + 0x86  <timetoy.cpp:48>
                      45:
                      46:     for ( int i = 0; i<argc; ++i )
                      47:     {
                      48:=>           nap( argc );
                      49:     }
                      50:
                      51:     timeplus( argc );
              _start() + 0x7c
      Thanks.
        • 1. Re: Trying to catch on to using 'discover'
          853416
          Hi,

          Thanks for the feedback.

          Discover relies on instrumenting executables and shared libraries, and often with C++ due to dependencies on libCstd.so, we may report false positives. We have fixed several C++ discover bugs in the to-be released version of discover. I'll take a look and will let you know what's going on here.

          In the mean time, you could safely assume that these errors are spurious false positives.

          Regards,
          Sheldon
          • 2. Re: Trying to catch on to using 'discover'
            859872
            I tried an experiment using CC's memory model settings ( -m32 and -m64 ). Then I use "-m32 -g -xO2" throughout the the compilation process, there is no change to what I wrote before. When I use "-m64 -g -xO2" things change, in an odd way.

            The make output looks like this.
            berlin{devel}548: make test1
            /opt/solstudio12.2/bin/CC -m64 -g -xO2 -I.. -c timetoy.cpp
            /opt/solstudio12.2/bin/CC -m64 -g -xO2 -I.. -c ../nctimestamp.cpp
            /opt/solstudio12.2/bin/CC -m64 -g -xO2 -o timetoy timetoy.o nctimestamp.o
            /usr/bin/file timetoy
            timetoy:        ELF 64-bit LSB executable AMD64 Version 1 [SSE FXSR CMOV FPU], dynamically linked, not stripped
            /usr/bin/ldd timetoy
                    libCstd.so.1 =>  /usr/lib/64/libCstd.so.1
                    libCrun.so.1 =>  /usr/lib/64/libCrun.so.1
                    libm.so.2 =>     /lib/64/libm.so.2
                    libc.so.1 =>     /lib/64/libc.so.1
            /opt/solstudio12.2/bin/discover -w timetoy.txt -o timetoy.disc timetoy
            ./timetoy.disc 1 1 1
            *** Signal 11 - core dumped
            make: Fatal error: Command failed for target `test1'
            berlin{devel}549: more /etc/release
                                    Solaris 10 5/09 s10x_u7wos_08 X86
                       Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
                                    Use is subject to license terms.
                                         Assembled 30 March 2009
            berlin{devel}550:
            Next step is to check what leads to the SEGV. To me, this looks like main() was never called. ?!
            berlin{devel}550: dbx ./timetoy.disc
            For information about new features see `help changes'
            To remove this message, put `dbxenv suppress_startup_message 7.8' in your .dbxrc
            Reading timetoy.disc
            Reading ld.so.1
            Reading libdiscover.so
            Reading libCstd.so.1
            Reading libCrun.so.1
            Reading libm.so.2
            Reading libc.so.1
            Reading libdl.so.1
            Reading libelf.so.1
            Reading libmd5.so.1
            Reading libthread.so.1
            Reading bitdl.so
            Reading libmapmalloc.so.1
            Reading libgen.so.1
            Reading bit_driver.so
            Reading libmd.so.1
            (dbx) run 1  2 3
            Running: timetoy.disc 1 2 3
            (process id 29484)
            t@null (l@1) signal SEGV (no mapping at the fault address) in _morecore at 0xfffffd7fff01623a
            0xfffffd7fff01623a: _morecore+0x007a:   movq     %rdi,(%rbx)
            dbx: read of 8 bytes at address 4 failed
            dbx: warning: No frame with source found
            (dbx) where
            dbx: read of 8 bytes at address 4 failed
            =>[1] _morecore(0x2803fe0, 0x2804000, 0x3, 0xfffffd7fff054f30, 0xffffffff, 0x0), at 0xfffffd7fff01623a
              [2] _malloc_unlocked(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff01588d
              [3] __sunos_malloc(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff0156f5
              [4] stack_init(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff013ca7
              [5] _init(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff0328a3
              [6] call_init(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff3ce13a
              [7] is_dep_init(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff3cde73
              [8] elf_bndr(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff3d9b3c
              [9] elf_rtbndr(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff3c2064
              [10] 0xfffffd7fff0902a8(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff0902a8
              [11] 0xfffffd7fff0902a8(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff0902a8
              [12] rt_thr_init(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x30761, 0x402840, 0x400000, 0x30761, 0xfffffd7fff3f0030, 0x4, 0x0, 0x0, 0x700000000, 0x0, 0x0, 0x0, 0xfffffd7fff3fcb40), at 0xfffffd7fff3ca2e9
              [13] setup(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff3cca42
              [14] _setup(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff3dae00
              [15] _rt_boot(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff3c1caf
              [16] 0xfffffd7fffdff0f0(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fffdff0f0
              [17] 0xfffffd7fffdff0f0(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fffdff0f0
              [18] 0xfffffd7fffdff149(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fffdff149
            (dbx)
            When I run the un-discover'd version "./timetoy 1 2 3 4 5", I do not get a SEGV and it runs without error. I only get this SEGV when running the discover'd binary.
            • 3. Re: Trying to catch on to using 'discover'
              859872
              Thanks Sheldon, I will ignore the SBRs.

              All of that, btw, was on an AMD Opteron processor, using a Sun Ultra 20 M2 Workstation.

              Moving all of this over to SPARC, I find that things clear up!
              blackeberg{devel}17: dmake test1
              dmake: defaulting to parallel mode.
              See the man page dmake(1) for more information on setting up the .dmakerc file.
              capricorn --> 1 job
              /opt/solstudio12.2/bin/CC -m32 -g -xO2 -I.. -c timetoy.cpp
              capricorn --> 2 jobs
              /opt/solstudio12.2/bin/CC -m32 -g -xO2 -I.. -c ../nctimestamp.cpp
              capricorn --> 1 job
              /opt/solstudio12.2/bin/CC -m32 -g -xO2 -o timetoy timetoy.o nctimestamp.o
              /usr/bin/file timetoy
              /usr/bin/ldd timetoy
              capricorn --> Job output
              /opt/solstudio12.2/bin/CC -m32 -g -xO2 -o timetoy timetoy.o nctimestamp.o
              /usr/bin/file timetoy
              timetoy:        ELF 32-bit MSB executable SPARC32PLUS Version 1, V8+ Required, dynamically linked, not stripped
              /usr/bin/ldd timetoy
                      libCstd.so.1 =>  /usr/lib/libCstd.so.1
                      libCrun.so.1 =>  /usr/lib/libCrun.so.1
                      libm.so.2 =>     /usr/lib/libm.so.2
                      libc.so.1 =>     /usr/lib/libc.so.1
                      /usr/lib/cpu/sparcv8plus/libCstd_isa.so.1
                      /platform/SUNW,Sun-Fire-V240/lib/libc_psr.so.1
              capricorn --> 1 job
              /opt/solstudio12.2/bin/discover -w timetoy.txt -o timetoy.disc timetoy
              ...
              blackeberg{devel}18:  cat timetoy.txt
              
              ***************** Discover Memory Report *****************
              No allocated memory left on program exit.
              DISCOVER SUMMARY:
                      unique errors   : 0 (0 total)
                      unique warnings : 0 (0 total)
              blackeberg{devel}19:  cat /etc/release
                                     Solaris 10 5/09 s10s_u7wos_08 SPARC
                         Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
                                      Use is subject to license terms.
                                           Assembled 30 March 2009
              blackeberg{devel}20: uname -a
              SunOS capricorn 5.10 Generic_141444-09 sun4u sparc SUNW,Sun-Fire-V240
              I get the same clean report for both "-m32" and "-64". How nice!

              Edited by: 856869 on May 5, 2011 3:11 PM
              • 4. Re: Trying to catch on to using 'discover'
                859872
                In the interest of helping out. I'll copy/paste here the makefile and source code. If it gets to be too long, I'll have to reply to this reply - and so on.

                There are four pieces: makefile, timetoy.cpp, nctimestamp.h and nctimestamp.cpp. The goal of this exercise has been to port the code base -this C++ class, CNCTimeStamp, is merely a first piece - up to the current Solaris Studio 12.2 C++ environment. At this point I am only using the command-line interface (dmake, dbx, CC). I hope to get to solstudio and dbxtool soon -- they look great!

                makefile
                CCC             = /opt/solstudio12.2/bin/CC
                DISCOVER        = /opt/solstudio12.2/bin/discover
                FILE            = /usr/bin/file
                LDD             = /usr/bin/ldd
                WEBBROWSER      = /opt/firefox4/firefox
                
                CC_OPTIMIZE     = -m32 -g -xO2
                
                timetoy: timetoy.o nctimestamp.o
                        $(CCC) $(CC_OPTIMIZE) -o $@ timetoy.o nctimestamp.o
                        $(FILE) $@
                        $(LDD) $@
                
                timetoy.disc: timetoy
                        $(DISCOVER) -w timetoy.txt -o $@ timetoy
                
                timetoy.o: timetoy.cpp
                        $(CCC) $(CC_OPTIMIZE) -I.. -c timetoy.cpp
                
                nctimestamp.o: ../nctimestamp.cpp
                        $(CCC) $(CC_OPTIMIZE) -I.. -c ../nctimestamp.cpp
                
                clean:
                        $(RM) timetoy
                        $(RM) timetoy.disc
                        $(RM) timetoy.o nctimestamp.o
                
                test1: timetoy.disc
                        ./timetoy.disc 1 1 1
                timetoy.cpp
                #include <iostream>
                #include <unistd.h>             // sleep(3C)
                #include <inttypes.h>           // int32_t
                #include "nctimestamp.h"
                
                void nap( int naptime )
                {
                        CNCTimeStamp* start = new CNCTimeStamp();
                
                        std::cout << *start << ". Start time." << std::endl;
                
                        sleep( naptime ); 
                
                        CNCTimeStamp* stop = new CNCTimeStamp();
                
                        time_t mynap = *stop - *start;
                
                        std::cout << *stop << ". That nap was " << mynap << " seconds long." << std::endl;
                
                        delete start;
                        start = 0;
                
                        delete stop;
                        stop = 0;
                } // nap
                
                void timeplus( time_t offset )
                {
                        CNCTimeStamp now;
                
                        time_t zoom = now.plus( offset );
                
                        CNCTimeStamp* future = new CNCTimeStamp( zoom );
                
                        std::cout << now << " plus " << offset << " is " << *future << std::endl;
                        delete future;
                }
                
                int main( int argc, const char* argv[] )
                {
                        int result = EXIT_SUCCESS;
                
                        for ( int i = 0; i<argc; ++i )
                        {
                                nap( argc );
                        }
                
                        timeplus( argc );
                
                        return result;
                } // main
                nctimestamp.h
                #ifndef _NCTIMESTAMP_H_
                #define _NCTIMESTAMP_H_
                
                #include <iostream>             // std:: ostream
                #include <string>               // std:: string
                #include <ctime>                // std:: time_t, struct tm
                
                #include <inttypes.h>           // int32_t
                
                // -------------------------------------------------------------------
                // Class CNCTimeStamp represents a single moment in time.
                //
                // Implementation:
                // 1. The class has two attributes, m_timestamp and m_tm.  The first,
                // m_timestamp, must always be maintained from contruction thru
                // to destruction.  The second, m_tm, is brought into use only
                // as needed; it is entirely secondary to m_timestamp.  The function
                // tm() is called to bring it into existance or return m_tm if it
                // is already created.
                // 2. Reliance on system calls is intentionally limited.  time(2)
                // is called only in the default constructor, which is the means
                // for the client to create an instance set to the present moment
                // in time.  localtime(3c) is used at the point when the m_tm
                // needs to be instantiated.
                
                class CNCTimeStamp {
                public: // Construction
                        CNCTimeStamp();
                                // Represents the current time.
                                // (The moment in time when the instance
                                // is created.)
                
                        CNCTimeStamp( time_t timestamp );
                                // Represents the moment set by 'timestamp'.
                
                        CNCTimeStamp( int year,
                                      int month,
                                      int day,
                                      int hour = 0,
                                      int minute = 0,
                                      int second = 0,
                                      bool* isDST = 0 );
                                // Represents the moment set by the params.
                
                        CNCTimeStamp( const struct tm& tm );
                                // Represents the moment set by the tm struct.
                
                        CNCTimeStamp( const CNCTimeStamp& other );
                                // Copy constructor.
                
                        virtual ~CNCTimeStamp();
                
                public:
                        const CNCTimeStamp& operator = ( const CNCTimeStamp& source );
                        const CNCTimeStamp& operator = ( time_t time );
                        const CNCTimeStamp& operator = ( const struct tm& tm );
                
                public: // Output
                        std::string YYYYMMDD_HHMMSS() const;
                        std::ostream& YYYYMMDD_HHMMSS( std::ostream& os ) const;
                                // Print the time as "yyyy-hh-mm hh-mm-ss"
                                // ex: "2010-01-31 13:59:03"
                
                public: // Conversion routines (public / static )
                        static struct tm* tm( time_t time);
                        static time_t time( struct tm* Tm );
                
                public: // Comparison
                        bool operator == ( const CNCTimeStamp& other ) const;
                        bool operator == ( time_t timestamp ) const;
                
                        bool operator != ( const CNCTimeStamp& other ) const;
                        bool operator != ( time_t timestamp ) const;
                
                        bool operator < ( const CNCTimeStamp& other ) const;
                        bool operator < ( time_t timestamp ) const;
                
                        bool operator <= ( const CNCTimeStamp& other ) const;
                        bool operator <= ( time_t timestamp ) const;
                
                        bool operator > ( const CNCTimeStamp& other ) const;
                        bool operator > ( time_t timestamp ) const;
                
                        bool operator >= ( const CNCTimeStamp& other ) const;
                        bool operator >= ( time_t timestamp ) const;
                
                public: // Comparison
                        int delta( const CNCTimeStamp& other ) const;
                                // The amount of time, in seconds, between this
                                // instance and the 'other'. The result can be
                                // positive (future) or negative (past) or
                                // zero (present).
                                //
                                // Ex: If both this and other are for the same
                                // minute in time, but 'this' is for the 30th
                                // second and 'other' is for the 44th second,
                                // then the delta is -14 seconds. As in, this
                                // instance is 14 seconds behind the 'other'.
                
                
                        static int delta( const CNCTimeStamp& first, const CNCTimeStamp& second );
                                // The amount of time, in seconds, between the
                                // 'first' and 'second' instances. The result can be
                                // positive (future) or negative (past) or
                                // zero (present).
                                //
                                // Ex: If both 'first' and 'second' are for the same
                                // minute in time, but 'first' is for the 3rd
                                // second and 'second' is for the 13th second,
                                // then the delta is -10 seconds. As in, the
                                // 'first' instance is 10 seconds behind the
                                // 'second'.
                
                public: // Operations (Addition / Subtraction)
                        time_t plus( time_t timespan ) const;
                        time_t operator + ( time_t timespan ) const;
                
                        time_t subtract( time_t timespan ) const;
                        time_t operator - ( time_t timespan ) const;
                
                        time_t subtract( const CNCTimeStamp& other ) const;
                        time_t operator - ( const CNCTimeStamp& other ) const;
                
                public: // Access
                        operator time_t() const;
                
                protected:
                        struct tm* tm() const;
                
                protected:
                        time_t m_timestamp;
                        mutable struct tm* m_tm;
                
                }; // class CNCTimeStamp
                
                std::ostream& operator<<( std::ostream& os, const CNCTimeStamp& timestamp );
                
                // -------------------------------------------------------------------
                // ###
                #endif // _NCTIMESTAMP_H_
                nctimestamp.cpp
                #include "nctimestamp.h"
                
                #include <iomanip>
                #include <iostream>
                #include <ctime>        // time_t mktime( struct std::tm* timeptr )
                
                // -------------------------------------------------------------------
                // Constructors
                
                CNCTimeStamp::CNCTimeStamp() :
                        m_timestamp(0),
                        m_tm(0)
                {
                        ::time( &m_timestamp );
                } // CNCTimeStamp
                
                CNCTimeStamp::CNCTimeStamp( time_t timestamp ) :
                        m_timestamp( timestamp ),
                        m_tm(0)
                {
                }
                
                CNCTimeStamp::CNCTimeStamp( int year,
                                            int month,
                                            int day,
                                            int hour,
                                            int minute,
                                            int second,
                                            bool* isDST ) :
                        m_timestamp(0),
                        m_tm(0)
                {
                        m_tm = new struct tm;
                        memset( m_tm, 0, sizeof( struct tm ) );
                        m_tm->tm_year = year - 1900;
                        m_tm->tm_mon = month - 1;
                        m_tm->tm_mday = day;
                        m_tm->tm_hour = hour;
                        m_tm->tm_min = minute;
                        m_tm->tm_sec = second;
                        m_tm->tm_wday = 0; // will be filled out by mktime()
                        m_tm->tm_yday = 0; // will be filled out by mktime()
                        if ( !isDST )
                                m_tm->tm_isdst = -1;
                        else
                                m_tm->tm_isdst = ( *isDST ) ? 1 : 0;
                
                        m_timestamp = mktime( m_tm );   // <ctime> function
                }
                
                CNCTimeStamp::CNCTimeStamp( const CNCTimeStamp& other ) :
                        m_timestamp( other.m_timestamp ),
                        m_tm(0)
                {
                }
                
                CNCTimeStamp::~CNCTimeStamp()
                {
                        if ( m_tm )
                        {
                                delete m_tm;
                                m_tm = 0;
                        }
                } // ~CNCTimeStamp
                
                //--------------------------------------------------------------------
                // operator =
                
                const CNCTimeStamp& CNCTimeStamp::operator = ( const CNCTimeStamp& source )
                {
                        if ( this != &source )
                        {
                                m_timestamp = source.m_timestamp;
                
                                if ( m_tm )
                                {
                                        delete m_tm;
                                        m_tm = 0;
                                }
                
                                if ( source.m_tm )
                                {
                                        m_tm = new struct tm( *source.m_tm );
                                }
                        }
                        return *this;
                } // operator =
                
                //--------------------------------------------------------------------
                // operator =
                
                const CNCTimeStamp& CNCTimeStamp::operator = ( time_t time )
                {
                        m_timestamp = time;
                
                        if ( m_tm )
                        {
                                delete m_tm;
                                m_tm = 0;
                        }
                
                        return *this;
                } // operator =
                
                //--------------------------------------------------------------------
                // operator =
                
                const CNCTimeStamp& CNCTimeStamp::operator = ( const struct tm& tm )
                {
                        if ( m_tm )
                        {
                                delete m_tm;
                                m_tm = 0;
                        }
                
                        m_tm = new struct tm( tm );
                
                        m_timestamp = mktime( m_tm );   // <ctime> function
                
                        return *this;
                } // operator =
                
                //--------------------------------------------------------------------
                // operator !=
                
                bool CNCTimeStamp::operator != ( const CNCTimeStamp& other ) const
                {
                        return ( m_timestamp != other.m_timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator ==
                
                bool CNCTimeStamp::operator == ( const CNCTimeStamp& other ) const
                {
                        return ( m_timestamp == other.m_timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator =
                
                bool CNCTimeStamp::operator != ( time_t timestamp ) const
                {
                        return ( m_timestamp != timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator =
                
                bool CNCTimeStamp::operator == ( time_t timestamp ) const
                {
                        return ( m_timestamp == timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator <
                
                bool CNCTimeStamp::operator < ( const CNCTimeStamp& other ) const
                {
                        return ( m_timestamp < other.m_timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator <
                
                bool CNCTimeStamp::operator < ( time_t timestamp ) const
                {
                        return ( m_timestamp < timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator <=
                
                bool CNCTimeStamp::operator <= ( const CNCTimeStamp& other ) const
                {
                        return ( m_timestamp <= other.m_timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator <=
                
                bool CNCTimeStamp::operator <= ( time_t timestamp ) const
                {
                        return ( m_timestamp <= timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator >
                
                bool CNCTimeStamp::operator > ( const CNCTimeStamp& other ) const
                {
                        return ( m_timestamp > other.m_timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator >
                
                bool CNCTimeStamp::operator > ( time_t timestamp ) const
                {
                        return ( m_timestamp > timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator >=
                
                bool CNCTimeStamp::operator >= ( const CNCTimeStamp& other ) const
                {
                        return ( m_timestamp >= other.m_timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // operator >=
                
                bool CNCTimeStamp::operator >= ( time_t timestamp ) const
                {
                        return ( m_timestamp >= m_timestamp ) ? true : false;
                }
                
                //--------------------------------------------------------------------
                // plus
                
                time_t CNCTimeStamp::plus( time_t timespan ) const
                {
                        return m_timestamp + timespan;
                } // plus
                
                //--------------------------------------------------------------------
                // operator +
                
                time_t CNCTimeStamp::operator + ( time_t timespan ) const
                {
                        return plus( timespan );
                } // operator +
                
                //--------------------------------------------------------------------
                // subtract
                
                time_t CNCTimeStamp::subtract( time_t timespan ) const
                {
                        return m_timestamp - timespan;
                } // subtract
                
                //--------------------------------------------------------------------
                // operator -
                
                time_t CNCTimeStamp::operator - ( time_t timespan ) const
                {
                        return subtract( timespan );
                } // operator -
                
                //--------------------------------------------------------------------
                // subtract
                
                time_t CNCTimeStamp::subtract( const CNCTimeStamp& other ) const
                {
                        return (m_timestamp - other.m_timestamp);
                } // subtract
                
                //--------------------------------------------------------------------
                // operator -
                
                time_t CNCTimeStamp::operator - ( const CNCTimeStamp& other ) const
                {
                        return subtract( other );
                } // operator -
                
                //--------------------------------------------------------------------
                // tm
                
                struct tm* CNCTimeStamp::tm() const
                {
                        if ( !m_tm )
                        {
                                m_tm = tm( m_timestamp );
                        }
                
                        return m_tm;
                } // tm
                
                //--------------------------------------------------------------------
                // tm
                
                struct tm* CNCTimeStamp::tm( time_t time )
                {
                        struct tm* result = new struct tm;
                        memset( result, 0, sizeof( struct tm ) );
                #if defined(__unix)
                        localtime_r( &time, result );
                #else
                        result = localtime( &time );
                #endif
                
                        return result;
                } // tm
                
                //--------------------------------------------------------------------
                // YYYYMMDD_HHMMSS
                
                std::string CNCTimeStamp::YYYYMMDD_HHMMSS() const
                {
                        struct tm* Tm = tm();
                #if 1
                        // format: "yyyy-mm-dd hh:mm:ss" which is a constant 19 chars.
                
                        char buffer[24];
                
                        sprintf( buffer, "%04d-%02d-%02d %02d:%02d:%02d",
                                 Tm->tm_year + 1900,
                                 Tm->tm_mon + 1,
                                 Tm->tm_mday,
                                 Tm->tm_hour,
                                 Tm->tm_min,
                                 Tm->tm_sec );
                
                        std::string result( buffer );
                        return result;
                #else
                        // This is slow at runtime. The problem is that it
                        // relies heavily on the heap for building up its
                        // value.
                
                        std::ostringstream result;
                        result << std::setfill('0')
                               << std::setw(4) << Tm->tm_year + 1900
                               << "-"
                               << std::setw(2) << Tm->tm_mon + 1
                               << "-"
                               << std::setw(2) << Tm->tm_mday
                               << " "
                               << std::setw(2) << Tm->tm_hour
                               << ":"
                               << std::setw(2) << Tm->tm_min
                               << ":"
                               << std::setw(2) << Tm->tm_sec;
                
                        return result.str();
                #endif
                } // YYYYMMDD_HHMMSS
                
                //--------------------------------------------------------------------
                // YYYYMMDD_HHMMSS
                
                std::ostream& CNCTimeStamp::YYYYMMDD_HHMMSS( std::ostream& os ) const
                {
                        os << YYYYMMDD_HHMMSS();
                        return os;
                } // YYYYMMDD_HHMMSS
                
                //--------------------------------------------------------------------
                // time
                
                time_t CNCTimeStamp::time( struct tm* tb )
                {
                        return mktime( tb );    // <ctime> function
                }
                
                //--------------------------------------------------------------------
                // operator time_t
                
                CNCTimeStamp::operator time_t() const
                {
                        return m_timestamp;
                } // operator std::time_t
                
                //--------------------------------------------------------------------
                // operator<<
                //      Note, there is no 'this' pointer within this function.  Also,
                //      ensure the feature 'YYYYMMDD_HHMMSS' is virtual for all descendents
                //      of CNCTimeStamp.
                
                std::ostream& operator<<( std::ostream& os, const CNCTimeStamp& timestamp )
                {
                        return timestamp.YYYYMMDD_HHMMSS( os );
                } // operator <<
                
                // -------------------------------------------------------------------
                // ###
                • 5. Re: Trying to catch on to using 'discover'
                  853416
                  Hi,

                  Thanks for the extremely detailed bug report.

                  I was able to reproduce your -m32 SBR false positives with the studio12.2 compiler, but these failures have been fixed in a studio12.2 patch. I believe patches are available for customers with support contracts.

                  Unfortunately, I was not able to reproduce your -m64 segv. I tried this on an Opteron as well, but it had an older Solaris 10 update version. Could you add the "-V" option to the compiler and discover commands, so I can accurately match the build ids?

                  Thanks again,
                  Sheldon
                  • 6. Re: Trying to catch on to using 'discover'
                    859872
                    Here's the '-V' info.

                    Opteron system

                    berlin{devel}503: CC -V
                    CC: Sun C++ 5.11 SunOS_i386 2010/08/13
                    usage: CC [ options ] files. Use 'CC -flags' for details
                    berlin{devel}504: discover -V
                    Sun Memory Error Discovery Tool 2.0 SunOS_i386 2010/08/13
                    berlin{devel}505: more /etc/release
                    Solaris 10 5/09 s10x_u7wos_08 X86
                    Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
                    Use is subject to license terms.
                    Assembled 30 March 2009
                    berlin{devel}506:

                    SPARC sytem

                    blackeberg{devel}1: CC -V
                    CC: Sun C++ 5.11 SunOS_sparc 2010/08/13
                    usage: CC [ options ] files. Use 'CC -flags' for details
                    blackeberg{devel}2: discover -V
                    Sun Memory Error Discovery Tool 2.0 SunOS_sparc 2010/08/13
                    blackeberg{devel}3: more /etc/release
                    Solaris 10 5/09 s10s_u7wos_08 SPARC
                    Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
                    Use is subject to license terms.
                    Assembled 30 March 2009
                    blackeberg{devel}4:
                    • 7. Re: Trying to catch on to using 'discover'
                      853416
                      Hi,

                      Thanks for the -V information.

                      Unfortunately I am still not able to reproduce your segv:

                      % cat /etc/release
                      Solaris 10 5/09 s10x_u7wos_08 X86
                      Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
                      Use is subject to license terms.
                      Assembled 30 March 2009
                      % /shared/dp/branches/aten/FCS/inst/intel-S2/bin/CC -m64 -g -xO2 -o timetoy.ss12.2fcs timetoy.cpp nctimestamp.cpp
                      timetoy.cpp:
                      nctimestamp.cpp:
                      % file timetoy.ss12.2fcs
                      timetoy.ss12.2fcs: ELF 64-bit LSB executable AMD64 Version 1 [SSE FXSR CMOV FPU], dynamically linked, not stripped
                      % /shared/dp/branches/aten/FCS/inst/intel-S2/bin/discover -w - -o timetoy.ss12.2fcs.disc timetoy.ss12.2fcs
                      % ./timetoy.ss12.2fcs.disc 1 1 1
                      2011-05-06 14:31:52. Start time.
                      ...
                      ERROR 1 (SBW): write to 0xfffffd7fffdff900 (8 bytes) is beyond stack frame bounds at:
                      ...

                      As you can see I do get a spurious SBW, but that too has been fixed in a patch.

                      Unfortunately, the days when we could say "try the latest patch" are over.

                      Best regards,
                      Sheldon