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

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            64位開發(fā)中去除64位平臺(tái)的內(nèi)存錯(cuò)誤方法

               對(duì)新平臺(tái)上應(yīng)用程序的開發(fā)者來說,64位平臺(tái)的穩(wěn)定和可靠,是吸引他們的關(guān)鍵;而任何內(nèi)存錯(cuò)誤問題都會(huì)導(dǎo)致開發(fā)工作的失敗,內(nèi)存錯(cuò)誤最棘手之處在于它是難以捉摸的,找出它們非常困難且要花費(fèi)大量時(shí)間。內(nèi)存錯(cuò)誤不會(huì)在通常意義上的測(cè)試中暴露出來,正是因?yàn)樗鼈儩撛诘挠泻π裕栽诔绦蚨ㄐ椭埃コ械膬?nèi)存問題就顯得非

             

            常必要了。

              目前有一些強(qiáng)大的內(nèi)存錯(cuò)誤檢測(cè)工具,它們可以在運(yùn)行于雙核心處理器的應(yīng)用程序中,找出導(dǎo)致線程內(nèi)存錯(cuò)誤的原因;它可在傳統(tǒng)測(cè)試技術(shù)找不出問題的地方,找出并修正那些難以捉摸、導(dǎo)致程序崩潰的"元兇"。錯(cuò)誤檢測(cè)工具可幫助你在發(fā)布程序之前,找出并修正那些C/C++內(nèi)存錯(cuò)誤,而在移植程序之前修正這些問題,可提高在新平臺(tái)新架構(gòu)上的程序質(zhì)量,使移植過程更加流水線化,并且使老程序更加健壯可靠。

              為何移植如此之難?

              在向64位處理器或新硬件移植代碼時(shí)產(chǎn)生的問題當(dāng)中,大多數(shù)開發(fā)者是負(fù)有主要責(zé)任的。就此來說,代碼在移植到新平臺(tái)或新架構(gòu)之上時(shí),內(nèi)存問題似乎也成倍增長(zhǎng)了。

              在過渡到64位架構(gòu)時(shí)最基本的問題,就是對(duì)各種不同的int和指針在比特位長(zhǎng)度上假定。在從long轉(zhuǎn)換到int時(shí),不管是賦值還是顯式轉(zhuǎn)換,都存在著一定的隱含限制。前者可能產(chǎn)生一個(gè)編譯器警告,而后者可能被無聲地接受,就此導(dǎo)致了運(yùn)行時(shí)的各種錯(cuò)誤。另一個(gè)問題就是int常量并不總是與int同樣大小,這是混淆有符號(hào)和無符號(hào)常量的問題,同時(shí),適當(dāng)?shù)厥褂糜嘘P(guān)的后綴可以減少此類問題的發(fā)生。

              另一些問題的主要原因是各種指針類型的不匹配。舉例來說,在多數(shù)64位架構(gòu)上,指針類型不能再放入一個(gè)int中,而那些把指針值儲(chǔ)存在int變量中的代碼,此時(shí)當(dāng)然就會(huì)出錯(cuò)了。

              這些問題通常會(huì)在移植過程中暴露出來,因?yàn)橐浦矎谋举|(zhì)上來說是一種變體測(cè)試。當(dāng)你在移植代碼時(shí),實(shí)際上是在創(chuàng)建一種"同等變體"(對(duì)原始代碼的小幅改動(dòng),不會(huì)影響到測(cè)試的結(jié)果),而通過這些"同等變體",可找出許多不常見的錯(cuò)誤。在C/C++中,創(chuàng)建和運(yùn)行"同等變體",可揭示出以下問題:

              1、缺少拷貝構(gòu)造函數(shù)或錯(cuò)誤的拷貝構(gòu)造函數(shù)

              2、缺少或不正確的構(gòu)造函數(shù)

              3、初始化代碼的錯(cuò)誤順序

              4、指針操作的問題

              5、依賴未定義的行為,如求值的順序

              在準(zhǔn)備移植應(yīng)用程序時(shí),有以下幾個(gè)相關(guān)步驟

              第1步、在移植之前,要保證原始代碼中沒有諸如內(nèi)存崩潰、內(nèi)存泄露等問題,找出指針類型和int錯(cuò)誤的最有效的一個(gè)方法是,采用平衡變體測(cè)試,來達(dá)到運(yùn)行時(shí)錯(cuò)誤檢測(cè)的目的。

              變體測(cè)試最先是為解決無法計(jì)量測(cè)試的準(zhǔn)確性問題而產(chǎn)生的,大致如下:假定已有了一個(gè)完美的測(cè)試方案,它已經(jīng)覆蓋了所有的可能性,再假定已有一個(gè)完美的程序通過了這個(gè)測(cè)試,接下來修改代碼(稱之為變異),在測(cè)試方案中運(yùn)行這個(gè)"變異"后的程序(稱之為變體),將會(huì)有兩個(gè)可能的情況:

              一是程序會(huì)受代碼改變的影響,并且測(cè)試方案檢測(cè)到了,在此假定測(cè)試方案是完美的,這意味著它可以檢測(cè)一切改變。此時(shí)變體被稱作"已死的變體"

              二是程序沒受改變的影響,而測(cè)試方案也沒有檢測(cè)到這個(gè)變體。此時(shí)變體稱作"同等變體"

              如果拿"已死變體"和已生成的變體作對(duì)比,就會(huì)發(fā)現(xiàn)這個(gè)比率要小于1,這個(gè)數(shù)字表示程序?qū)Υa改變有多敏感。事實(shí)上,完美的測(cè)試方案和完美的程序都不存在,這就說上面的兩種情況可能會(huì)有一個(gè)發(fā)生。

              程序受影響的結(jié)果因個(gè)體而異,如果測(cè)試方案不適當(dāng),將無法檢測(cè)到。"已經(jīng)變體""生成變體"的比率小于1同時(shí)也揭示了測(cè)試方案有多精確。

              在實(shí)踐中,往往無法區(qū)分測(cè)試方案不精確與同等變體之間的關(guān)系。由于缺乏其他的可能性,在此我們只好把"已死變體"對(duì)所有變體的比率,看成是測(cè)試方案的精確程度。

              例1test1.c)證實(shí)了以上的說法(此處所有的代碼均在Linux下編譯),test1.c用以下命令編譯:

             

            cc -o test1 test1.c.

            main(argc, argv) /* line 1 */
            int argc; /* line 2 */
            char *argv[]; /* line 3 */
            { /* line 4 */
            int c=0; /* line 5 */
            /* line 6 */
            if(atoi(argv[1]) < 3){ /* line 7 */
            printf("Got less than 3\n"); /* line 8 */
            if(atoi(argv[2]) > 5) /* line 9 */
            c = 2; /* line 10 */
            } /* line 11 */
            else /* line 12 */
            printf("Got more than 3\n"); /* line 13 */
            exit(0); /* line 14 */
            } /* line 15 */


              例1:程序test1.c

              這個(gè)簡(jiǎn)單的程序讀取輸入的參數(shù),并打印出相關(guān)的信息。現(xiàn)在假定用一個(gè)測(cè)試方案來測(cè)試此程序:

            Test Case 1:
            input 2 4
            output Got less than 3
            Test Case 2:
            input 4 4
            output Got more than 3
            Test Case 3:
            input 4 6
            output Got more than 3
            Test Case 4:
            input 2 6
            output Got less than 3
            Test Case 5:
            input 4
            output Got more than 3


              這個(gè)測(cè)試方案在業(yè)界是有一定代表性的,它進(jìn)行正則測(cè)試,表示它將測(cè)試對(duì)所有正確的輸入,程序是否有正確的輸出,而忽視非法的輸入。程序test1完全通過測(cè)試,但它也許隱藏著嚴(yán)重的錯(cuò)誤。

              現(xiàn)在,對(duì)程序進(jìn)行"變體",用以下簡(jiǎn)單的改變:

            Mutant 1: change line 9 to the form
            if(atoi(argv[2]) <= 5)
            Mutant 2: change line 7 to the form
            if(atoi(argv[1]) >= 3)
            Mutant 3: change line 5 to the form
            int c=3;


              如果在測(cè)試方案中運(yùn)行此修改后的程序,Mutants 13完全通過測(cè)試,而Mutant 2則無法通過。

                Mutants 13沒有改變程序的輸出,所以是同等變體,而測(cè)試方案沒有檢測(cè)

             

            到它們。Mutant 2不是同等變體,故Test Cases 1-4將會(huì)檢測(cè)到程序的錯(cuò)誤輸出,而Test Case 5在不同的電腦上可能會(huì)有不同的表現(xiàn)。以上表明,程序的錯(cuò)誤輸出,可看作是程序可能會(huì)崩潰的一個(gè)信號(hào)。

              我們統(tǒng)計(jì)一下,共創(chuàng)建了三個(gè)變體,而只被發(fā)現(xiàn)了一個(gè),這說明表示測(cè)試方案的質(zhì)量為1/3,正如你看到的,1/3有點(diǎn)低,之所以低是因?yàn)楫a(chǎn)生了兩個(gè)同等變體。這個(gè)數(shù)字應(yīng)當(dāng)作是測(cè)試不足的一個(gè)警告,實(shí)際上,測(cè)試方案應(yīng)檢測(cè)到程序中的

             

            兩個(gè)嚴(yán)重錯(cuò)誤。

              再回到Mutant 2,在Test Case 5中運(yùn)行它,如果程序崩潰了,那這個(gè)變體測(cè)試不但計(jì)量到了測(cè)試方案的質(zhì)量,還檢測(cè)到了嚴(yán)重的錯(cuò)誤,這就是變體測(cè)試發(fā)現(xiàn)錯(cuò)誤的方法。

            main(argc, argv) /* line 1 */
            int argc; /* line 2 */
            char *argv[]; /* line 3 */
            { /* line 4 */
            int c=0; /* line 5 */
            int a, b; /* line 6 */
            /* line 7 */
            a = atoi(argv[1]); /* line 8 */
            b = atoi(argv[2]); /* line 9 */
            if(a < 3){ /* line 10 */
            printf("Got less than 3\n"); /* line 12 */
            if(b > 5) /* line 13 */
            c = 2; /* line 14 */
            } /* line 15 */
            else /* line 16 */
            printf("Got more than 3\n"); /* line 17 */
            exit(0); /* line 18 */
            } /* line 19 */


              例2:同等變體

              在例2中的同等變體(Mutant 4),它和前一個(gè)變體的不同之處在于,Mutant 4是同等變體,這意味著它在構(gòu)建時(shí)的目的,就是要使修改后的程序如同原始程序一樣運(yùn)行。如果在測(cè)試方案中運(yùn)行Mutant 4,那么Test Case 5大概會(huì)失敗--程序?qū)⒈罎ⅰ4颂幈砻鳎ㄟ^創(chuàng)建一個(gè)同行變體,實(shí)際上是增強(qiáng)了測(cè)試方案的檢測(cè)力度,由此得出的結(jié)論是,有以下兩種方法,可提高測(cè)試方案的精確性:

              ·在測(cè)試方案中增加測(cè)試數(shù)量

              ·在測(cè)試方案中運(yùn)行同等變體

              這兩點(diǎn)是非常重要的,尤其是第二點(diǎn),因?yàn)樗C明了變體可提高測(cè)試的有效性。在這些例子中,是由手工創(chuàng)建了每一個(gè)變體,并且對(duì)每一個(gè)程序都作了單獨(dú)的修改,這個(gè)步驟費(fèi)時(shí)又費(fèi)力,但是自動(dòng)生成同等變體是有可能的,正如例3所演示的,這個(gè)程序沒有輸入,只有一個(gè)輸出,原則上來說,它只需要一次測(cè)試:

            int doublew(x)
            int x;
            { return x*2; }

            int triple( y)
            int y;
            { return y*3; }

            main() {
            int i = 2;
            printf("Got %d \n", doublew(i++)+ triple(i++));
            }


              例3:自動(dòng)生成變體

            Test Case 1:
            input none
            output 12


              有意思的是,這個(gè)程序因編譯器的差異,而分別給出答案1312(注:譯者在Visual C++ 2005中,得出的結(jié)果是10)。假設(shè)你要編寫一個(gè)這樣的程序,還要能在兩個(gè)不同的平臺(tái)上運(yùn)行,如果不同平臺(tái)上的編譯器有所差異,此時(shí)你會(huì)察覺到這個(gè)程序的不同,疑問由此而生:"是哪錯(cuò)了?"這有可能就是導(dǎo)致問題產(chǎn)生的原因。

              試想你在例4中創(chuàng)建了一個(gè)同等變體,此時(shí)這個(gè)程序的結(jié)果不依賴于編譯器,實(shí)際上應(yīng)是13,這也是在預(yù)料之中的。但一旦運(yùn)行變體測(cè)試,就會(huì)發(fā)現(xiàn)錯(cuò)誤了。

            int doublew(x)
            int x;
            { return x*2; }

            int triple( y)
            int y;
            { return y*3; }

            main() {
            int i = 2;
            int a, b;

            a = doublew(i++);
            b = triple(i++);
            printf("Got %d \n", a+b);
            }


              例4:一個(gè)變體

              在變體測(cè)試中,最讓人驚奇的是,它能找出正常看來是不可能檢測(cè)到的錯(cuò)誤,通常,這些錯(cuò)誤隱藏得很深,直到程序崩潰時(shí),才可能發(fā)現(xiàn),但對(duì)此,程序員經(jīng)常不能理解。同等變體是找出錯(cuò)誤的機(jī)會(huì),而不是其他。但普遍來說,程序員期望同等變體能得出與原程序一樣的結(jié)果,但如果總是這樣的話,那同等變體是沒有任何作用了。

              第2步:當(dāng)清除最致命的錯(cuò)誤之后,要把那些可能會(huì)出錯(cuò)的代碼在移植之前,用靜態(tài)分析工具再確認(rèn)一遍。在靜態(tài)分析時(shí),有兩個(gè)主要的工作要做:

              ·找出并修正那些移植到新平臺(tái)之后可能會(huì)出錯(cuò)的代碼

              ·找出并修正那些可能不能很好地被移植的代碼

                首先,要用業(yè)界推薦的C/C++編碼標(biāo)準(zhǔn)來檢查那些可能在新平臺(tái)上出錯(cuò)的代碼,以確認(rèn)其編碼結(jié)構(gòu)沒有問題。通過確認(rèn)代碼符合編碼標(biāo)準(zhǔn),可防止不必要的錯(cuò)誤發(fā)生,還能減少在新平臺(tái)上的調(diào)試工作量,并降低在最終產(chǎn)品中出現(xiàn)bug的機(jī)率。

              以下是一些可用的編碼標(biāo)準(zhǔn):

              不要返回對(duì)一個(gè)局部對(duì)象或?qū)υ诤瘮?shù)內(nèi)用"new"初始化的指針

             

            的引用。對(duì)一個(gè)局部對(duì)象返回一個(gè)引用,可能會(huì)導(dǎo)致堆棧崩潰;而返回一個(gè)對(duì)在函數(shù)內(nèi)用"new"初始化的指針的引用,可能會(huì)引起內(nèi)存泄漏。

              不要轉(zhuǎn)換一個(gè)常量到非常量。這可能會(huì)導(dǎo)致數(shù)值被改變,從而破壞數(shù)據(jù)的完整性。這也會(huì)降低代碼的可讀性,因?yàn)槟悴荒茉偌俣ǔA坎槐桓淖儭?span lang="EN-US">

              如果某個(gè)類有虛擬成員函數(shù),它最好也帶有一個(gè)虛擬析構(gòu)函數(shù)。這能在繼承類中防止內(nèi)在泄漏。帶有任何虛擬成員函數(shù)的類,通常被用作基類,此時(shí)它應(yīng)有一個(gè)虛擬析構(gòu)函數(shù),以保證繼承類通過一個(gè)指向基類的指針來引用時(shí),相應(yīng)的析構(gòu)函數(shù)會(huì)被調(diào)用。

              公共成員函數(shù)必須為成員數(shù)據(jù)返回常量句柄。當(dāng)把一個(gè)非常量的句柄提供給成員數(shù)據(jù)時(shí),此時(shí)調(diào)用者可在成員函數(shù)之外修改成員數(shù)據(jù),這就破壞了類的封裝性。

              不要把指向一個(gè)類的指針,轉(zhuǎn)換成指向另一個(gè)類的指針,除非它們之間有繼承關(guān)系。這種無效的

             

            轉(zhuǎn)換將導(dǎo)致不受控的指針、數(shù)據(jù)崩潰等問題,或者其他錯(cuò)誤。

              不要從一個(gè)構(gòu)造函數(shù)中直接訪問一個(gè)全局變量。C++語言的定義之中,沒有規(guī)定在不同的代碼單元中定義的靜態(tài)對(duì)象初始化的順序。因此,在從一個(gè)構(gòu)造函數(shù)中訪問一個(gè)全局變量時(shí),這個(gè)變量可能還沒有初始化。

              當(dāng)找到并修正有錯(cuò)誤的代碼之后,從那些在當(dāng)前平臺(tái)上運(yùn)行良好的代碼中再繼續(xù)找,因?yàn)樗鼈兛赡懿荒鼙缓芎玫匾浦病R韵率且恍?duì)大多數(shù)64位移植項(xiàng)目都適用的規(guī)則:

              盡量使用標(biāo)準(zhǔn)類型。比如說,使用size_t而不是int。如果想要一個(gè)無符號(hào)的64int,那么請(qǐng)使用uint64_t。這個(gè)習(xí)慣不但有助于找出和防止代碼中的bug,還能在將來向128位處理器移植程序時(shí),幫上大忙。

              檢查現(xiàn)有代碼中long數(shù)據(jù)類型的用法。如果變量、域、參數(shù)中數(shù)值的變化范圍,只在2Gig-1-2Gig4Gig0之間,那么最好分別使用int32_tuint32_t

              檢查所有的"窄向"賦值。應(yīng)該避免這種情況出現(xiàn),因?yàn)榘岩粋€(gè)long賦值給一個(gè)int,在64位數(shù)值上會(huì)導(dǎo)致截?cái)唷?span lang="EN-US">

              找出"窄向"轉(zhuǎn)換。應(yīng)只在表達(dá)式中使用窄向轉(zhuǎn)換,而不是在操作數(shù)中。

              找出那些把long*轉(zhuǎn)換成int*,或把int*轉(zhuǎn)換成long*的地方。在32位環(huán)境下,這也許是可交替的,但在64位中不行,并檢查所有的不匹配指針賦值。

              找出那些在乘法符號(hào)的兩端,沒有long操作數(shù)的表達(dá)式。要使int型表達(dá)式將產(chǎn)生64位結(jié)果,至少其中的一個(gè)操作數(shù)是longunsigned long

              找出long型值用int初始化的地方。應(yīng)避免這種類型的初始化,因?yàn)樯踔猎?span lang="EN-US">64位類型的表達(dá)式中,int常量也可能只是代表一個(gè)32位類型。

              找出那些對(duì)int進(jìn)行移位操作,又把結(jié)果賦給long的地方。如果結(jié)果是64位值,最好使用64位乘法。

              找出那些64位表達(dá)式中的int常量。在64位表達(dá)式中應(yīng)使用64位值。

              找出把指針轉(zhuǎn)換成int的地方。涉及指針與int互轉(zhuǎn)換的代碼,應(yīng)仔細(xì)檢查。

              檢查內(nèi)聯(lián)匯編語句。因?yàn)樗豢赡鼙缓芎玫匾浦病?span lang="EN-US">

              第3步:重復(fù)一遍運(yùn)行時(shí)錯(cuò)誤檢測(cè),以確認(rèn)所有的修改都沒有引入新的運(yùn)行時(shí)錯(cuò)誤。

              第4步:此時(shí),你可選擇進(jìn)行更多的測(cè)試步驟,以保證在移植之前,所有的代碼都完全正確。這個(gè)額外的步驟是單元測(cè)試,單元測(cè)試是在每一個(gè)軟件單元完成之后進(jìn)行的傳統(tǒng)測(cè)試,它在開發(fā)階段的后期,也是有益的。因?yàn)樵趩卧?jí)別,很容易設(shè)計(jì)出每個(gè)函數(shù)的輸入,它將有助于更快地找出那些在應(yīng)用級(jí)別測(cè)試中無法發(fā)現(xiàn)的錯(cuò)誤。

              找出64位處理器上的問題

              也許64位處理器本身就有問題,如果是這樣的話,下面的步驟應(yīng)該有用: 第1步:在64位處理器上重新編譯應(yīng)用程序。在編譯中如果有問題,應(yīng)考慮是不是因編譯器的不同而產(chǎn)生的。

              第2步:一旦重新編譯代碼,應(yīng)進(jìn)行代碼檢查,以確保新代碼都遵循適當(dāng)?shù)木幋a標(biāo)準(zhǔn)。在這一點(diǎn)上,任何人都不希望每一次修改都帶來一個(gè)錯(cuò)誤,此時(shí)解決好過在程序運(yùn)行時(shí)才發(fā)現(xiàn)。

              第3步:鏈接并生成應(yīng)用程序。

              第4步:應(yīng)試著運(yùn)行程序。如果在64位處理器上,運(yùn)行程序時(shí)發(fā)現(xiàn)了問題,應(yīng)使用單元測(cè)試方法一個(gè)函數(shù)一個(gè)函數(shù)地去找,這樣能確定哪些代碼沒有正確地被移植;修正這些問題直到程序可以運(yùn)行。

              第5步:重復(fù)運(yùn)行時(shí)錯(cuò)誤檢測(cè)。

              一旦程序可以運(yùn)行,一定要重復(fù)一遍運(yùn)行時(shí)錯(cuò)誤檢測(cè),因?yàn)橐浦策^程很可能導(dǎo)致新的問題產(chǎn)生,例如新的內(nèi)存崩潰或程序工作方式有所不同。如果運(yùn)行時(shí)錯(cuò)誤檢測(cè)發(fā)現(xiàn)了錯(cuò)誤,那么此時(shí)趕快修正它。

              結(jié)論

              遵循此文中提及的方法,可在程序發(fā)布之前,找到并修正C/C++內(nèi)存錯(cuò)誤,并可以節(jié)省下數(shù)周的調(diào)試時(shí)間,使用戶免受"災(zāi)難"之苦。

             

            posted on 2009-09-08 00:35 肥仔 閱讀(2328) 評(píng)論(6)  編輯 收藏 引用 所屬分類: Windows開發(fā)

            評(píng)論

            # re: 64位開發(fā)中去除64位平臺(tái)的內(nèi)存錯(cuò)誤方法  回復(fù)  更多評(píng)論   

            Lots of specialists claim that <a href="http://lowest-rate-loans.com/topics/mortgage-loans">mortgage loans</a> aid people to live their own way, just because they can feel free to buy needed things. Moreover, various banks give credit loan for all people.
            2010-06-30 07:34 | JuanitaGoodwin34

            # re: 64位開發(fā)中去除64位平臺(tái)的內(nèi)存錯(cuò)誤方法  回復(fù)  更多評(píng)論   

            Lots of college students become embarrassed because of academic papers composing. However, clever people order coursework online and have advantages.
            2010-07-06 21:09 | buy coursework online

            # re: 64位開發(fā)中去除64位平臺(tái)的內(nèi)存錯(cuò)誤方法  回復(fù)  更多評(píng)論   

            Your knowledge related to this good topic is supreme! Thence scholars not have to accomplish the dissertation writing or essay thesis by their own efforts, they should get your support.
            2010-07-09 00:51 | dissertation writing service

            # re: 64位開發(fā)中去除64位平臺(tái)的內(nèi)存錯(cuò)誤方法  回復(fù)  更多評(píng)論   

            Students have to remember that the perfect essay writing service can help to have good grades, accomplishing the great quality sample essay. So, it's your own choice to buy custom essays or to spend hours for writing!
            2010-07-15 06:29 | custom term paper

            # re: 64位開發(fā)中去除64位平臺(tái)的內(nèi)存錯(cuò)誤方法  回復(fù)  更多評(píng)論   

            There is no automatic ways of research papers. Professional writers who are employed at the writing services work very hard to write the best papers!
            2011-09-30 04:18 | essay service

            # re: 64位開發(fā)中去除64位平臺(tái)的內(nèi)存錯(cuò)誤方法  回復(fù)  更多評(píng)論   

            Do you have papers completing difficulties? Doubt no more and buy essays, just because it's the best way out.
            2011-10-23 02:27 | essay writing
            精品综合久久久久久888蜜芽| 久久笫一福利免费导航 | 亚洲va久久久噜噜噜久久男同| 久久亚洲国产最新网站| 久久婷婷五月综合97色| 久久精品国产99国产精偷| 亚洲国产精品无码久久久久久曰| 欧美牲交A欧牲交aⅴ久久 | 久久精品人人做人人爽电影| 91久久精品视频| 久久久久久久女国产乱让韩| 精品久久久久久国产| 欧美亚洲国产精品久久高清| 久久久综合九色合综国产| 亚洲欧美日韩精品久久亚洲区 | 欧美精品丝袜久久久中文字幕 | 亚洲精品乱码久久久久久按摩| 亚洲精品无码久久久影院相关影片| jizzjizz国产精品久久| 午夜精品久久久久9999高清| 久久精品国产精品青草app| 久久人妻AV中文字幕| 久久一区二区三区免费| 国产成人AV综合久久| 久久久精品国产sm调教网站| 色诱久久av| 久久人人爽人人澡人人高潮AV | 久久久久噜噜噜亚洲熟女综合| 香蕉久久永久视频| 久久99精品国产麻豆不卡| 久久97精品久久久久久久不卡| 99精品国产综合久久久久五月天| 日韩精品无码久久一区二区三| 品成人欧美大片久久国产欧美... 品成人欧美大片久久国产欧美 | 99久久国产亚洲高清观看2024| 99久久超碰中文字幕伊人| 久久久久se色偷偷亚洲精品av| 久久经典免费视频| 欧美日韩精品久久免费| 亚洲欧美伊人久久综合一区二区 | 久久精品国产亚洲AV麻豆网站 |