This discussion is archived
7 Replies Latest reply: May 6, 2011 11:35 AM by 853416 RSS

Trying to catch on to using 'discover'

859872 Newbie
Currently Being Moderated
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 Newbie
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points