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

曠野的呼聲

路漫漫其修遠(yuǎn)兮 吾將上下而求索

常用鏈接

統(tǒng)計(jì)

最新評(píng)論

【轉(zhuǎn)帖】Rational Purify 使用及分析實(shí)例

Rational Purify 使用及分析實(shí)例

developerWorks

級(jí)別: 初級(jí)

蔡 林, IBM 中國(guó)軟件開發(fā)中心軟件工程師

2006 年 2 月 23 日

本文介紹了 IBM Rational Purify的基本概念和在不同操作系統(tǒng)中使用Purify對(duì)C/C++源程序中存在的內(nèi)存問(wèn)題進(jìn)行勘察和分析,并且提供了有關(guān)的實(shí)例以便讀者在實(shí)際操作中作為參考。

簡(jiǎn)介

本文介紹了IBM Rational Purify的基本概念和在不同操作系統(tǒng)中使用Purify對(duì)C/C++源程序中存在的內(nèi)存問(wèn)題進(jìn)行勘察和分析,并且提供了有關(guān)的實(shí)例以便讀者在實(shí)際操作中作為參考。






1.內(nèi)存問(wèn)題的原因及分類

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

總的說(shuō)來(lái),與內(nèi)存有關(guān)的問(wèn)題可以分成兩類:內(nèi)存訪問(wèn)錯(cuò)誤和內(nèi)存使用錯(cuò)誤。內(nèi)存訪問(wèn)錯(cuò)誤包括錯(cuò)誤地讀取內(nèi)存和錯(cuò)誤地寫內(nèi)存。錯(cuò)誤地讀取內(nèi)存可能讓你的模塊返回意想不到的結(jié)果,從而導(dǎo)致后續(xù)的模塊運(yùn)行異常。錯(cuò)誤地寫內(nèi)存可能導(dǎo)致系統(tǒng)崩潰。內(nèi)存使用方面的錯(cuò)誤主要是指申請(qǐng)的內(nèi)存沒(méi)有正確釋放,從而使程序運(yùn)行逐漸減慢,直至停止。這方面的錯(cuò)誤由于表現(xiàn)比較慢很難被人工察覺。程序也許運(yùn)行了很久才會(huì)耗凈資源,發(fā)生問(wèn)題。

1.1 內(nèi)存解剖

一個(gè)典型的C++內(nèi)存布局如下圖所示:



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

1.2 內(nèi)存訪問(wèn)錯(cuò)誤

相對(duì)用戶使用的語(yǔ)言,動(dòng)態(tài)內(nèi)存的申請(qǐng)一般由malloc/new來(lái)完成,釋放由free/delete完成。基本的原則可以總結(jié)為:一對(duì)一,不混用。也就是說(shuō)一個(gè)malloc必須對(duì)應(yīng)一且唯一的free;new對(duì)應(yīng)一且唯一的delete; malloc不能和delete, new不能和free對(duì)應(yīng)。另外在C++中要注意delete和delete[]的區(qū)別。delete用來(lái)釋放單元變量,delete[]用來(lái)釋放數(shù)組等集聚變量。有關(guān)這方面的詳細(xì)信息可以參考[C++Adv]。

我們可以將內(nèi)存訪問(wèn)錯(cuò)誤大致分成以下幾類:數(shù)組越界讀或?qū)憽⒃L問(wèn)未初始化內(nèi)存、訪問(wèn)已經(jīng)釋放的內(nèi)存和重復(fù)釋放內(nèi)存或釋放非法內(nèi)存。

下面的代碼集中顯示了上述問(wèn)題的典型例子:


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行分配內(nèi)存時(shí),忽略了字符串終止符"\0"所占空間導(dǎo)致了第8行的數(shù)組越界寫(Array Bounds Write)和第9行的數(shù)組越界讀(Array Bounds Read); 在第7行,打印尚未賦值的str2將產(chǎn)生訪問(wèn)未初始化內(nèi)存錯(cuò)誤(Uninitialized Memory Read);在第11行使用已經(jīng)釋放的變量將導(dǎo)致釋放內(nèi)存讀和寫錯(cuò)誤(Freed Memory Read and Freed Memory Write);最后由于str3和str2所指的是同一片內(nèi)存,第12行又一次釋放了已經(jīng)被釋放的空間 (Free Freed Memory)。

