青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

曠野的呼聲

路漫漫其修遠兮 吾將上下而求索

常用鏈接

統計

最新評論

【轉帖】Rational Purify 使用及分析實例

Rational Purify 使用及分析實例

developerWorks

級別: 初級

蔡 林, IBM 中國軟件開發中心軟件工程師

2006 年 2 月 23 日

本文介紹了 IBM Rational Purify的基本概念和在不同操作系統中使用Purify對C/C++源程序中存在的內存問題進行勘察和分析,并且提供了有關的實例以便讀者在實際操作中作為參考。

簡介

本文介紹了IBM Rational Purify的基本概念和在不同操作系統中使用Purify對C/C++源程序中存在的內存問題進行勘察和分析,并且提供了有關的實例以便讀者在實際操作中作為參考。






1.內存問題的原因及分類

在C/C++程序中,有關內存使用的問題是最難發現和解決的。這些問題可能導致程序莫名其妙地停止、崩潰,或者不斷消耗內存直至資源耗盡。由于C/C++語言本身的特質和歷史原因,程序員使用內存需要注意的事項較多,而且語言本身也不提供類似Java的垃圾清理機制。編程人員使用一定的工具來查找和調試內存相關問題是十分必要的。

總的說來,與內存有關的問題可以分成兩類:內存訪問錯誤和內存使用錯誤。內存訪問錯誤包括錯誤地讀取內存和錯誤地寫內存。錯誤地讀取內存可能讓你的模塊返回意想不到的結果,從而導致后續的模塊運行異常。錯誤地寫內存可能導致系統崩潰。內存使用方面的錯誤主要是指申請的內存沒有正確釋放,從而使程序運行逐漸減慢,直至停止。這方面的錯誤由于表現比較慢很難被人工察覺。程序也許運行了很久才會耗凈資源,發生問題。

1.1 內存解剖

一個典型的C++內存布局如下圖所示:



自底向上,內存中依次存放著只讀的程序代碼和數據,全局變量和靜態變量,堆中的動態申請變量和堆棧中的自動變量。自動變量就是在函數內聲明的局部變量。當函數被調用時,它們被壓入棧;當函數返回時,它們就要被彈出堆棧。堆棧的使用基本上由系統控制,用戶一般不會直接對其進行控制,所以堆棧的使用還是相對安全的。動態內存是一柄雙刃劍:它可以提供程序員更靈活的內存使用方法,而且有些算法沒有動態內存會很難實現;但是動態內存往往是內存問題存在的沃土。

1.2 內存訪問錯誤

相對用戶使用的語言,動態內存的申請一般由malloc/new來完成,釋放由free/delete完成。基本的原則可以總結為:一對一,不混用。也就是說一個malloc必須對應一且唯一的free;new對應一且唯一的delete; malloc不能和delete, new不能和free對應。另外在C++中要注意delete和delete[]的區別。delete用來釋放單元變量,delete[]用來釋放數組等集聚變量。有關這方面的詳細信息可以參考[C++Adv]。

我們可以將內存訪問錯誤大致分成以下幾類:數組越界讀或寫、訪問未初始化內存、訪問已經釋放的內存和重復釋放內存或釋放非法內存。

下面的代碼集中顯示了上述問題的典型例子:


1   #include <iostream>
                        2   using namespace std;
                        3   int main(){
                        4      char* str1="four";
                        5      char* str2=new char[4];	//not enough space
                        6      char* str3=str2;
                        7      cout<<str2<<endl;	//UMR
                        8      strcpy(str2,str1);	//ABW
                        9      cout<<str2<<endl;  //ABR
                        10     delete str2;
                        11     str2[0]+=2;	//FMR and FMW
                        12     delete str3;	//FFM
                        13   }
                        

由以上的程序,我們可以看到:在第5行分配內存時,忽略了字符串終止符"\0"所占空間導致了第8行的數組越界寫(Array Bounds Write)和第9行的數組越界讀(Array Bounds Read); 在第7行,打印尚未賦值的str2將產生訪問未初始化內存錯誤(Uninitialized Memory Read);在第11行使用已經釋放的變量將導致釋放內存讀和寫錯誤(Freed Memory Read and Freed Memory Write);最后由于str3和str2所指的是同一片內存,第12行又一次釋放了已經被釋放的空間 (Free Freed Memory)。

這個包含許多錯誤的程序可以編譯連接,而且可以在很多平臺上運行。但是這些錯誤就像定時炸彈,會在特殊配置下觸發,造成不可預見的錯誤。這就是內存錯誤難以發現的一個主要原因。

1.3 內存使用錯誤

