功峰's profile旋动家族PhotosBlogListsMore Tools Help

Blog


    September 18

    【翻译文章】如何升级基于STL的应用来支持Unicode

                                         

    翻译作者:dozb,Nicole

    译注:注意,本文仅仅适合于MSVC环境中STL库,对于STLPort有问题

    原作者:Taka Muraoka

    原出处:http://www.codeproject.com/vcpp/stl/upgradingstlappstounicode.asp

    介绍

    我最近升级一个想当大的程序,目的是用Unicode代替single-byte 字符。除了少数遗留下来的模块,我忠实地使用t-functions并且用_T()宏包裹我的字符串和字符常量,众所周知这能安全的转换成Unicode,我要做的事情是定义UNICODE 和 _UNICODE,我祈祷所有事情将如我所愿的工作。

    天啊,我是多么地错误:((

    因此,我写这篇文章是为了治疗两周工作之痛,并且希望解除其他人的痛苦,这痛苦是我已经经受的。唉...

    基础

    理论上,写出用single- 或 double-字节字符能被编译的代码是直接的。我曾经想在这里写一节,但是Chris Maunder 已经写了 done it. 他描述的技术是广为人知的,因此对理解这篇文章的内容非常有帮助。

    Wide 文件 I/O

    这里是stream类的wide版本,它容易地定义t-风格的宏去管理他们:

    你将像这样用它们:

    tofstream testFile( "test.txt" ) ; 
    testFile << _T("ABC") ;

    现在,你期待的结果是,当用single-byte 字符编译的时候,执行代码将生成3字节的文件,当用double-byte 字符编译的时候,执行代码将生成6字节的文件。但是你错了,都是3字节的文件。
    到底怎么啦?

    这渊源是标准C++的规定,wide流当写到 file。必须转换double-byte 到single-byte 。如上例,宽字符串L"ABC"(有6个字节长),当写到文件前,被转换成窄字符串(3字节)。更坏的情况,如何转换由库的实现来决定的( implementation-dependent)。

    我不能找出一个确切的解释,为什么事情会弄成这样子。我猜测,文件被定义为考虑作为字符(single-byte)流。若允许同时写2字节的字符将无法提取。不管对还是错,这都导致严重的问题。例如,你不能写二进制数据到wofstream,因为这个类试图在输出前先窄字符化它。

    这对我是明显的问题,因为我有大量的函数像这样写:

    void outputStuff( tostream& os )
    {
        // output stuff to the stream
        os << ....
    }

    假如你传递的是tstringstream 对象将没有问题(例如,它流出宽字符),但是假如你传递的是tofstream 将得到怪异的结果(因为所有内容都被窄化了)。

    Wide 文件 I/O: 解决方案

    用调试器单步跟踪STL,结果发现wofstream 在写输出到文件以前,调用std::codecvt 对象来窄化输出的数据。std::codecvt对象是造成字符串从一种字符集到另一种字符集转换的原因。C++要求作为标准提供:1、转换chars 到 chars(例如,费力地什么也不做),2、转换wchar_ts 到chars。后一种就是引起我们这么多伤心事的原因。

    解决方案:写一个新的继承自codecvt的类,用来转换wchar_ts 到 wchar_ts(什么也不做),绑定到wofstream 对象中。当wofstream 试图转换它所输出的数据时,它将调用我们新的codecvt 对象,实际上什么也不做,不改变地写输出数据。

    在google groups浏览找一些P. J. Plauger写的代码 code (是MSVC环境中STL库的作者),但是用 Stlport 4.5.3 编译还是有问题。 这是最后敲定的版本:

    #include 
    
    // nb: MSVC6+Stlport can't handle "std::"
    // appearing in the NullCodecvtBase typedef.
    using std::codecvt ; 
    typedef codecvt < wchar_t , char , mbstate_t > NullCodecvtBase ;
    
    class NullCodecvt
        : public NullCodecvtBase
    {
    
    public:
        typedef wchar_t _E ;
        typedef char _To ;
        typedef mbstate_t _St ;
    
        explicit NullCodecvt( size_t _R=0 ) : NullCodecvtBase(_R) { }
    
    protected:
        virtual result do_in( _St& _State ,
                       const _To* _F1 , const _To* _L1 , const _To*& _Mid1 ,
                       _E* F2 , _E* _L2 , _E*& _Mid2
                       ) const
        {
            return noconv ;
        }
        virtual result do_out( _St& _State ,
                       const _E* _F1 , const _E* _L1 , const _E*& _Mid1 ,
                       _To* F2, _E* _L2 , _To*& _Mid2
                       ) const
        {
            return noconv ;
        }
        virtual result do_unshift( _St& _State , 
                _To* _F2 , _To* _L2 , _To*& _Mid2 ) const
        {
            return noconv ;
         }
        virtual int do_length( _St& _State , const _To* _F1 , 
               const _To* _L1 , size_t _N2 ) const _THROW0()
        {
            return (_N2 < (size_t)(_L1 - _F1)) ? _N2 : _L1 - _F1 ;
        }
        virtual bool do_always_noconv() const _THROW0()
        {
            return true ;
        }
        virtual int do_max_length() const _THROW0()
        {
            return 2 ;
        }
        virtual int do_encoding() const _THROW0()
        {
            return 2 ;
        }
    } ;

    你能看得出这些函数都是空架子,实际上什么也不做,仅仅返回noconv 指示而已。

    剩下要做的仅仅是把其实例化,并连接到wofstream 对象中。用MSVC,假定你用_ADDFAC() 宏(非标准的)来imbue一个locale到对象。可是它不能和我的新的NullCodecvt类工作,因此我绕过这个宏,写一个新的来代替:

    #define IMBUE_NULL_CODECVT( outputFile ) \
    { \
        NullCodecvt* pNullCodecvt = new NullCodecvt ; \
        locale loc = locale::classic() ; \
        loc._Addfac( pNullCodecvt , NullCodecvt::id, NullCodecvt::_Getcat() ) ; \
        (outputFile).imbue( loc ) ; \
    }

    好,上面给出的不能好好工作的例子代码,现在能这样写:

    tofstream testFile ;
    IMBUE_NULL_CODECVT( testFile ) ;
    testFile.open( "test.txt" , ios::out | ios::binary ) ; 
    testFile << _T("ABC") ;

    重要的是必须是在打开文件前,文件流对象要用新的codecvt对象imbue。文件也必须用binary模式打开。假如不是这种模式,每次文件看一个宽字符的高位或低位是10的时候,它将进行既定的CR/LF翻译,结果不是你想要的。假如你真的想要CR/LF序列,你可以明确地插入"\r\n"来代替std::endl。

    wchar_t 问题

    wchar_t 是宽字符的类型,其定义如下:

    typedef unsigned short wchar_t ;

    不幸的是,因为它用typedef 代替真正的C++类型,这样定义有一个棘手的缺点:你不能重载它。看下面的代码:

    TCHAR ch = _T('A') ;
    tcout << ch << endl ;

    用窄字符串,正如你期望的:打印出字符A。用宽字符,它打印出65。编译器决定出,你正在流出一个unsigned short 并且把它作为数字值来代替宽字符来打印它。哈哈!!!找出在你流出特别的字符的地方并修正它,比起贯串你整个代码的基础,这不是办法。我写了一个小函数,使得情况好一些:

    #ifdef _UNICODE
        // NOTE: Can't stream out wchar_t's - convert to a string first!
        inline std::wstring toStreamTchar( wchar_t ch ) 
                { return std::wstring(&ch,1) ; }
    #else 
        // NOTE: It's safe to stream out narrow char's directly.
        inline char toStreamTchar( char ch ) { return ch ; }
    #endif // _UNICODE    
    
    TCHAR ch = _T('A') ;
    tcout << toStreamTchar(ch) << endl ;

    Wide 异常类

    多数C++程序用异常来捕获错误的发生。不幸地,std::exception 被定义成这个样子:

    class std::exception
    {
        // ...
        virtual const char *what() const throw() ;
    } ;

    仅仅能捕获窄字符的错误信息。我曾经throw自己定义的或std::runtime_error的异常,因此我写了一个std::runtime_error 的版本如下:

    class wruntime_error
        : public std::runtime_error
    {
    
    public:                 // --- PUBLIC INTERFACE ---
    
    // constructors:
                            wruntime_error( const std::wstring& errorMsg ) ;
    // copy/assignment:
                            wruntime_error( const wruntime_error& rhs ) ;
        wruntime_error&     operator=( const wruntime_error& rhs ) ;
    // destructor:
        virtual             ~wruntime_error() ;
    
    // exception methods:
        const std::wstring& errorMsg() const ;
    
    private:                // --- DATA MEMBERS ---
    
    // data members:
        std::wstring        mErrorMsg ; ///< Exception error message.
        
    } ;
    
    #ifdef _UNICODE
        #define truntime_error wruntime_error
    #else 
        #define truntime_error runtime_error
    #endif // _UNICODE
    
    /* -------------------------------------------------------------------- */
    
    wruntime_error::wruntime_error( const wstring& errorMsg )
        : runtime_error( toNarrowString(errorMsg) )
        , mErrorMsg(errorMsg)
    {
        // NOTE: We give the runtime_error base the narrow version of the 
        //  error message. This is what will get shown if what() is called.
        //  The wruntime_error inserter or errorMsg() should be used to get 
        //  the wide version.
    }
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    wruntime_error::wruntime_error( const wruntime_error& rhs )
        : runtime_error( toNarrowString(rhs.errorMsg()) )
        , mErrorMsg(rhs.errorMsg())
    {
    }
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    wruntime_error&
    wruntime_error::operator=( const wruntime_error& rhs )
    {
        // copy the wruntime_error
        runtime_error::operator=( rhs ) ; 
        mErrorMsg = rhs.mErrorMsg ; 
    
        return *this ; 
    }
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    wruntime_error::~wruntime_error()
    {
    }
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    const wstring& wruntime_error::errorMsg() const { return mErrorMsg ; }

    (toNarrowString() 是一个小函数用来转换宽字符到窄字符,下面会给出). wruntime_error 简单地保存宽错误信息自身的一个拷贝,并且为适应有人调用what(),给出一个基于std::exception的窄版本。 我定义的异常类,如下:

    class MyExceptionClass : public std::truntime_error
    {
    public:
        MyExceptionClass( const std::tstring& errorMsg ) : 
                                std::truntime_error(errorMsg) { } 
    } ;

    最后的问题是我有大量的代码看起来如下: 

    try
    {
        // do something...
    }
    catch( exception& xcptn )
    {
        tstringstream buf ;
        buf << _T("An error has occurred: ") << xcptn ; 
        AfxMessageBox( buf.str().c_str() ) ;
    }

    我已经定义了一个std::exception的插入者,如下:

    tostream&
    operator<<( tostream& os , const exception& xcptn )
    {
        // insert the exception
        // NOTE: toTstring() converts a string to a tstring - defined below
        os << toTstring( xcptn.what() ) ;
    
        return os ;
    }

    问题是我的插入者调用what(),其仅仅返回窄版本的错误信息。但是假如错误信息包含外国字符,我想看他们在错误对话框。因此我重写了插入者如下:

    tostream&
    operator<<( tostream& os , const exception& xcptn )
    {
        // insert the exception
        if ( const wruntime_error* p = 
                dynamic_cast<const wruntime_error*>(&xcptn) )
            os << p->errorMsg() ; 
        else 
            os << toTstring( xcptn.what() ) ;
    
        return os ;
    }

    现在,它检测是否给的是一个宽异常类,假如是,流出宽错误信息。否则它用标准的窄错误信息取回。即使我可以专门用truntime_error起源的类在我的应用中,后面的情况仍然是重要的,因为STL或其他第三方库可以throw 来自std::exception的错误。

    其他各种问题

    • Q100639: 假如你在MFC中使用Unicode,你需要指定wWinMainCRTStartup 作为你的进入点(在你的Project Options中的Link页面里)。
    • 许多windows函数接受一个buffer来在里面返回其结果。buffer大小通常以字符多少指定,非字节。因此下面的代码用single-byte 编译的时候工作良好:
      // get our EXE name 
      TCHAR buf[ _MAX_PATH+1 ] ; 
      GetModuleFileName( NULL , buf , sizeof(buf) ) ;

      double-byte 字符的时候将发生错误。调用GetModuleFileName()需要这么写:

      GetModuleFileName( NULL , buf , sizeof(buf)/sizeof(TCHAR) ) ;
    • 假如你一个一个字节地处理文件的时候,你需要测试WEOF, 而不是 EOF。
    • 在发送前,HttpSendRequest() 接收一个字符串,用来指定附加的头绑定到HTTP请求。ANSI建造接收一个长度为-1的字符串意味着头字符是以NULL结束的。Unicode 建造需要字符串的长度必须明确提供。不要问我为什么。

    各种有用的东东

    最后,假如你做类似工作,一些小函数对你来说可能有用:

    extern std::wstring toWideString( const char* pStr , int len=-1 ) ; 
    inline std::wstring toWideString( const std::string& str )
    {
        return toWideString(str.c_str(),str.length()) ;
    }
    inline std::wstring toWideString( const wchar_t* pStr , int len=-1 )
    {
        return (len < 0) ? pStr : std::wstring(pStr,len) ;
    }
    inline std::wstring toWideString( const std::wstring& str )
    {
        return str ;
    }
    extern std::string toNarrowString( const wchar_t* pStr , int len=-1 ) ; 
    inline std::string toNarrowString( const std::wstring& str )
    {
        return toNarrowString(str.c_str(),str.length()) ;
    }
    inline std::string toNarrowString( const char* pStr , int len=-1 )
    {
        return (len < 0) ? pStr : std::string(pStr,len) ;
    }
    inline std::string toNarrowString( const std::string& str )
    {
        return str ;
    }
    
    #ifdef _UNICODE
        inline TCHAR toTchar( char ch )
        {
            return (wchar_t)ch ;
        }
        inline TCHAR toTchar( wchar_t ch )
        {
            return ch ;
        }
        inline std::tstring toTstring( const std::string& s )
        {
            return toWideString(s) ;
        }
        inline std::tstring toTstring( const char* p , int len=-1 )
        {
            return toWideString(p,len) ;
        }
        inline std::tstring toTstring( const std::wstring& s )
        {
            return s ;
        }
        inline std::tstring toTstring( const wchar_t* p , int len=-1 )
        {
            return (len < 0) ? p : std::wstring(p,len) ;
        }
    #else 
        inline TCHAR toTchar( char ch )
        {
            return ch ;
        }
        inline TCHAR toTchar( wchar_t ch )
        {
            return (ch >= 0 && ch <= 0xFF) ? (char)ch : '?' ;
        } 
        inline std::tstring toTstring( const std::string& s )
        {
            return s ;
        }
        inline std::tstring toTstring( const char* p , int len=-1 )
        {
            return (len < 0) ? p : std::string(p,len) ;
        }
        inline std::tstring toTstring( const std::wstring& s )
        {
            return toNarrowString(s) ;
        }
        inline std::tstring toTstring( const wchar_t* p , int len=-1 )
        {
            return toNarrowString(p,len) ;
        }
    #endif // _UNICODE
    
    /* -------------------------------------------------------------------- */
    
    wstring 
    toWideString( const char* pStr , int len )
    {
        ASSERT_PTR( pStr ) ; 
        ASSERT( len >= 0 || len == -1 , _T("Invalid string length: ") << len ) ; 
    
        // figure out how many wide characters we are going to get 
        int nChars = MultiByteToWideChar( CP_ACP , 0 , pStr , len , NULL , 0 ) ; 
        if ( len == -1 )
            -- nChars ; 
        if ( nChars == 0 )
            return L"" ;
    
        // convert the narrow string to a wide string 
        // nb: slightly naughty to write directly into the string like this
        wstring buf ;
        buf.resize( nChars ) ; 
        MultiByteToWideChar( CP_ACP , 0 , pStr , len , 
            const_cast(buf.c_str()) , nChars ) ; 
    
        return buf ;
    }
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    string 
    toNarrowString( const wchar_t* pStr , int len )
    {
        ASSERT_PTR( pStr ) ; 
        ASSERT( len >= 0 || len == -1 , _T("Invalid string length: ") << len ) ; 
    
        // figure out how many narrow characters we are going to get 
        int nChars = WideCharToMultiByte( CP_ACP , 0 , 
                 pStr , len , NULL , 0 , NULL , NULL ) ; 
        if ( len == -1 )
            -- nChars ; 
        if ( nChars == 0 )
            return "" ;
    
        // convert the wide string to a narrow string
        // nb: slightly naughty to write directly into the string like this
        string buf ;
        buf.resize( nChars ) ;
        WideCharToMultiByte( CP_ACP , 0 , pStr , len , 
              const_cast<char*>(buf.c_str()) , nChars , NULL , NULL ) ; 
    
        return buf ; 
    }

    September 11

    Windbg 使用指南 转

    debug常用命令解析:
    1 !address eax查看对应内存页的属性
    2 vertarget 显示当前进程的大致信息
    3 !peb 显示process Environment Block
    4 lmvm 可以查看任意一个dll的详细信息
     例如:0:026 lmvm msvcrt (deferred)表示察看msvcrt.dll的信息,但是没有加载
    symbol可以通过.reload命令来加载
     
    5.reload /!sym 加载符号文件
     
    6 lmf 列出当前进程中加载的所有dll文件和对应的路径
    0:018> lmf
     
    7 r 命令显示和修改寄存器上的值
    r命令显示和修改寄存器上的值
    0:018> r     显示寄存器的值
    0:018> r eax=0 修改了寄存器,把eax的值修改为0x0
     
    8 d命令显示esp寄存器指向的内存
    如下
    0:018>d esp
     
    用dd命令直接指定054efc14地址
    0:018>dd 054efc14 
    注意:第二个d表示DWORD格式,此外还有db(byte),du(Unicode),dc(char)等等。
    数据查看指令 d{a|b|c|d|D|f|p|q|u|w|W}
    d{b|c|d|D|f|p|q}
    分别是显示:
    byte&ASCII, double-word&ASCII,double-word,double-precision,float,pointer-sized,quad-word
    数据;
    DA
    用于显示ASCIIDU用于显示UNICODE
    BYB
    BYD,显示binaryBytebinaryDWORD
    补充一个DV,用于查看本地变量用的
    9 e命令可以用来修改内存地址
    跟d命令一样,e命令后面也可以跟类型后缀,比如ed命
    令表示用DWORD的方式修改。下面的命令把054efc14地址上的值修改为11112222。
    0:018>ed 054efc14 11112222
    修改后可以用dd命令来查看内存。
    0:018>dd 0543fc14 L4 L4参数指定内存区间的长度为4个DWORD,这样输出只有1行,
    而不是8行了。
     
    10s 命令用来搜索内存具体见help文档
    11!runaway 可以显示每一个线程的cpu消耗
    0:018> !runaway 结果如下:
     0:83c       0 days 0:00:00.406
     13:bd4       0 days 0:00:00.046
     10:ac8       0 days 0:00:00.046
     24:4f4       0 days 0:00:00.031
     上面输出的第一列是线程的编号和线程ID,后一列对应的是该线程在用户态模式中的
    总的繁忙时间。
     在该命令加上f参数,还可以看到内核态的繁忙时间,当进程内存占用率比较高的时候
    ,通过该命令可以方便的找到对应的繁忙线程。
     
    12 ~ 命令是用来切换目标线程
    0:018> ~ 可以显示线程的信息
    0:018> ~0s把当前的线程切换到0号线程,也就是主线程,切换后提示符会变为0:000.
    13 ~* 命令列出当前进程中的所有线程的详细信息
    14~*kb命令列出所有线程的堆栈
    15 k 命令用来显示当前线程的堆栈,如下
    0:018> k
    跟d命令一样,k后面也可以跟很多后缀,比如kb kp,kn,kv,kl等,这些后缀控制了
    显示的格式和信息。
    栈指令k[b|p|P|v]
    这四条指令显示的内容类似,但是每个指令都有特色,KB显示三个参数Kp显示所有的参数,但需要Full SymbolsPrivate PDBSymbols支持。KPKp相似,只是KP将参数换行显示了Kv用于显示FPO和调用约定KD,用于显示StackDump,在跟踪栈时比较有用。
    这些指令区分大小。

    16 u命令把指定地址上的代码翻译成汇编输出
    0:018> u 7739d023
    USER32!NtUserWaitMessage:
    7739d023 b84a120000       mov     eax,0x124a
    7739d028 ba0003fe7f       mov     edx,0x7ffe0300
    7739d02d ff12             call    dword ptr [edx]
    7739d02f c3               ret
    如果符号文件加载正确,可以用uf命令直接反汇编整个函数,比如uf USER32! NtUserWaitMessage
     
    17 x 查找符号的二进制地址如下
    0:018> x msvcr!printf
    77bd27c2 msvcrt!printf = <no type information>
    上面的命令找到了printf函数的入口地址在77bd27c2
     
    0:001> x ntdll!GlobalCounter
    7c99f72c ntdll!GlobalCounter = <no type information>
    上面的命令表示ntdll!GlobalCounter这个变量保存的地址是7c99f72c。
    注意:符号对应的是变量和变量所在的地址,不是变量的值,上面只是找到GlobalCounter这个变量的值是7c99f72,要找到变量的值,需要用d命令读取内存地址来获取。
     
    X命令还支持通配符,比如x ntdll !*命令列出ntdll模块中的所有的符号,以及对应的二进制地址。
     
    18 dds 打印内存地址上的二进制值
    同时自动搜索二进制值对应的符号。
    比如要看看当前**中保存了那些函数地址,就可以检查ebp指向的内存
    0:018>dds ebp
    0013ed98  0013ee24
    0013ed9c  75ecb30f BROWSEUI!BrowserProtectedThreadProc+0x44
    0013eda0  00163820
    0013eda4  0013ee50
    0013eda8  00163820
    0013edac  00000000
    0013edb0  0013ee10
    0013edb4  75ece83a BROWSEUI!__delayLoadHelper2+0x23a
    0013edb8  00000005
    0013edbc  0013edcc
    0013edc0  0013ee50
    0013edc4  00163820
    0013edc8  00000000
    0013edcc  00000024
    0013edd0  75f36d2c BROWSEUI!_DELAY_IMPORT_DESCRIPTOR_SHELL32
    0013edd4  75f3a184 BROWSEUI!_imp__SHGetInstanceExplorer
    0013edd8  75f36e80 BROWSEUI!_sz_SHELL32
    0013eddc  00000001
    0013ede0  75f3726a BROWSEUI!urlmon_NULL_THUNK_DATA_DLN+0x116
    0013ede4  7c8d0000 SHELL32!_imp__RegCloseKey <PERF> (SHELL32+0x0)
    0013ede8  7c925b34 SHELL32!SHGetInstanceExplorer
     
    这里dds命令从ebp指向的内存地址0013ed98开始打印,第一列是内存地址的值,第二列是地址上对应的二进制数据,第三列是二进制对应的符号。上面的命令自动找到了75ecb390f对应的符号是BROWSEUI!BrowserProtectedThreadProc +0x44.
     
    Com interface 和c++ vtable里面的成员函数都是顺序排列的。所以,dds命令可以方便的找到虚函数表中的具体的函数地址,比如用下面的命令可以找到OpaqueDatinfo类型中虚函数的实际函数地址。
    首先通过x命令找到OpaqueDataInfo虚函数地址
    0:000> x ole32!OpaqueDataInfo::vftable’
    7768265c ole32!OpaqueDataInfo::`vftable' = <no type information>
    77682680 ole32!OpaqueDataInfo::`vftable' = <no type information>
    接下来dds命令可以打印出虚函数表中的函数名字
    0:000> dds 7768265c
    19 .frame 命令在栈中切换以便检查局部变量
    要查看局部变量的需要如下:
    1查看线程的callstack
    0:018>knl
    00 0012f7a0 7c821c94 ntdll!KiFastSystemCallRet
    01 0012f7a4 7c836066 ntdll!NtRequestWaitReplyPort+0xc
    02 0012f7c4 77eaaba3 ntdll!CsrClientCallServer+0x8c
    03 0012f8bc 77eaacb8 kernel32!ReadConsoleInternal+0x1b8
    04 0012f944 77e41990 kernel32!ReadConsoleA+0x3b
     
    第一列的号称为Frame num,通过.frame命令就可以切换到对应的函数中检查局部变量,比如我们检查kernel32!ReadConsoleA,这个函数的frame num是4,于是,我们如下
    2 iframe切换到指定行号的函数中
    0:018> .frame 4
    3然后调用x显示当前frame的局部变量,比如这个函数中有两个局部变量pcls和rawptr
    0:018> x
    0012fced pcls = 0x0039ba80
    0012fcd8 rawptr = 0x0039ba80
     
    20 dt 格式化显示资料
    Dt命令格式化显示变量的资料和结构
    0:000> dt pcls
    Local var @ 0x12fce4 Type MyCls*
    0x0039ba80
       +0x000 str              : 0x00416648  "abcd"
       +0x004 inobj            : inner
    上面的命令打印出pcls的类型是MyCls指针,指向的地址是0x0039ba80,其中的两个class成员的偏移分别在+0和+4,对应的值在第2列显示。加上-b -r参数可以显示inner class和数组的信息:
    0:000> dt pcls -b -r
    Local var @ 0x12fce4 Type MyCls*
    0x0039ba80
       +0x000 str              : 0x00416648  "abcd"
       +0x004 inobj            : innner
          +0x000 arr              :  "abcd"
           [00] 97 'a'
           [01] 98 'b'
           [02] 99 'c'
           [03] 100 'd'
           [04] 0 ''
           [05] 0 ''
           [06] 0 ''
           [07] 0 ''
           [08] 0 ''
           [09] 0 ''
    对于任意的地址,也可以手动指定符号类型来格式化显示。比如把0x0039ba80地址上的数据用MyCls类型来显示:
    0:000> dt 0x0039ba80 MyCls
       +0x000 str              : 0x00416648  "abcd"
       +0x004 inobj            : innner
    21bp设定调试断点
     比如可以这样写:0:018>bp notepad!WinMain 在notepade的winmain函数处下断点
    断点的位置可以用符号来表示,如上,也可以直接用地址以及windbg的Pseudo_Register(虚拟寄存器)。比如,我们用$exentry表示进程的入口,那么可以用bp @$exentry在进程的入口设置断点,如果notepade的winmain的入口地址为01006420,那么断点也可以这么写
    Bp 01006420
    bp mysource.cpp:143` "j (poi(MyVar)”0n20) ''; 'g' "
    意思就是:当myvar的值等于0x20时,g命令继续执行
    下面一个设置条件断点
    0:001> bp exceptioninject!foo3 “k; .echo ‘breaks’ ; g”
    在exceptioninject!foo3上设置断点后,每次断下来后,先用k显示callstack,然后用.echo命令输出简单的字符串‘breaks’,最后g命令继续执行。
    下面看一个更复杂的设置条件断点的例子:
    ba w4 execptioninject!i ”j(poi(exceptioninject!i)<0n40) ‘.printf\”exceptioninject!i value is :%d\”,poi(exceptioninject!i); g’ ; ‘.echo stop!’ ”
    首先ba w4 exceptioninject!i 表示在修改exceptioninject!i这个全局变量的时候,停下来,
    j(judge)命令的作用就是对后面的表达式作条件判断如果为true,执行第一个单引号里面的命令,否则执行第2个单引号里面的命令。
    条件表达式是(poi(exceptioninject!i)<0n40),在windbg中excepioninject!i符号表示符号所在的内存地址,而不是符号的数值,相当于c语言的&操作符的作用,poi命令就是取这个地址上的值,相当于c语言的*操作符。所以这个条件判断的意思就是判断exceptioninject!i的值,是否小于十进制的40。如果为真,就执行第一个单引号,‘.printf\”exceptioninject!i value is :%d\”,poi(exceptioninject!i); g’,如果为假,就执行第二个单引号‘.echo stop!’
    第一个单引号里有三个命令,.printf .echo g。这里的printfc语言的printf函数语法一样,不过由于这个printf命令本身是在ba命令的双引号里面,所以需要用\来转义print中的引号。第一个引号的作用是:打印出当前exceptioninject!i的值,.echo命令换行 g命令继续执行
    第二个引号的作用就是显示stop,由于后面没有g命令,所以windbg会停下。
    22 bm 使用模式匹配设置断点
    这个功能需要符号表的支持,bm可以通过模式一次设置多个断点,比如
    bm mydriver!FastIO* 可以将所有与FastIO*模式匹配的函数下设置断点,比如FastIoRead ,FastIoWriter等函数都会被设置上断点。需要注意的是,bm命令需要full or export symbols支持。
    23 ba 对内存访问设置断点 break on access
    就是对于内存访问设置断点,对于在多核处理或者多核处理器调试的时候很有用,对于调试多线程也很有用,比如说,我们可以对一个全局变量设置断点,
    ba mydriver!gMonitoreedDevices , 如果你认为这个变量的值被莫名的修改了,相信通过ba设置的断点,你可以很快找到是谁修改的。
    也可以这样
    ba w4 0x4000000 "kb;g" 当0x4000000地址有写操作时,进入断点 。w表示类型为写 4表示长度为4个字节
    24 bl 列出所有的断点 break list
    25 bc 清除断点       break clear
    26 be 开启断点      break enable
    27 bd禁用断点       break disable
    以上提到的断点指令通过和j指令很容易形成条件断点,比如
    bp USER32!GetMessageW "r $t1=poi(esp+4);r $t2=poi(@$t1+4); j(@$t2 = 0x102 ) 'du @$t1+8 L2;gc';'gc'"
    这个条件断点,截取WM_CHAR消息,并将字符(包括中文)显示出来。
    条件断点的最简形式:bp Address "j (Condition) 'OptionalCommands'; 'gc' "
    Address是指令的地址,Condition是一个条件表达式,如果@eax=1,'OptionalCommands'是在断点被击中并且表达式成立时要执行的指令;gc指定是从一个条件断点返回,是不可少的一部分。
    28跟踪指令T,TA,TB,TC,WT,P,PA,PC
      T指令单步执行,在源码调试状态下,可指源码的一行,根据不同的选项也可以为一行ASM指令;
    TA
    单步跟踪到指定地址,如果没有参数将运行到断点处。
    TB
    执行到分支指令,分支指令包括calls, returns, jumps, counted loops, and while loops
    TC
    执行到Call指令
    WT Trace and Watch Data
    ,一条强大指令,对执行流程做Profile,执行一下看看结果吧
    P
    PAPC相信不用多做解释,大家也都明白了
    29源代码操作指令.lsflsclsllsp
    .指令打一个源文件,可以打开一个全路径的文件,也可以通过函数地址来打开并定位到源文件中函数的位置,如. –a myapp!main. j:\mydriver\mydriver.c
    lsf
    指定一个源文件为当前源文件,使用lsc可显示当前指定的源文件ls可显示源文件的代码。Lsf可以使用全路径,如果源路径已经设置,也可以直接指定源文件名称。如lsf mydriver.clsf j:\mydriver\mydriver.c
    lsc
    显示当前源文件
    ls
    显示当前源文件的代码,如ls 200显示第200
    l
    用于设置源文件选项
    lsp
    设置源文件行在调试时显示范围比如,显示当前行的前50,后50lsp 100
    但通常使用Windbg时,可以直接用Ctrl+O来打开并查看源文件
    30 查询符号
    kd> x nt!KeServiceDescriptorTable*
    8046e100 nt!KeServiceDescriptorTableShadow = <no type information>
    8046e0c0 nt!KeServiceDescriptorTable = <no type information>
    kd> ln 8046e100
    (8046e100)     nt!KeServiceDescriptorTableShadow     | (8046e140)     nt!MmSectionExtendResource
    Exact matches:
    nt!KeServiceDescriptorTableShadow = <no type information>
    31!gle 查看LastError
    32指定进制的形式0x/0n/0t/y 分别表示 16/10/8/2进制
    ? 0x12345678+0n10
    Evaluate expression: 305419906 = 12345682
    33!sym noice/quiet symbol prompts开关
    34.srcpath 设置源代码的路径
    35dv查看本地变量
    36!teb 显示当前线程的执行块(execution block
    37!peb 显示当前进程的执行块(execution block
    38ln[Address] 显示当前地址上的对象类型
    39!locks 显示死锁
    40!handle可以获取整个进程或者某一个handle的详细信息
    首先运行以下!handle,可以看到当前进程的每个一个handle的类型,以及统计信息
    0:002>!handle
    Handle 4
     Type      key
    Handle c
       Type     keyEvent
    …….
    然后找到一个key,查看详细信息
    0:001>!handle 4 f
    就会列出这个handle的详细信息。
    41!htrace命令检查操作句柄的历史记录
    !htrace命令可以打印出指定的handle的最近几次调用堆栈
    0:001>!htrace 384
    42!cs列出CriticalSection的详细信息
    43!threadpool能看到完成端口,线城池工作线程和timer回调占线程池的情况
    44.time 可以看到进程跑了多长时间
    45 !dso 查看当前线程中有哪些对象,分析泄露时用到
    46.dump保存进程的dump文件
    Dump文件是进程的内存镜像,可当在调试器中打开dump文件时,使用上面的命令检查,看到的结果跟用调试检查进程看到的一样
    .dump /ma c:\testdump.dmp
    这个命令把当前进程的镜像保存为c:\testdump.dmp,其中/ms参数表示dump的文件应该包含进程的完整信息。
    在windbg中,通过file—open---open Crash dump菜单打开dump文件进行分析。打开文件后,运行调试命令看到的信息和状态就是dump文件保存时进程的状态。通过dump文件能够方便的保存发生问题时进程的状态,方便事后分析。
    August 26

    C++的一些免费库

    • Linear Algebra
      • MTL, the Matrix Template Library. Dense and sparse matrices and vectors; banded, symmetric, triangular matrices; basic algorithms. C++.

                 矩阵模版库,紧密和稀疏矩阵、矢量,带状,对称、三角矩阵,基本算法(C++语言)

      • uBLAS, BLAS in C++ with expression templates.

                  表达式模版形式的 C++中的BLAS ,

      • tvmet, a C++ library for "tiny" vectors and matrices with expression templates.

                  小型矢量和矩阵的表达式模版

      • GMM++, generic C++ template library for sparse, dense and skyline matrices, with solvers from ITL.
      • MET, a C++ matrix library with expression templates, which eliminates the overhead of overloaded operators.
      • SL++, the Scientific Library project. Will provide matrices, random numbers, complex, quaternions, plotting, and FFTs. C++.

                 科学计算库,提供矩阵、随机数、复数、四元数,快速复利叶变换(C++语言)

      • Seldon, C++ library for linear algebra with BLAS interface. Many matrix types (sparse, symmetric, hermitian, etc.) are supported.

                  BLAS 线性代数接口,支持 稀疏,对称,共轭矩阵

      • ALP, linear and polynomial algebra. Vectors, matrices, polynomials.
      • SVMT: E. Robert Tisdale's proposal for a standard C++ Scalar, Vector, Matrix and Tensor Class Library (with implementation). Note: this is a proposal, not an official standard.
      • GNUSSL [ftp only], the GNU Scientific Software Library. Linear algebra and arrays. C++.
      • CPPLapack, C++ wrapper for BLAS and LAPACK.
      • Lapack++, C++ wrapper for BLAS and LAPACK.
      • IML++ A C++ template library for numerical iterative methods.
      • MV++ Numerical Matrix/Vector Classes in C++
      • SparseLib++ A library for sparse matrix computations, including the Sparse BLAS (Basic Linear Algebra Subprograms). C++.
      • ISIS++, an object-oriented framework for solving sparse linear systems of equations. C++.
      • ARPACK++, a C++ template library for solving large-scale standard and generalized eigenvalue problems.
      • The Template Numerical Toolkit (TNT) for linear algebra is a successor to the Lapack++, Sparselib++, IML++, and MV++ packages. Its goal is to integrate these ideas into a generic algorithmic library, supporting generic user-defined data types, and increasing its functionality. C++.
      • LinAlg, basic linear algebra and optimization classes. C++.
      • CAM C++ Class Library (Matrix, vector, and graphics classes)
      • Newmat, a C++ matrix library (docs, download)
      • CLHEP includes matrix classes, random number generators for the High Energy Physics (HEP) community. C++.
      • BPKIT, Block Preconditioning Toolkit for iterative solution of linear systems. Callable from C++, C, or FORTRAN.

    • Arrays and Images
      • POOMA II framework for scientific computing on sequential and parallel computers. Provides parallel arrays; fields, meshes, particles to come in version 2.1 (June 1999). C++.
      • The Blitz++ class library: Array and Vector classes which rival Fortran's performance. C++.
      • The AIPS++ Array and Image Classes (Astronomical Information Processing System). C++.
      • Daixtrose, a general-purpose expression template engine.
      • PETE, an expression templates library -- add expression templates to your own array class.
      • SCTL (BlueSail), C++, arrays, matrics, vectors, sparse, rotations.  
      • VIGRA, generic computer vision/image processing library.
      • CPPIMA A C++ image processing library
      • LIMP, Large Image Manipulation Program
      • Image Restoration and Inpainting, C++ library for image restoration.
      • valarray<Troy> [ftp only], approximation of the valarray<T> class described in Ch. 26 of the ANSI/ISO C++ Standard. Uses expression templates for efficient evaluation.
      • Image Understanding Environment (IUE), a DARPA project. C++.
      • WAILI, a wavelet transform library in C++.

    • Neural Networks, genetic algorithms, machine learning, data mining

    • High-Energy Physics and Quantum Chemistry

    • Multiprecision, arbitrary precision data types
      • NTL, arbitrary length integers, vectors/matrices/polynomials over integers and over finite fields.
      • EXTNUM, version of double which has the same number of mantissa bits as IEEE 754, but extends the exponent to have range from 10^-646456993 to 10^646456992.
      • CLN, an extensive number library. Arbitrary precision integer, float, rational, polynomials, complex, modular integers, transcendental functions, assembly language kernels for some CPUs.
      • MUNTL, Multiprecision unsigned number template library (C++).
      • MPFUN++, a multiple precision floating point computation package in C++.
      • LiDIA, A library for computational number theory. Provides a collection of highly optimized implementations of various multiprecision data types and time-intensive algorithms.
      • Apfloat, a C++ High Performance Arbitrary Precision Arithmetic Package
      • hfloat, An arbitrary precision package, optimized for very large (> 1000) (decimal) digit numbers.
      • fPoint, a C++ class which helps convert floating-point arithmetic to fixed-point arithmetic by recommending range and precision requirements.
      • doubledouble, a quad-precision (approximately 30 decimal place) floating point arithmetic class.

    • Differential Equations
      • Rheoolef, finite element environment in C++.
      • EXPDE, a C++ library for solving partial differential equations on semi-unstructured grids. Parallel.
      • PZ, a C++ library for finite elements. 1-3 dimensions with hp-adaptivity, continuous or discontinuous, variety of matrix formats.
      • MBDyn, multibody dynamics analysis in C++. Built-in parallelization via MPI/Metis.
      • P2MESH, 2D finite volume/finite elements, C++ library designed for fast prototyping of high-performance PDE solvers.
      • Femlisp, a Common Lisp framework for Finite Element Methods.
      • GETFEM++, a C++ finite element library, generic, arbitrary dimensions.
      • MOUSE, a C++ library for finite volume computations on unstructured grids.
      • DEAL, a C++ library for adaptive finite elements and error estimation. Supports SMPs.
      • ODE++, a class library for ordinary differential equations. Explicit and linear-implicit ODE systems, IVP and BVP parameters, various solvers (Runge-Kutta, multistep, BDF). [English] [Deutsch]
      • PETSc, object-oriented software for partial differential equations (programmed in C)
      • Diffpack, partial differential equations in C++. ($)
      • TIDE: Classes for Ordinary Differential Equations. Provides vectors and matrices, extrapolation integrator for ODEs, sparse matrix classes, eigenvalues, shooting for two point BVPs, nonlinear solver, continuation
      • BoxLib/CCSE Applications Suite (docs), a class library supporting adaptive mesh refinement (AMR) schemes for computational fluid dynamics.
      • OVERTURE, a C++ class library for solving PDEs in complicated domains. Includes adaptive mesh refinement and overlapping grids.
      • FEMLIB (ftp, www) A Finite Element package [ftp only] by Michael Tiller (BROKEN LINK, no longer supported)

    • Automatic differentiation and interval arithmetic
      • Gaol, C++ library for interval arithmetic. Includes methods for interval constraint solvers.
      • FADBAD-TADIFF, a C++ package for automatic differentiation using any arithmetic (double or interval) by operator overloading.
      • PROFIL/BIAS [English] [Deutsch], a C++ interval arithmetic class library.

    • Visualization

    • Graph Theory/Combinatorics
      • Boost Graph Library, a general purpose, generic C++ library for graph data structures and graph algorithms.
      • GTL, the Graph Template Library (C++).
      • LEDA, a C++ library for graph theory and combinatorial computing.

    • Language interoperability/scripting
      • CPPF77 (cppf77.zip), a utility for interfacing C++ and Fortran 77 programs.
      • Paul Dubois's code for interfacing Python and C++
      • SWIG, generates Perl, Python, Tcl, Java, Eiffel and Guile wrappers for C++ libraries.
      • SILOON (Scripting Interface Languages for Object-Oriented Numerics), toolkits and run-time support for building scripting interfaces to existing numerical codes in C, C++, and Fortran. Generates script bindings for Perl, Tcl, and Python.
      • Matwrap, a tool which generates C++ wrapper code for matrix-oriented scripting languages such as Matlab 5, Octave, and tela.

    • Transforms
      • FFTPACK++, a C++ wrapper for FFTPACK complex routines using LAPACK++ Matrix and Vector classes.
      • The FXT library of transforms. FFTs, Hartley, Number theoretic, Walsh, others coded in C++.

    • Optimization
      • COOOL, an object-oriented optimization library
      • OptSolve++, a C++ optimization library from Tech-X. (commercial)
      • StarFLIP, optimization library for combinatorial problems with fuzzy constraints (C++)
      • LM (Levenberg-Marquardt) implementation in Java for nonlinear least squares problems.

    • Miscellaneous
    • Tools
      • TAU (Tuning and Analysis Utilities), explicit instrumentation of C++ libraries for profiling and tracing. For both serial and parallel codes.


    Compilers
    • Compilers
      • KAI C++, an optimizing compiler from Kuck & Associates (now a division of Intel). Unfortunately, this product has been discontinued.
      • The free GCC (Gnu Compiler Collection) has a good C++ compiler which can be used under unix or windows (with CygWin).
      • Intel's C++ compiler.
      • The Portland Group C++ compiler
      • The MPC++, a massively parallel, message passing, meta-level processing C++.
      • Titanium (free), a dialect of Java for large-scale scientific computing.


      Commercial software
      • Diffpack, a development framework for multi-physics simulations (C++).
      • VectorSpace provides vs.lib (integrable/differentiable objects in C++) and fe.lib (an object-oriented finite element library).
      • NMath provides vector, matrix, complex numbers and math functions for the .NET platform (e.g. C#)
      • macstl, std::valarray implementation using SIMD opcodes (Altivec on PowerPC, SSE/SSE2 on Intel)
      • ExacMath library (quad and double-quad precision floating point math), from Floating Point Software.
      • Math.h++ and LAPACK.h++ from Rogue Wave Software, Inc (LAPACK.h++ is not the same package as Roldan Pozo's LAPACK++ listed above)
      • MtxVec, linear algebra/numerical library for Delphi and C++ Builder.
      • Extreme Optimization Library, numerical library for .NET
      • MAT<LIB> (Matlab compatible C++ Matrix Class Library)
      • C-XSC: A C++ Class Library for Extended Scientific Computing (A C++ interval methods class library)
      • Siscat, C++ software for scattered data approximation
      • JNL, A numerical language/library proposal for Java from Visual Numerics.
      • LIA,GIA,ICE libraries for interval methods in C++ from Delisoft Ltd. Includes interval arithmetic, global optimization, and solving nonlinear equations.
      • AMRES, a C++ library for financial analysis.
      Diffpack, a development framework for multi-physics simulations (C++).
    • VectorSpace provides vs.lib (integrable/differentiable objects in C++) and fe.lib (an object-oriented finite element library).
    • NMath provides vector, matrix, complex numbers and math functions for the .NET platform (e.g. C#)
    • macstl, std::valarray implementation using SIMD opcodes (Altivec on PowerPC, SSE/SSE2 on Intel)
    • ExacMath library (quad and double-quad precision floating point math), from Floating Point Software.
    • Math.h++ and LAPACK.h++ from Rogue Wave Software, Inc (LAPACK.h++ is not the same package as Roldan Pozo's LAPACK++ listed above)
    • MtxVec, linear algebra/numerical library for Delphi and C++ Builder.
    • Extreme Optimization Library, numerical library for .NET
    • MAT<LIB> (Matlab compatible C++ Matrix Class Library)
    • C-XSC: A C++ Class Library for Extended Scientific Computing (A C++ interval methods class library)
    • Siscat, C++ software for scattered data approximation
    • JNL, A numerical language/library proposal for Java from Visual Numerics.
    • LIA,GIA,ICE libraries for interval methods in C++ from Delisoft Ltd. Includes interval arithmetic, global optimization, and solving nonlinear equations.
    • AMRES, a C++ library for financial analysis.
    KAI C++, an optimizing compiler from Kuck & Associates (now a division of Intel). Unfortunately, this product has been discontinued.
  • The free GCC (Gnu Compiler Collection) has a good C++ compiler which can be used under unix or windows (with CygWin).
  • Intel's C++ compiler.
  • The Portland Group C++ compiler
  • The MPC++, a massively parallel, message passing, meta-level processing C++.
  • Titanium (free), a dialect of Java for large-scale scientific computing.

    Commercial software
    • Diffpack, a development framework for multi-physics simulations (C++).
    • VectorSpace provides vs.lib (integrable/differentiable objects in C++) and fe.lib (an object-oriented finite element library).
    • NMath provides vector, matrix, complex numbers and math functions for the .NET platform (e.g. C#)
    • macstl, std::valarray implementation using SIMD opcodes (Altivec on PowerPC, SSE/SSE2 on Intel)
    • ExacMath library (quad and double-quad precision floating point math), from Floating Point Software.
    • Math.h++ and LAPACK.h++ from Rogue Wave Software, Inc (LAPACK.h++ is not the same package as Roldan Pozo's LAPACK++ listed above)
    • MtxVec, linear algebra/numerical library for Delphi and C++ Builder.
    • Extreme Optimization Library, numerical library for .NET
    • MAT<LIB> (Matlab compatible C++ Matrix Class Library)
    • C-XSC: A C++ Class Library for Extended Scientific Computing (A C++ interval methods class library)
    • Siscat, C++ software for scattered data approximation
    • JNL, A numerical language/library proposal for Java from Visual Numerics.
    • LIA,GIA,ICE libraries for interval methods in C++ from Delisoft Ltd. Includes interval arithmetic, global optimization, and solving nonlinear equations.
    • AMRES, a C++ library for financial analysis.
    Diffpack, a development framework for multi-physics simulations (C++).
  • VectorSpace provides vs.lib (integrable/differentiable objects in C++) and fe.lib (an object-oriented finite element library).
  • NMath provides vector, matrix, complex numbers and math functions for the .NET platform (e.g. C#)
  • macstl, std::valarray implementation using SIMD opcodes (Altivec on PowerPC, SSE/SSE2 on Intel)
  • ExacMath library (quad and double-quad precision floating point math), from Floating Point Software.
  • Math.h++ and LAPACK.h++ from Rogue Wave Software, Inc (LAPACK.h++ is not the same package as Roldan Pozo's LAPACK++ listed above)
  • MtxVec, linear algebra/numerical library for Delphi and C++ Builder.
  • Extreme Optimization Library, numerical library for .NET
  • MAT<LIB> (Matlab compatible C++ Matrix Class Library)
  • C-XSC: A C++ Class Library for Extended Scientific Computing (A C++ interval methods class library)
  • Siscat, C++ software for scattered data approximation
  • JNL, A numerical language/library proposal for Java from Visual Numerics.
  • LIA,GIA,ICE libraries for interval methods in C++ from Delisoft Ltd. Includes interval arithmetic, global optimization, and solving nonlinear equations.
  • AMRES, a C++ library for financial analysis.
  • 风波

    早上洗脚出门,顺便把鞋子给洗了下!
    走在半路上,我低头一看,吓了一跳,不知道怎么搞的,满脚的泡沫。
    天呢,丢大了。
    赶紧走路先,边走边甩脚,真是可恶!
    好不容易捱到公司,我去了不下十次厕所,还是没洗干净!
    于是一不做二不休,换拖鞋!我阴干你个破鞋子!
    看你还干跟我吐泡泡....
    等着它干.....
    August 08

    2008年8月8日8点 奥运

    今天是奥运开幕的日子,是我们北京举办奥运的日子!
     
    昨天晚上折腾个电脑到凌晨四点,早上很早就起床了。为嘛?为的是早早的回家看奥运开幕!
     
    这几天心里总是暖暖的,感到一阵喜悦,不知道为什么,有点要过年的味道,又有种家里来客人的感觉!
     
    预祝奥运圆满成功,预祝我们国家可以取得更多的金牌!
     
    August 02

    一生相随 转

    Life Together
    One fine day, an old couple around the age of 70, walks into a lawyer’s office. Apparently, they are there to file a divorce. Lawyer was very puzzled, after having a chat with them, he got their story.
    This couple had been quarreling all their 40 over years of marriage nothing ever seems to go right.
    They hang on because of their children, afraid that it might affect their up-bringing. Now, all their children have already grown up, have their own family, there’s nothing else the old couple have to worry about, all they wanted is to lead their own life free from all these years of unhappiness from their marriage, so both agree on a divorce.
    Lawyer was having a hard time trying to get the papers done, because he felt that after 40 years of marriage at the age of 70, he couldn’t understand why the old couple would still wants a divorce.
    While they were signing the papers, the wife told the husband. “I really love you, but I really can’t carry on anymore, I’m sorry.”
    “It’s OK, I understand.” said the husband. Looking at this, the lawyer suggested a dinner together, just three of them, wife thought, why not, since they are still going be friends.
      At the dining table, there was a silence of awkwardness.
    The first dish was roasted chicken, immediately, the old man took the drumstick for the old lady. “Take this, it’s your favorite.”
    Looking at this, the lawyer thought maybe there’s still a chance, but the wife was frowning when she answer. “This is always the problem, you always think so highly of yourself, never thought about how I feel, don’t you know that I hate drumsticks?”
    Little did she know that, over the years, the husband have been trying all ways to please her, little did she know that drumsticks was the husband’s favorite.
    Little did he know that she never thought he understand her at all, little did he know that she hates drumsticks even though all he wants is the best for her.
    That night, both of them couldn’t sleep, toss and turn, toss and turn. After hours, the old man couldn’t take it anymore, he knows that he still loves her, and he can’t carry on life without her, he wants her back, he wants to tell her, he is sorry, he wanted to tell her, “I love you.”
    He picks up the phone, started dialing her number. Ringing never stops. He never stop dialing.
    On the other side, she was sad, she couldn’t understand how come after all these years, he still doesn’t understand her at all, she loves him a lot, but she just can’t take it any- more. Phone’s ringing, she refuses to answer knowing that it’s him. “What’s the point of talking now that it’s over. I have asked for it and now. I want to keep it this way, if not I will lose face. “She thought. Phone still ringing. She has decided to pull out the cord.
    Little did she remember, he had heart problems.
    The next day, she received news that he had passed away. She rushed down to his apartment, saw his body, lying on the couch still holding on to the phone. He had a heart attack when he was still trying to get thru her phone line.
    As sad as she could be. She will have to clear his belongings. When she was looking thru the drawers, she saw this insurance policy, dated from the day they got married, beneficiary is her. Together in that file there’s this note.
    “To my dearest wife, by the time you are reading this, I’m sure I’m no longer around, I bought this policy for you, though the amount is only $100k, I hope it will be able to help me continue my promise that I have made when we got married, I might not be around anymore, I want this amount of money to continue taking care of you, just like the way I will if I could have live longer. I want you to know I will always be around, by your side. I love you.”
    Tears flowed like river.
    When you love someone, let them know. You never know what will happen the next minute. Learn to build a life together. Learn to love each other for who they are,Not what they are.
    【中文译文】:
      在一个阳光明媚的日子里,一对70多岁的老夫妇走进了律师事务所。显然地,他们准备到那儿办理离婚手续。律师对这对年老的夫妇提出要离婚的事感到非常困惑。后来,跟他们交谈了之后,他得知他们之间有这样一段故事:
    这对夫妇从40年前结婚之日起就一直吵个不停。他们似乎找不到共同点,一切在他们看来都格格不入。   
      由于担心他们的离婚会给孩子的成长带来不良影响,这对老夫妇把离婚的事搁浅到现在。现在,他们的孩子都长大成人了,也有他们各自的家庭了。于是,这对老夫妇再也没有什么事可以担忧的了。他们现在渴望的就是过各自的生活,免受这些年来婚姻带给他们的种种不幸。正因为这样,两个老人都赞同通过离婚解决事情的争端。
          律师极其艰难地为他们拟造了一份离婚协议书,因为他觉得,经过婚后40年的相濡以沫现在两个老人都70多岁了,他就是弄不明白为什么这对老夫妇仍然坚持要离婚。
      当他们签署文件时,老夫人遗憾地告诉丈夫:“我真的很爱你,但我再也不能忍受下去了,我非常抱歉。”
        “没有关系,我理解。”她的丈夫有点悲伤地回答道。看到他们夫妇还有一线挽救的希望,律师于是建议他们三个人一起去吃顿晚餐。就他们三个人,老夫人想道,为什么不呢,反正他们很快就成为朋友了。
        餐桌上,这对夫妇沉默不语,尴尬的气氛顿时弥漫开来。
        第一道菜是烤鸡。立刻地,老夫人的丈夫夹了一个鸡腿给她说道:“尝尝这个,我知道你最喜欢吃鸡腿了。”
     见到这种情景,律师心想,他们相亲相爱到这个地步本不应该提出离婚的。然而,出奇意料的是,当老夫人接过丈夫所夹的菜时,眉毛却很不自然地皱了一下答道:“这就是问题所在,你总是自以为是,从来没有顾及过我的感受,难道你就不知道我很讨厌吃鸡腿吗?”
      她一点也不清楚,这些年来,她的丈夫一直使尽办法讨她开心;她一点也不知道,鸡腿是她丈夫最喜爱吃的食物。
         他一点也不清楚,他的妻子会认为他完全不了解她;他一点也不知道,他妻子讨厌吃鸡腿,尽管他把自己最喜爱吃的都给了她。
         那天晚上,两个老人都睡不着,各自在自己的床上辗转反侧,辗转反侧。挣扎了几个小时后,老夫人的丈夫终于忍耐不住,他发觉他仍然深爱着老夫人。他的生活不能没有老夫人,他要她回来,他要亲口告诉她,“我很抱歉;”他要亲口告诉她,“我爱你。”
        于是,他拿起电话,开始按老夫人的电话号码,铃声响个不停,但另一边却没人接。尽管对方不接通他的电话,他还是一直不停地在按着重拔键。
        另一方面,老夫人也很伤心,她搞不清楚为什么经过多年来的相处她丈夫仍然一点都不了解她。事实上,她也非常爱她的丈夫,但她再也不愿意跟他一起生活了。电话铃声在响,老夫人知道是她丈夫打来的,但她心意已决不再接他的电话。 “现在谈论还有什么意思呢?我和你的感情已经结束了。当初,第一次提出离婚的人是我,那我现在也得保持这种现状。要不然,你会说我反悔,那我岂不是很丢脸。对,对,就这样下去。”老夫人心想道。电话铃声仍然在响,她于是索性把电话线拉开了。
      悲剧就这样发生了,她一点也不曾记起,她的丈夫有心脏病。
         第二天早上,老夫人得知她丈夫昨晚已逝世的消息。她径直向他的公寓里跑去,发现死后的丈夫躺在沙发上,手里仍然拿着电话。那天晚上,当她的丈夫试图接通她的电话时,心脏病突然发作,他就这样离开了她。
      尽管她很悲伤,老夫人仍不得不亲自动手清理他的遗物。当老夫人认真细致地翻着一个抽屉时,她发现了一张保险单。保险日期从他们结婚之日起算起,毫无疑问,保险受益人是她。在这个文件夹里,还有一份就是她丈夫亲手写的遗嘱,里面说道:
      “献给我最亲爱的妻子:当你读着这封遗嘱的时候,我确信我已不在人间。我为你买了这份保险。虽然金额总数才区区100英磅,但我希望它能帮助我继续履行我们结婚时我所起的照顾你一生一世的诺言。我不能再陪你一起度过你的余生,但我希望保险金额里的钱能够帮助我实现照顾你后半生生活的愿望,就像我可以重生的话那样照顾你。我同时也想让你知道,我会一直在你的周围,在你的身边,保护你关心你,我爱你!”
      老夫人读着读着,泪水如小河流水般奔涌而出。
      当你爱着一个人的时候,务必要让他们知道,因为你永远不知道下一分钟将会发生什么事。学会一起生活,学会互爱,不是他们是你的什么,而是他们是你的谁.
    August 01

    2008年8月1日 建军节

    今天是建军节,距离奥运会开幕一而就只剩下7天了!
    今天还是我拿到驾照四个月的纪念日,只是很可惜,一直没有钱来买属于自己的小汽车。
     
    努力,赚钱!
     
    好消息,下周三,EF测试。
    July 29

    为了忘却的纪念

    没想到就这么永别了!
    一个鲜活的生命,往事还是那么历历在目,我有点不敢相信,但是我却要接受这个事实!
    老爸生日,晚上给了电话,本来想第二天再打的,但是由于自己的懒惰去一直没打。
     
    直到昨天晚上,我收到哥哥的一个短信,我不敢相信自己的眼睛,“咱xx哥没了。挺想你的。”眼泪在眼眶里打转,往日一起玩耍,一起喝酒的场面又跃然脑海。
     
    本来七兄弟,现在只有六个了。
    我见他最后一面应该算是去年年底了。谁知那是一别,竟是永别。心在痛,脑子里乱乱的。
    他真的好年轻啊,不应该啊!万恶的老天爷。
     
    收到短信,我急忙给爸爸妈妈电话,家里无人接电话。我知道,他们现在一定是在我哥哥家,我大娘大爷一定很难过。我好希望这一切都不是真的。
     
    同龄人,竟这样和我们分别,怎么能叫人不心疼。
     
    家里没人接电话,我又打电话给妹妹,从妹妹口中我再得知详细情形。好恨呢,为什么不可以活得再久一些呢?
    快十点半了,我又打电话给爸爸妈妈,这次爸爸妈妈在家了。
    爸爸妈妈怕我担心挂念,一直没敢告诉我。要不是我先说我知道了,他们或许还是不会现在就告诉我!
    我理解他们做父母的心。对着电话,我哽咽着,我伤心难过,电话那头的爸爸妈妈,很无奈,不知道该怎么劝我。
     
    我知道自己要坚强,我不能让他们担心我。我说我没事,只是一时难以接受,自己的兄弟就这么离开我们了。难过是有的,但是我不会一直沉湎于这种悲伤之中的。
    说了好一会,才挂断电话,我努力坚强着,不能让爸爸妈妈担心我。
     
    今天早上七点多,我接到我哥哥的电话,哥哥跟我说了一些话,是啊,我们都是大人了,而哥哥他们也都是为人父母的人了。哥哥大意就是事已至此,只愿逝者安息,生者坚强,小心照顾自己,不要让意外再次发生。我又伤心了。
     
    挂断电话,去洗了澡,出门上班。台风“凤凰”来了,杭州笼罩在一片雨雾之中。我的心情也就想这天一样,阴着。
     
    再次愿逝者安息。
     
    好好活着就是对关心你的人的最好的礼物。
     
     
    July 22

    2008年最龌龊语录100句,可作QQ签名


    001◎老鼠一发威,大家都是病猫。
      002◎和一MM争论鲸鱼是不是鱼,最后我说“曰本人也带个人字”,她这才同意鲸鱼不是鱼。
      003◎男人膝下有黄金,我把整个腿都切下来了,连块铜也没找着!
      004◎春天我把玉米埋在土里,到了秋天我就会收获很多玉米。春天我把老婆埋在土里,到了秋天我就会…被枪毙!
      005◎如果你看到面前的阴影,别怕,那是因为你的背后有阳光!
      006◎踏遍青楼人未老,请用汇仁肾宝。
      007◎听君一席话,省我十本书!
      008◎0岁出场亮相,10岁天天向上。20岁远大理想,30岁发奋图强。40岁基本定向,50岁处处吃香。60岁打打麻将,70岁处处闲逛。80岁拉拉家常,90岁挂在墙上!
      009◎脱了衣服我是禽兽,穿上衣服我是衣冠禽兽!
      010◎师太,你就从了老衲吧!…很久很久以后…师太,你就饶了老衲吧!
      011◎“亲爱的,我…我怀孕了…三个月了,不过你放心,不是你的,不用你负责……”
      012◎我们产生一点小分歧:她希望我把粪土变黄金,我希望她视黄金如粪土。
      013◎读10年语文,不如聊半年QQ。
      014◎早晨懒床,遂从口袋里掏出6枚硬币:如果抛出去六个都是正面,我就去上课!思躇良久,还是算了,别冒这个险了……
      015◎我花8万买了个西周陶罐,昨儿到《鉴宝》栏目进行鉴定,专家严肃地说:“这哪是西周的?这是上周的!”
      016◎我能容忍身材是假的,脸是假的,胸是假的,臀是假的!!!但就是不容忍钱是假的!!!!
      017◎士为知己者装死,女为悦己者整容。
      018◎长大了要嫁给唐僧,能玩就玩,不能玩就把他吃掉。
      019◎一山不能容二虎,除非一公和一母。
      020◎千万别等到人人都说你丑时才发现自己真的丑。
      021◎如果朋友可以出卖,每个值五块的话,我也能发笔小财了。
      022◎征婚启事:要求如下,A活的,B女的。
      023◎给点阳光我就腐烂。
      024◎要适当吃一点,才有劲减肥啊。
      025◎摇啊摇,摇到奈何桥。
      026◎命运负责洗牌,但是玩牌的是我们自己!
      027◎问:你喜欢我哪一点?答:我喜欢你离我远一点!
      028◎你快回来,我一人忽悠不来!
      029◎生活就像宋祖德的嘴,你永远都不知道下一个倒霉的会是谁~~~
      030◎跌倒了,爬起来再哭~~~
      031◎世界上难以自拔的,除了牙齿,还有爱情。
      032◎一恐龙路过西安交大时上了趟厕所,出来后她呜咽道:“555,这辈子终于不愁嫁不出去了……”
      033◎生,容易。活,容易。生活,不容易。
      034◎吾表兄,年四十余。始从文,连考三年而不中。遂习武,练武场上发一矢,中鼓吏,逐之出。改学医,自撰一良方,服之,卒。
      035◎问君能有几多愁,恰似一群太监上青楼……
      036◎吾生也有涯,而吃也无涯~~~
      037◎想污染一个地方有两种方法:垃圾,或是钞票!
      038◎年轻的时候,我们常常冲着镜子做鬼脸;年老的时候,镜子算是扯平了。
      039◎你瞎了眼啊?这么大的盾牌你看不见,偏偏要把石头朝我脑袋上扔!
      040◎出问题先从自己身上找原因,别一便秘就怪地球没引力。
      041◎拍脑袋决策,拍胸脯保证,拍屁股走人。
      042◎我们走得太快,灵魂都跟不上了……
      043◎不要和地球人一般见识~~~
      044◎女孩从处女到女人只要一次并成功,男孩从处男变男人需要反复的磨练!
      045◎出来混,老婆迟早是要换的!
      046◎小时候我以为自己长大后可以拯救整个世界,等长大后才发现整个世界都拯救不了我……
      047◎有钱的都是大爷!但是欠钱不还的更是!
      048◎我就算是一只癞蛤蟆,我也决不娶母癞蛤蟆。
      049◎生前何必久睡,死后自会长眠……
      050◎不想当厨子的裁缝,不是好司机。
      051◎时间是最好的老师,但遗憾的是——最后他把所有的学生都弄死了。
      052◎去西安出差的路上,一位大连老兄一阵狂吹大连多好多好,然后说大连建市一百周年的时候举行了很隆重的庆祝活动云云,然后问了旁边一人:“西安建市一百周年有什么庆祝活动没有?”旁边几位西安的哥们一愣,过了一会儿,逼出一句话来:“我记得西安建市600年的时候搞了一个‘烽火戏诸侯’吧……”
      053◎钻石恒久远,一颗就破产!
      054◎和谐校园里,骑自行车的也许是位博导,而开奔驰的则可能是个后勤……
      055◎是金子,总会花光的;是镜子,总会反光的……
      056◎我女友不当尼姑的原因是她四级没过,庵里不收。
      057◎明星脱一点就能更出名,我脱的光光的却被抓起来了!
      058◎看一漂亮MM,苦无搭讪办法,路旁一砖头,拣起,上前,“同学,这是你掉的吧?”
      059◎小时候的梦想并不是要当什么科学家,幻想自己是地主家的少爷,家有良田千顷,终日不学无术,没事领着一群狗奴才上街去调戏一下良家少女……
      060◎别和我谈理想,戒了!
      061◎玫瑰你的,巧克力你的,钻石你的。你,我的!
      062◎所谓惊喜就是你苦苦等候的兔子来了,后面跟着狼!
      063◎什么是幸褔?幸福就是猫吃鱼狗吃肉,奥特曼打小怪兽!
      064◎俩农夫吹牛:“俺们农场的鸡,吃的都是茶叶,下的全是茶叶蛋”“有嘛啊,咱农场给鸡吃钱包,让它下荷包蛋。”
      065◎蟑螂都不怕蟑螂药了,我们却连维生素都搞不定!
      066◎长个包子样就别怨狗跟着!
      067◎男人偷腥时的智商仅次于爱因斯坦!
      068◎为中华而努力读书!一包中华好多钱啊……
      069◎如果你不能给你的女人穿上嫁衣,那么千万别停下你解开她衣扣的手!
      070◎别以为穿着脏衣服就可以做污点证人;别以为穿着木制拖鞋就可以做木屐证人……
      071◎事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。
      072◎凤凰重生就是涅盘,野鸡重生就是尸变。
      073◎如果有一天我变成流氓,请告诉别人,我纯真过……
      074◎老子不但有车,还是自行的……
      075◎女人拥有无数个QQ号只为了调戏一个男人,男人常用一个QQ号上面加满各种各样的女人……
      076◎偶然看见书上所谓的当代女子择偶标准:“有车有房,父母双亡。”郁闷。遂写下幻想中的选妻标准:“家中财产过亿,美貌天下第一,贤惠温柔性感,岳父癌症晚期……”
      077◎大部分人一辈子只做三件事:自欺、欺人、被人欺。
      078◎睡眠是一门艺术——谁也无法阻挡我追求艺术的脚步!
      079◎为了避免家庭暴力,于是我决定不结婚!
      080◎你可以像猪一样的生活,但你永远都不能像猪那样快乐!
      081◎迅雷不及掩耳盗铃,以不变应万变不离其宗,成事不足挂齿,此物最相思风雨中,一屋不扫何以扫天下无敌,东边日出西边雨一直下,举头望明月几时有,呆若木鸡毛当令箭,杀鸡焉用牛刀小试,锋芒毕露春光,围魏救赵宝奎,Very good bye,八格牙鲁冰花,一泻千里共婵娟……
      082◎某女的一篇博客日记:某月某日,大醉而归,伸手一摸——手机和贞操都在,睡觉!
      083◎又美丽、又纯洁、又温柔、又性感、又可爱的处女,就像鬼魂一样,男人们都在谈论它,但从来没有人亲眼见过……
      084◎记得小学老师骂我:“我一巴掌把你踢出去!”当时我想笑却不敢笑。现在,是敢笑却不会笑了……
      085◎如果幸福是浮云,如果痛苦似星辰。那我的生活真是万里无云,漫天繁星……
      086◎避孕的效果:不成功,便成“人”。
      087◎孤单是一个人的狂欢,狂欢是一群人的孤单。
      088◎这世上最累的事情,莫过于眼睁睁看着自己的心碎了,还得自己动手把它粘起来。
      089◎人生的悲惨在于:辛辛苦苦的作了一晚上内容香艳的美梦,第二天早上醒来居然全都记不起来了!
      090◎父亲问我人生有什么追求?我回答金钱和美女,父亲凶狠的打了我的脸;我回答事业与爱情,父亲赞赏的摸了我的头。
      091◎男人都好色,色心稍强一点叫色狼,再强一点叫色鬼,更加强就叫色魔,尤其强那就成了变态色魔,好色到了极致,被称作人体美学艺术家。
      092记得刚毕业不久的一天,女友给我发了一条短信:“我们还是分手吧!”我还没来得及伤心呢,女友又发来一条:“对不起,发错了。”这下可以彻底伤心了……
      093◎此地禁止大小便,违者没收工具。
      094◎在街上看美女,目光高一点就是欣赏,目光低一点就是流氓。
      095◎孩儿他娘,咱这辈子还有很多事要做呢,别耽误功夫和我玩捉迷藏了,赶紧蹦出来吧~~~
      096◎女人一生喜欢两朵花:一是有钱花,二是尽量花!
      097◎一炮走红——是形容女艺人的……
      098◎这个世界不公平就在于:上帝说:“我要光!”于是有了白天。美女说:“我要钻戒!”于是她有了钻戒。富豪说:“我要女人!”于是他有了女人。我说:“我要洗澡!”居然停水了!
      099真不明白,女孩买很多很多漂亮衣服穿,就是为了吸引男孩的目光,但男孩想看的,却是不穿衣服的女孩。
    July 21

    电脑升级啦

    实在很不幸,我那老爷车式的CRT显示器终于退役了。
    代替它的是一ViewSonic的1916.
    宽屏显示器还是很不错的很爽,但是我那不争气的显卡不配合,分辨率不支持1440*900.
    可恶的很!
    最后换了台机器才好的!
     
    打算最近进行一系列的升级,包括内存 CPU之流的硬件!!
     
    不知道这样可以支持Vista吗?
     
    呵呵,希望吧!

    祝有情人终成眷属

    伟玲世纪婚礼,祝有情人终成眷属!
     
     
    July 19

    注意 三伏,从今儿开始

    注意 三伏,从今儿开始

    头伏饺子二伏面三伏烙饼加积碳,,,

    ,,大热天的出行注意防暑哦!!,,

    2008年何时入伏 怎么计算出来的

             “表示阴气受阳气所迫藏伏在地下的意思,每年有三个伏,三伏天是一年中最热的季节。从夏至开始,依照干、支纪日的排列,第三个庚日为初伏。第四个庚日为中伏,立秋后第一个庚日为末伏。庚日的字是甲、乙、丙、丁、戊、己、庚、辛、壬、癸十天干中的第七个字,庚日每十天重复一次。

    伏天的起讫时间每年都不尽相同,大致是在七月中旬到八月中旬。具体是怎样计算的呢?我国流行的干支纪日法用天干与地支相配而成的60组不同的名称来记日子,每逢有庚字的日子叫庚日。

         秦汉时盛行五行相生相克的说法,认为最热的夏天日子属火,而庚属金,金怕火烧熔(火克金),所以到庚日,金必伏藏。于是规定从夏至后的第三个庚日起为初伏(有10天),从夏至后的第四个庚日起为中伏(有的年的10天,有的年的20天),立秋后的第一个庚起为末伏,也称终伏(有10天),总称为三伏。

    2008年6月21日农历五月十八日,星期六,壬辰日,今日夏至

    第一个庚日是6月29日农历五月二十六日,庚子日

    第二个庚日是7月9日农历六月初七日,庚戌日

    第三个庚日是7月19日农历六月十七日,庚申日。入伏(初伏共10天)。

    7月29日农历六月二十七日庚申日(中伏共20天)

    8月7日农历七月初七日,星期四,己卯日,中伏第10天,今日立秋

    8月17日农历七月十七日,星期日,己丑日,中伏第20天

    8月18日农历七月十八日,星期一,庚寅日,三伏(共10天)第1天;


    8月27日农历七月二十七日,星期三,己亥日,三伏第10天;——

    July 16

    做人真难

    终于发现做人真难!
    有些人平时很好,一旦涉及到利益的时候,就大变脸了!
    哪怕是小小的一点利益!
     
    哎,劣根性还是那么明显的!
     
    以后做人要识相点,这种人要远离,还是独善其身比较好!
     
    不要做好人,很痛苦的!
     
    做一个不伤害别人,也不被别人伤害的人吧!!
     
    真希望做个无忧无虑的人。
     
    无欲则刚!
     
    我不想求人,什么事情也不求的!!
     
    大不了不去做,大不了不要。大不了不想!
    没什么了不起的。
     
    想做到面面俱到还是比较困难的!!
     
    就当是趁此看清楚有些人的真面目吧!!
     
    以后做人要小心点了!!
    越来越想念小番茄了!她曾经告诉过我的!
    只是当时我一直不承认!
    July 15

    电影票有发票吗?

    只是很想知道这个问题!
    呵呵
     
    这方面不是很精通。
    July 12

    和谐共处

    我家原来有小强!
     
    晚上还是我家地板上散步呢!
    July 11

    活得有点累

    最近有点累,不是工作打来的,尽管经常很晚回家!
     
    晚上都不太容易入睡的,眼袋,黑眼圈接连到来!精神状态不是很好!
     
    最近也接近于承认一个事实,一直都是我活在自己的幻想当中!
     
    不敢不想不愿接受这样的事实!
     
    实在是有点累,还不如让自己承认这个事实。
     
    活得解脱点,不想再这样了!
     
    心死了,或许就不会有希望了!
    July 08

    Gmail--番茄宝贝

    好久没上gmail了!
    今天无意上去,看到了我和上面仅有的一个朋友的聊天!
     
    在这上面,你就是我的全部!
    那是我刚进海康威视时你和我的对话!
     
    现在读来,心好痛!
    都是我不珍惜你!
    现在我所经历的一切,都在证实你所说的一切!
    我慢慢感到,你以前都是对的!
     
    想起gmail,我就会想起你!因为那是我在万般无奈,不知道有什么可以选择的情况下选择的工具,一个可以让我联系你的工具!
     
    爱情是伟大的,我却是自私的,就像你说的!
     
     
    你结婚了,祝福你。
    假如有一天我们可以相遇,希望你是笑着的!
     我会珍藏我们的点点滴滴!
    June 20

    红塔山

    独自倚窗,看着烟头闪烁!
     
    百味人生,涌上心头!
     
    遥想当年,悔当初!
     
    不宜妄自菲薄,最终害人害己!
     
    呵呵

    莱芜地震说

    不知道真假!
    据说是假的!爸爸妈妈说一切都好,不要挂念!
     
    晚上在车上,经历了逆向行驶和手刹拉起的高速行驶,估计很有警示效果,我都闻到焦味了,还以为是新车固有的味道!
     
    呵呵,都是我太大意了!
    我这么警觉,以后有什么事情就说了,不要太顾及我自己的小面子!
     
    啊哈哈,愉快的一天!
     
    男人好!

    挪威森林

    让我将你心儿摘下
    试著将它慢慢溶化

    看我在你心中是否仍完美无瑕
    是否依然为我丝丝牵挂
    依然爱我无法自拔纳威
    心中是否有我未曾到过的地方啊

    那里湖面总是澄清
    那里空气充满宁静
    雪白明月照在大地
    藏著你不愿提起的回忆

    你说真心总是可以从头
    真爱总是可以长久
    为何你的眼神还有孤独时的落寞
    是否我只是你一种寄托
    填满你感情的缺口
    心中那片森林何时能让我停留

    那里湖面总是澄清
    那里空气充满宁静
    雪白明月照在大地
    藏著你最深处的秘密

    或许我
    不该问
    让你平静的心再起涟漪
    只是爱你的心超出了界线
    我想拥有你所有一切
    应该是
    我不该问
    不该让你再将往事重提
    只是心中枷锁
    该如何才能解脱

    让我将你心儿摘下
    试著将它慢慢溶化
    看我在你心中是否仍完美无瑕

    是否依然为我丝丝牵挂
    依然爱我无法自拔
    心中是否有我未曾到过的地方啊

    那里湖面总是澄清
    那里空气充满宁静
    雪白明月照在大地
    藏著你最深处的秘密

    或许我
    不该问
    让你平静的心再起涟漪
    只是爱你的心超出了界线
    我想拥有你所有一切
    应该是
    我不该问
    不该让你再将往事重提
    只是心中枷锁
    该如何才能解脱

    或许我
    不该问
    让你平静的心再起涟漪
    只是爱你的心超出了界线
    我想拥有你所有一切
    应该是
    我不该问
    不该让你再将往事重提
    只是心中枷锁
    该如何才能解脱