這個(gè)包含許多錯(cuò)誤的程序可以編譯連接,而且可以在很多平臺(tái)上運(yùn)行。但是這些錯(cuò)誤就像定時(shí)炸彈,會(huì)在特殊配置下觸發(fā),造成不可預(yù)見的錯(cuò)誤。這就是內(nèi)存錯(cuò)誤難以發(fā)現(xiàn)的一個(gè)主要原因。

1.3 內(nèi)存使用錯(cuò)誤

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






2.Purify的原理及使用

IBM Rational PurifyPlus是一組程序運(yùn)行時(shí)的分析軟件。她包括了程序性能瓶頸分析軟件Quantify, 程序覆蓋面分析軟件PureCoverage,和本文的主角:程序運(yùn)行錯(cuò)誤分析軟件Purify。Purify可以發(fā)現(xiàn)程序運(yùn)行時(shí)的內(nèi)存訪問(wèn),內(nèi)存泄漏和其他難以發(fā)現(xiàn)的問(wèn)題。

同時(shí)她也是市場(chǎng)上唯一支持多種平臺(tái)的類似工具,并且可以和很多主流開發(fā)工具集成。Purify可以檢查應(yīng)用的每一個(gè)模塊,甚至可以查出復(fù)雜的多線程或進(jìn)程應(yīng)用中的錯(cuò)誤。另外她不僅可以檢查C/C++,還可以對(duì)Java或.NET中的內(nèi)存泄漏問(wèn)題給出報(bào)告。

2.1 Purify的原理

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

對(duì)于所有程序中使用的動(dòng)態(tài)內(nèi)存,Purify將它們按照狀態(tài)進(jìn)行歸類。這可以由下圖來(lái)說(shuō)明(來(lái)自[DEV205]):



參見本文中以上給出的代碼,在程序第5行執(zhí)行后,str2處于黃色狀態(tài)。當(dāng)在第7行進(jìn)行讀的時(shí)候,系統(tǒng)就會(huì)報(bào)告一個(gè)訪問(wèn)未初始化內(nèi)存錯(cuò)誤(Uninitialized Memory Read)。因?yàn)橹挥性诰G色狀態(tài)下,內(nèi)存才可以被合法訪問(wèn)。

為了檢查數(shù)據(jù)越界錯(cuò)誤(ABR,ABW),Purify還在每個(gè)分配的內(nèi)存前后插入了紅色區(qū)域。這樣一來(lái),超過(guò)邊界的訪問(wèn)指令必定落在非法區(qū)域,從而觸發(fā)ABR或者ABW錯(cuò)誤報(bào)告。這里需要指出一點(diǎn)。訪問(wèn)未初始化內(nèi)存錯(cuò)誤UMR在某些情況下其實(shí)是合法的操作,例如內(nèi)存拷貝。所以在分析報(bào)告時(shí)可以把UMR放到最后,或者干脆從結(jié)果中濾除。

2.2 Purify的使用

這里簡(jiǎn)單介紹一下Purify在Windows和UNIX環(huán)境下的使用。

在Windows中,只要運(yùn)行Purify,填入需要分析的程序及參數(shù)就可。Purify會(huì)自動(dòng)插入檢測(cè)代碼并顯示報(bào)告。報(bào)告的格式如下(來(lái)自[DEV205]):



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

在UNIX系統(tǒng)中,使用Purify需要重新編譯程序。通常的做法是修改Makefile中的編譯器變量。下面是用來(lái)編譯本文中程序的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
                        

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

下面是本文中的程序在Linux上Purify運(yùn)行的結(jié)果:


    ****  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
                        