內存使用錯誤主要是指內存泄漏,也就是指申請的動態內存沒有被正確地釋放,或者是沒有指針可以訪問這些內存。這些小的被人遺忘的內存塊占據了一定的地址空間。當系統壓力增大時,這些越來越多的小塊將最終導致系統內存耗盡。內存使用錯誤比內存訪問錯誤更加難以發現。這主要有兩點原因:第一,內存使用錯誤是"慢性病",它的癥狀可能不會在少數、短時間的運行中體現;第二,內存使用錯誤是因為"不做為"(忘記釋放內存)而不是"做錯"造成的。這樣由于忽略造成的錯誤在檢查局部代碼時很難發現,尤其是當系統相當復雜的時候。






2.Purify的原理及使用

IBM Rational PurifyPlus是一組程序運行時的分析軟件。她包括了程序性能瓶頸分析軟件Quantify, 程序覆蓋面分析軟件PureCoverage,和本文的主角:程序運行錯誤分析軟件Purify。Purify可以發現程序運行時的內存訪問,內存泄漏和其他難以發現的問題。

同時她也是市場上唯一支持多種平臺的類似工具,并且可以和很多主流開發工具集成。Purify可以檢查應用的每一個模塊,甚至可以查出復雜的多線程或進程應用中的錯誤。另外她不僅可以檢查C/C++,還可以對Java或.NET中的內存泄漏問題給出報告。

2.1 Purify的原理

程序運行時的分析可以采用多種方法。Purify使用了具有專利的目標代碼插入技術(OCI:Object Code Insertion)。她在程序的目標代碼中插入了特殊的指令用來檢查內存的狀態和使用情況。這樣做的好處是不需要修改源代碼,只需要重新編譯就可以對程序進行分析。

對于所有程序中使用的動態內存,Purify將它們按照狀態進行歸類。這可以由下圖來說明(來自[DEV205]):



參見本文中以上給出的代碼,在程序第5行執行后,str2處于黃色狀態。當在第7行進行讀的時候,系統就會報告一個訪問未初始化內存錯誤(Uninitialized Memory Read)。因為只有在綠色狀態下,內存才可以被合法訪問。

為了檢查數據越界錯誤(ABR,ABW),Purify還在每個分配的內存前后插入了紅色區域。這樣一來,超過邊界的訪問指令必定落在非法區域,從而觸發ABR或者ABW錯誤報告。這里需要指出一點。訪問未初始化內存錯誤UMR在某些情況下其實是合法的操作,例如內存拷貝。所以在分析報告時可以把UMR放到最后,或者干脆從結果中濾除。

2.2 Purify的使用

這里簡單介紹一下Purify在Windows和UNIX環境下的使用。

在Windows中,只要運行Purify,填入需要分析的程序及參數就可。Purify會自動插入檢測代碼并顯示報告。報告的格式如下(來自[DEV205]):



藍色的圖標代表一些運行的信息,比如開始和結束等。黃色是Purify給出的警告。通常UMR會作為警告列出。紅色則代表嚴重的錯誤。每一種相同的錯誤,尤其是在循環中的,會被集中在一起顯示,并且標明發生的次數。由每個錯誤的詳細信息,用戶可以知道相應的內存地址和源代碼的位置,并直接修改。另外用戶還可以設置不同的濾過器,用來隱藏暫時不關心的消息。

在UNIX系統中,使用Purify需要重新編譯程序。通常的做法是修改Makefile中的編譯器變量。下面是用來編譯本文中程序的Makefile:


        CC=purify gcc
                        all: pplusdemo
                        pplusdemo: pplusdemo.o
                        $(CC) -o pplusdemo pplusdemo.o -lstdc++
                        pplusdemo.o: pplusdemo.cpp
                        $(CC) -g -c -w pplusdemo.cpp
                        clean:
                        -rm pplusdemo pplusdemo.o
                        

首先運行Purify安裝目錄下的purifyplus_setup.sh來設置環境變量,然后運行make重新編譯程序。需要指出的是,程序必須編譯成調試版本。在gcc中,也就是必須使用"-g"選項。在重新編譯的程序運行結束后,Purify會打印出一個分析報告。它的格式和含義與Windows平臺大同小異。