我們對(duì)照程序可以發(fā)現(xiàn)Purify查出了程序中所有的錯(cuò)誤。對(duì)于每個(gè)錯(cuò)誤,她不但給出了源代碼的位置還指出這些內(nèi)存最初分配的源代碼位置。這對(duì)于查找問(wèn)題提供了很大幫助。對(duì)于程序12行的解釋,Purify將其認(rèn)為是不匹配的內(nèi)存釋放(FMM: Freeing mismatched memory),因?yàn)樗J(rèn)為這樣的釋放方式不符合嚴(yán)格的規(guī)定。

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



2.3 Purify的一些特性

這里簡(jiǎn)單介紹一下Purify提供的幾個(gè)特性。有關(guān)這些特性的詳細(xì)信息,請(qǐng)查閱文檔[Purify]。

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





3.總結(jié)

當(dāng)使用C/C++進(jìn)行開發(fā)時(shí),采用良好的一致的編程規(guī)范是防止內(nèi)存問(wèn)題第一道也是最重要的措施。在此前提下,IBM Rational Purify作為一種運(yùn)行時(shí)分析軟件可以很好地幫助您發(fā)現(xiàn)忽略的內(nèi)存問(wèn)題,或成為軟件自動(dòng)測(cè)試中的一個(gè)重要組成部分。






4.參考資料

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



關(guān)于作者

 

蔡林,IBM 中國(guó)軟件開發(fā)中心軟件工程師,2004年獲得美國(guó)Baylor University計(jì)算機(jī)系碩士學(xué)位,同年加入IBM 中國(guó)軟件開發(fā)中心,從事Rational ClearQuest G11N的開發(fā)工作。

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


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   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>
            亚洲人www| 国产欧美精品日韩区二区麻豆天美| 亚洲欧美日韩一区二区三区在线观看 | 欧美日韩国产在线播放网站| 亚洲欧美日韩一区二区三区在线观看| 欧美aa在线视频| 欧美阿v一级看视频| 久久久久久久久综合| 久久视频这里只有精品| 媚黑女一区二区| 久久久久久久网| 欧美一区二区三区视频在线| 亚洲影视九九影院在线观看| 一二三区精品福利视频| 亚洲一区二区日本| 欧美一区影院| 欧美成人中文| 国产美女高潮久久白浆| 韩国精品一区二区三区| 狠久久av成人天堂| 在线视频免费在线观看一区二区| 一区二区三区精品国产| 牛夜精品久久久久久久99黑人 | 国产精品入口日韩视频大尺度| 国产午夜精品一区二区三区欧美 | 亚洲少妇一区| 久久久久国产精品www| 国产精品久久亚洲7777| 亚洲国产精品一区二区第四页av| 久久av红桃一区二区小说| 亚洲精品日本| 欧美日韩的一区二区| 亚洲国产女人aaa毛片在线| 巨胸喷奶水www久久久免费动漫| 9i看片成人免费高清| 欧美激情五月| 一本色道久久综合亚洲91| 亚洲欧洲在线观看| 欧美大片在线观看一区二区| 99热免费精品| 亚洲天堂av在线免费| 蜜桃精品久久久久久久免费影院| 一区二区三区国产精品| 欧美亚州一区二区三区| 欧美亚洲色图校园春色| 久久精品国产清高在天天线| 在线播放日韩欧美| 亚洲三级免费电影| 国产农村妇女精品一区二区| 欧美中文字幕不卡| 久久午夜av| 亚洲欧美精品在线观看| 久久精品人人爽| 亚洲欧美色一区| 久久男人资源视频| 亚洲一区美女视频在线观看免费| 午夜精品福利在线观看| 亚洲韩国日本中文字幕| 亚洲香蕉在线观看| 亚洲国产精品久久久久秋霞影院 | 久久爱91午夜羞羞| 美女日韩欧美| 欧美一区午夜精品| 欧美日韩伦理在线| 欧美国产在线观看| 激情欧美日韩| 久久久午夜精品| 久久精品国产一区二区三区| 欧美精品在线观看| 亚洲人成网站影音先锋播放| 亚洲电影av在线| 久久久久久婷| 日韩图片一区| 农村妇女精品| 国内精品久久久久久久97牛牛| 亚洲美女区一区| 中文成人激情娱乐网| 欧美日韩视频第一区| 亚洲精品欧美激情| 亚洲小少妇裸体bbw| 欧美视频在线免费| 欧美在线观看视频在线 | 国产在线日韩| 久热成人在线视频| 最近中文字幕日韩精品| 亚洲伦理精品| 国内成人在线| 欧美日本一区二区三区| 亚洲欧美日本视频在线观看| 欧美与黑人午夜性猛交久久久| 韩日欧美一区二区| 欧美三级在线视频| 麻豆9191精品国产| 亚洲天堂久久| 亚洲清纯自拍| 牛牛国产精品| 久久久久免费视频| 一区二区三区波多野结衣在线观看| 国内久久婷婷综合| 国产精品亚洲第一区在线暖暖韩国| 久久久久一区二区| 午夜亚洲性色视频| 宅男噜噜噜66一区二区| 亚洲高清影视| 农夫在线精品视频免费观看| 午夜精彩视频在线观看不卡| 99综合在线| 一本色道**综合亚洲精品蜜桃冫 | 久久精品人人爽| 亚洲激情视频在线播放| 午夜在线一区| 性色一区二区| 欧美亚洲视频在线看网址| 亚洲麻豆av| 99热在线精品观看| 日韩视频二区| 亚洲图片欧美一区| 亚洲女人天堂成人av在线| 亚洲免费一级电影| 久久av最新网址| 欧美国产大片| 国产精品一区视频网站| 国产一区二区三区高清在线观看| 国产精一区二区三区| 国产精品私房写真福利视频| 狠狠色丁香婷婷综合影院| 激情综合久久| 一本色道**综合亚洲精品蜜桃冫| 亚洲视频一区在线观看| 久久久午夜电影| 亚洲精品免费一二三区| 日韩视频三区| 久久成人免费视频| 国产精品九九| 一区二区三区视频在线| 久久久www成人免费毛片麻豆| 亚洲人成在线影院| 久久免费观看视频| 国产精品影院在线观看| 亚洲精品中文字| 久久久欧美一区二区| 亚洲综合国产激情另类一区| 欧美jizz19性欧美| 在线观看av不卡| 久久亚洲视频| 在线视频你懂得一区二区三区| 久久精品99国产精品| 亚洲一区二区在线视频| 国产精品毛片高清在线完整版| 亚洲激情在线观看| 亚洲日本欧美在线| 欧美日韩123| 欧美亚洲自偷自偷| 久久成人免费网| 在线观看日韩欧美| 亚洲片区在线| 国产精品久久久久久一区二区三区 | 男人的天堂亚洲| 久久青青草综合| 亚洲精品美女在线观看| 亚洲国产成人精品女人久久久| 欧美激情久久久久| 欧美一区二区三区免费观看视频 | 久久最新视频| 欧美日韩在线视频一区| 亚洲一区二区在线播放| 午夜精品福利一区二区三区av| 国产一区91| 亚洲日本va午夜在线影院| 欧美日韩在线免费视频| 女同一区二区| 国产亚洲福利| 日韩一级大片| 日韩午夜免费| 麻豆av一区二区三区| 久久精品123| 国产精品欧美一区喷水| 亚洲国产小视频| 亚洲国产成人精品女人久久久| 这里只有精品视频在线| 亚洲另类自拍| 欧美国产亚洲精品久久久8v| 久久综合中文色婷婷| 欧美激情中文字幕乱码免费| 国产日韩一区二区| 99re6这里只有精品视频在线观看| 激情偷拍久久| 狼人天天伊人久久| 欧美高清自拍一区| 999亚洲国产精| 欧美激情一区二区三区蜜桃视频| 免费成人激情视频| 亚洲国产精品嫩草影院| 免费不卡在线观看| 亚洲激情一区二区| 亚洲手机在线| 国产精品拍天天在线| 亚洲欧美国产一区二区三区| 午夜精品久久久久久久99水蜜桃 | 日韩一区二区免费高清|