下面是本文中的程序在Linux上Purify運行的結果:


    ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        UMR: Uninitialized memory read:
                        * This is occurring while in:
                        strlen         [rtlib.o]
                        std::basic_ostream< char,std::char_traits< char>> & std::operator
                        <<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits<
                        char>> &, char const *) [libstdc++.so.5]
                        main           [pplusdemo.cpp:7]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * Reading 1 byte from 0x80b45e0 in the heap.
                        * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
                        * This block was allocated from:
                        malloc         [rtlib.o]
                        operator new( unsigned) [libstdc++.so.5]
                        operator new []( unsigned) [libstdc++.so.5]
                        main           [pplusdemo.cpp:5]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        ABW: Array bounds write:
                        * This is occurring while in:
                        strcpy         [rtlib.o]
                        main           [pplusdemo.cpp:8]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * Writing 5 bytes to 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal).
                        * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
                        * This block was allocated from:
                        malloc         [rtlib.o]
                        operator new( unsigned) [libstdc++.so.5]
                        operator new []( unsigned) [libstdc++.so.5]
                        main           [pplusdemo.cpp:5]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        ABR: Array bounds read:
                        * This is occurring while in:
                        strlen         [rtlib.o]
                        std::basic_ostream< char,std::char_traits< char>> & std::operator
                        <<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits<
                        char>> &, char const *) [libstdc++.so.5]
                        main           [pplusdemo.cpp:9]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * Reading 5 bytes from 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal).
                        * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
                        * This block was allocated from:
                        malloc         [rtlib.o]
                        operator new( unsigned) [libstdc++.so.5]
                        operator new []( unsigned) [libstdc++.so.5]
                        main           [pplusdemo.cpp:5]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        FMM: Freeing mismatched memory:
                        * This is occurring while in:
                        operator delete( void *) [rtlib.o]
                        main           [pplusdemo.cpp:10]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * Attempting to free block at 0x80b45e0 in the heap.
                        * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
                        * This block was allocated from:
                        malloc         [rtlib.o]
                        operator new( unsigned) [libstdc++.so.5]
                        operator new []( unsigned) [libstdc++.so.5]
                        main           [pplusdemo.cpp:5]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * This block of memory was obtained using an allocation routine which is
                        not compatible with the routine by which it is being freed.
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        FMR: Free memory read:
                        * This is occurring while in:
                        main           [pplusdemo.cpp:11]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * Reading 1 byte from 0x80b45e0 in the heap.
                        * Address 0x80b45e0 is at the beginning of a freed block of 4 bytes.
                        * This block was allocated from:
                        malloc         [rtlib.o]
                        operator new( unsigned) [libstdc++.so.5]
                        operator new []( unsigned) [libstdc++.so.5]
                        main           [pplusdemo.cpp:5]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * There have been 0 frees since this block was freed from:
                        free           [rtlib.o]
                        _ZdLpV         [libstdc++.so.5]
                        main           [pplusdemo.cpp:10]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        FMW: Free memory write:
                        * This is occurring while in:
                        main           [pplusdemo.cpp:11]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * Writing 1 byte to 0x80b45e0 in the heap.
                        * Address 0x80b45e0 is at the beginning of a freed block of 4 bytes.
                        * This block was allocated from:
                        malloc         [rtlib.o]
                        operator new( unsigned) [libstdc++.so.5]
                        operator new []( unsigned) [libstdc++.so.5]
                        main           [pplusdemo.cpp:5]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * There have been 0 frees since this block was freed from:
                        free           [rtlib.o]
                        _ZdLpV         [libstdc++.so.5]
                        main           [pplusdemo.cpp:10]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        FUM: Freeing unallocated memory:
                        * This is occurring while in:
                        free           [rtlib.o]
                        _ZdLpV         [libstdc++.so.5]
                        main           [pplusdemo.cpp:12]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * Attempting to free block at 0x80b45e0 already freed.
                        * This block was allocated from:
                        malloc         [rtlib.o]
                        operator new( unsigned) [libstdc++.so.5]
                        operator new []( unsigned) [libstdc++.so.5]
                        main           [pplusdemo.cpp:5]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        * There have been 1 frees since this block was freed from:
                        free           [rtlib.o]
                        _ZdLpV         [libstdc++.so.5]
                        main           [pplusdemo.cpp:10]
                        __libc_start_main [libc.so.6]
                        _start         [crt1.o]
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        Current file descriptors in use: 5
                        FIU: file descriptor 0: <stdin>
                        FIU: file descriptor 1: <stdout>
                        FIU: file descriptor 2: <stderr>
                        FIU: file descriptor 26: <reserved for Purify internal use>
                        FIU: file descriptor 27: <reserved for Purify internal use>
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        Purify: Searching for all memory leaks...
                        Memory leaked: 0 bytes (0%); potentially leaked: 0 bytes (0%)
                        Purify Heap Analysis (combining suppressed and unsuppressed blocks)
                        Blocks        Bytes
                        Leaked          0            0
                        Potentially Leaked          0            0
                        In-Use          0            0
                        ----------------------------------------
                        Total Allocated          0            0
                        ****  Purify instrumented ./pplusdemo (pid 30669)  ****
                        * Program exited with status code 0.
                        * 7 access errors, 7 total occurrences.
                        * 0 bytes leaked.
                        * 0 bytes potentially leaked.
                        * Basic memory usage (including Purify overhead):
                        290012 code
                        152928 data/bss
                        6816 heap (peak use)
                        7800 stack
                        

我們對照程序可以發現Purify查出了程序中所有的錯誤。對于每個錯誤,她不但給出了源代碼的位置還指出這些內存最初分配的源代碼位置。這對于查找問題提供了很大幫助。對于程序12行的解釋,Purify將其認為是不匹配的內存釋放(FMM: Freeing mismatched memory),因為她認為這樣的釋放方式不符合嚴格的規定。

Purify在其報告和文檔中使用了很多的縮寫,在此一并列出,以便讀者在使用時參考(來自[Purify]):



2.3 Purify的一些特性

這里簡單介紹一下Purify提供的幾個特性。有關這些特性的詳細信息,請查閱文檔[Purify]。

  • 觀察點(Watchpoint):通過在程序或者調試器中調用Purify 提供的觀察點函數,Purify可以報告有關被觀察對象的讀寫或其他操作。
  • 與Rational其他產品的集成:在Puify的用戶界面中可以方便地進入ClearCase和ClearQuest。Purify還可以和PureCoverage同時使用,對程序進行分析。
  • Purify的定制:無論是Purify報告中的消息,還是界面中的元素,都可以進行一定程度的定制。另外通過修改配置文件和調用Purify API,用戶還可以自動記錄運行日志,發送電子郵件等。
  • Purify提供的API:為了更好地把Purify融合到自動化測試的體系中,Purify提供了一系列的公開函數。用戶完全可以通過腳本的方式自動運行,記錄,和分析Purify。





3.總結

當使用C/C++進行開發時,采用良好的一致的編程規范是防止內存問題第一道也是最重要的措施。在此前提下,IBM Rational Purify作為一種運行時分析軟件可以很好地幫助您發現忽略的內存問題,或成為軟件自動測試中的一個重要組成部分。






4.參考資料

[C++Adv]
[DEV205] Essentials of Rational PurifyPlus
[Purify] IBM Rational PurifyPlus for Linux and UNIX Documentation



關于作者

 

蔡林,IBM 中國軟件開發中心軟件工程師,2004年獲得美國Baylor University計算機系碩士學位,同年加入IBM 中國軟件開發中心,從事Rational ClearQuest G11N的開發工作。

posted on 2009-05-25 23:36 董波 閱讀(1001) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久久久久搜平片| 久久夜色撩人精品| 国产日韩欧美综合精品| 欧美视频一区二区| 欧美日韩成人精品| 欧美视频在线观看| 国产精品免费福利| 国产亚洲日本欧美韩国| 国模套图日韩精品一区二区| 激情婷婷亚洲| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲电影免费观看高清完整版在线观看 | 亚洲第一视频网站| 欧美第一黄色网| 久久综合狠狠综合久久综青草| 国产午夜精品一区二区三区视频| 国产一区二区中文字幕免费看| 极品中文字幕一区| 一区二区高清在线| 欧美一区午夜精品| 亚洲高清av在线| 亚洲欧美成aⅴ人在线观看| 久久久久久久综合| 欧美日韩一区精品| 在线不卡中文字幕播放| 亚洲天堂av在线免费观看| 久久久国产亚洲精品| 亚洲第一精品夜夜躁人人爽| 亚洲深夜福利视频| 欧美大胆人体视频| 国产一区二区0| 这里只有精品视频在线| 久久综合九九| 亚洲天堂免费在线观看视频| 久久久综合激的五月天| 国产精品久久久久久户外露出 | 亚洲国产成人久久综合一区| 一区二区三区国产精品| 久久精品99久久香蕉国产色戒| 欧美激情在线狂野欧美精品| 亚洲一区在线免费观看| 欧美精品一区二区在线观看| 国产综合在线看| 亚洲欧美日本另类| 亚洲国产成人久久综合一区| 欧美一区二区三区播放老司机| 欧美激情综合色综合啪啪| 国产一区二区三区四区老人| 亚洲小说欧美另类社区| 亚洲激情视频网| 久久综合伊人77777蜜臀| 国产日韩欧美综合精品| 欧美一级在线亚洲天堂| 99国产精品99久久久久久| 欧美激情一区| 亚洲毛片在线看| 欧美福利一区| 欧美成人精品影院| 亚洲精品日产精品乱码不卡| 欧美肥婆bbw| 免费在线看一区| 亚洲国产欧美久久| 亚洲国产精品第一区二区| 久久综合九九| 在线精品国产欧美| 欧美成人一区二区三区| 老鸭窝毛片一区二区三区| 一区二区在线免费观看| 久久全国免费视频| 乱码第一页成人| 久久亚洲综合色一区二区三区| 国产精品一二三| 午夜在线一区二区| 香蕉久久夜色精品国产使用方法| 国产精品一级二级三级| 欧美在线免费视屏| 久久久久成人网| 亚洲美女淫视频| 亚洲视频免费| 狠狠久久婷婷| 亚洲人成网站在线播| 欧美日韩在线一区二区三区| 亚洲在线网站| 久久精品夜色噜噜亚洲aⅴ| 亚洲国产日韩欧美在线图片| 亚洲国产网站| 国产精品一区视频| 亚洲成色最大综合在线| 欧美午夜精品一区| 久久综合色天天久久综合图片| 乱码第一页成人| 亚洲尤物视频在线| 久久―日本道色综合久久| 日韩亚洲精品电影| 欧美一区高清| 99热精品在线| 久久精品国产亚洲一区二区三区| 亚洲精品乱码| 欧美中文字幕视频在线观看| 亚洲精品女人| 久久精品九九| 亚洲欧美日韩第一区| 噜噜噜噜噜久久久久久91| 午夜精品视频在线| 欧美欧美午夜aⅴ在线观看| 久久精品久久综合| 欧美日韩精品福利| 免费观看在线综合| 国产精品一区二区你懂得| 欧美激情网友自拍| 狠狠狠色丁香婷婷综合激情| 在线一区二区三区四区五区| 一区久久精品| 午夜精品福利电影| 一区二区三区四区五区视频 | 一本久久综合亚洲鲁鲁| 亚洲成色最大综合在线| 亚洲欧美另类中文字幕| 亚洲精品在线看| 久久人人97超碰精品888| 欧美亚洲综合在线| 欧美调教vk| 亚洲黄色免费电影| 亚洲第一成人在线| 欧美中文字幕精品| 久久精品国产亚洲5555| 欧美午夜视频网站| 亚洲精品国产视频| 日韩午夜精品| 欧美激情第三页| 欧美国产日产韩国视频| 久久另类ts人妖一区二区| 午夜激情久久久| 欧美午夜影院| 亚洲精品九九| 在线视频日韩精品| 欧美日本韩国在线| 亚洲看片一区| 中文在线资源观看视频网站免费不卡| 欧美顶级艳妇交换群宴| 欧美a级一区| 亚洲国产一区二区三区a毛片| 欧美在线视频在线播放完整版免费观看 | 亚洲图片在线| 国产精品久久久久久久app| 99视频精品免费观看| 亚洲视频一区二区免费在线观看| 欧美精品免费在线| 一本色道久久综合亚洲精品不 | 欧美在线观看视频一区二区三区 | 国产一区二区精品久久91| 亚洲欧美文学| 久久久中精品2020中文| 狠狠色丁香婷综合久久| 老司机一区二区三区| 欧美国产一区二区三区激情无套| 亚洲国产婷婷香蕉久久久久久| 蜜臀久久99精品久久久久久9| 亚洲电影下载| 亚洲综合视频网| 海角社区69精品视频| 免费在线观看精品| 一区二区精品在线| 久久久午夜视频| 日韩一区二区精品在线观看| 国产精品久久久久久久久久尿 | 亚洲精品永久免费精品| 欧美日韩国产精品一区| 国产精品99久久久久久白浆小说| 欧美在线影院| 在线观看日韩www视频免费| 欧美成人精品福利| 亚洲伊人伊色伊影伊综合网| 久久综合亚洲社区| 亚洲一本视频| 在线观看欧美日韩| 国产精品成人一区二区三区夜夜夜| 午夜精品久久久久久久男人的天堂 | 亚洲一级免费视频| 韩日午夜在线资源一区二区| 亚洲欧美不卡| 性色一区二区| 亚洲国产导航| 久久精品视频在线看| 亚洲精品日韩在线| 国产亚洲欧美中文| 欧美日韩日本视频| 麻豆国产精品一区二区三区| 一本一本久久a久久精品综合妖精| 久久先锋影音| 香蕉亚洲视频| 亚洲视频导航| 亚洲精品中文字| 经典三级久久| 国产欧美日韩另类一区| 欧美日韩国产综合久久| 裸体一区二区| 久久亚洲精品网站| 久久精品一区二区三区四区| 一本色道久久综合亚洲精品婷婷|