国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

跟蹤 UNIX 應(yīng)用程序的解決方案

瀏覽:140日期:2024-06-08 09:48:15

本文示例源代碼或素材下載

開始之前

本教程幫助 Unix 系統(tǒng)開發(fā)人員和管理員以最佳方式跟蹤系統(tǒng)上運行的應(yīng)用程序。要想從本教程獲得最大收獲,您應(yīng)該了解 UNIX 操作系統(tǒng)的基本知識及其操作方式。具備基本的編程經(jīng)驗會有幫助,但不是必需的。

關(guān)于本教程

大多數(shù)開發(fā)人員和系統(tǒng)管理員知道在他們的操作系統(tǒng)和應(yīng)用程序中應(yīng)該會發(fā)生什么情況,但糟糕的是,有時候不是這樣的。當(dāng)應(yīng)用程序崩潰或表現(xiàn)異常時,需要查明更多信息。通過利用對應(yīng)用程序正常工作方式的了解和一些基本 UNIX 技能,可以跟蹤應(yīng)用程序,查明造成問題的原因。本教程講解使用跟蹤工具了解應(yīng)用程序內(nèi)部情況的基本技術(shù)。

本教程首先討論調(diào)試和跟蹤的差異,以及這兩種解決方案的工作方式差異。然后,通過一些具體示例講解如何使用跟蹤解決應(yīng)用程序中的問題。DTrace 提供跟蹤和調(diào)試兩種系統(tǒng)的組件,還支持對應(yīng)用程序進行計時和基準(zhǔn)測試。最后,本教程講解如何跟蹤在網(wǎng)絡(luò)計算機之間交換的信息,幫助發(fā)現(xiàn)網(wǎng)絡(luò)應(yīng)用程序中的問題。

跟蹤概述

有時候,需要了解在應(yīng)用程序內(nèi)部正在發(fā)生的情況。例如,應(yīng)用程序可能會運行失敗,而又沒有顯示有幫助的錯誤消息,或者系統(tǒng)服務(wù)沒有按照預(yù)期的方式運行。在這些情況下,您可能不掌握應(yīng)用程序源代碼,因此無法通過傳統(tǒng)的調(diào)試過程尋找問題的原因。跟蹤提供了一種替代方法。

調(diào)試

對于開發(fā)人員來說,尋找 UNIX 應(yīng)用程序問題的主要方法是,使用開發(fā)環(huán)境或操作系統(tǒng)的調(diào)試特性檢查源代碼,查明造成問題的原因。

大多數(shù)調(diào)試系統(tǒng)支持逐行監(jiān)視和檢查代碼行的執(zhí)行過程,還支持監(jiān)視變量和結(jié)構(gòu)的值。可以使用調(diào)試器在代碼中設(shè)置斷點,執(zhí)行過程會停在斷點上;在斷點上,可以獲得關(guān)于調(diào)用堆棧(函數(shù)的調(diào)用路徑)的信息以及變量值。

我們來看一個例子,假設(shè)一個應(yīng)用程序根據(jù)人的生日計算他的年齡,還要考慮到閏年等因素。要想調(diào)試這個應(yīng)用程序,需要有源代碼,還需要在啟用調(diào)試選項的情況下編譯應(yīng)用程序:$ gcc -g ageindays.c -o ageindays。

運行這個應(yīng)用程序,提供用戶的生日和用來比較的目標(biāo)日期(見清單 1)。

清單 1. 執(zhí)行比較

$ ./ageindays 24/1/1980 22/2/2009 You have been alive 10622 days You were born on 24/1/1980 which is a Thursday 

在調(diào)試應(yīng)用程序時,首先懷疑問題出在 calc_diff 函數(shù)中,這個函數(shù)計算第一個和第二個日期的差。接下來,可能按照清單 2 這樣進行調(diào)試。

清單 2. 調(diào)試 calc_diff 函數(shù)

$ gdb ageindays GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:14:40 UTC 2008) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copIEs of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries ... done  (gdb) b calc_diff Breakpoint 1 at 0x1bd7: file ageindays.c, line 27. (gdb) r 24/1/1980 26/3/2009 Starting program: /nfs/MC/UnixSrc/c/bio/ageindays 24/1/1980 26/3/2009 Reading symbols for shared libraries ++. done  Breakpoint 1, calc_diff (day=26, month=3, year=2009) at ageindays.c:27 27unsigned long days_diff=0; (gdb) bt #0 calc_diff (day=26, month=3, year=2009) at ageindays.c:27 #1 0x00001e3d in main (argc=3, argv=0xbffff708) at ageindays.c:89 (gdb) p days_diff $1 = 8041 (gdb) 

通過 清單 2 中的輸出可以看出,我們打開了調(diào)試器,通過指定名稱在 calc_diff() 函數(shù)中設(shè)置了一個斷點,然后在調(diào)試器中運行程序,提供與命令行相同的參數(shù)。

當(dāng)調(diào)試器到達創(chuàng)建的斷點時,執(zhí)行過程停止,您可以檢查應(yīng)用程序代碼和調(diào)用的函數(shù)。通過使用調(diào)試器,可以查看提供給函數(shù)的參數(shù)及其值(在這里是為目標(biāo)日期提供的日期信息)。執(zhí)行停止之后,可以查看堆棧跟蹤,查看代碼中調(diào)用 calc_diff 函數(shù)的行,可以獲得 days_diff 變量的值。因為應(yīng)用程序的執(zhí)行過程已經(jīng)暫停了,所以還可以修改變量的值。這樣就可以在應(yīng)用程序中嘗試使用不同的值,從而尋找潛在的問題。

可以使用這些信息,因為定義了特定的調(diào)試信息(組成函數(shù)和變量名的符號)和其他元數(shù)據(jù)(比如定義函數(shù)的代碼行)。

必須在編譯時把特定的調(diào)試信息添加到二進制應(yīng)用程序中;更重要的是,必須訪問源代碼,才能把調(diào)試信息包含在編譯的應(yīng)用程序中。如果無法識別函數(shù)名和變量,那么幾乎不可能調(diào)試程序。

跟蹤與調(diào)試的對比

系統(tǒng)管理員(和開發(fā)人員)常常希望發(fā)現(xiàn)正在運行的程序中的錯誤。例如,某個程序為什么造成了其他問題(比如內(nèi)存和其他錯誤),應(yīng)用程序的表現(xiàn)為什么不符合預(yù)期,它過去發(fā)生了什么情況。在這種情況下,調(diào)試應(yīng)用程序的特定方面往往沒什么用。需要查明的實際上是操作系統(tǒng)如何執(zhí)行應(yīng)用程序。

在進行調(diào)試時,檢查的是應(yīng)用程序中定義的各個函數(shù)的執(zhí)行過程。調(diào)試主要關(guān)注應(yīng)用程序本身,包括其中的函數(shù)和結(jié)構(gòu),通常會忽視應(yīng)用程序向操作系統(tǒng)發(fā)出的系統(tǒng)調(diào)用和庫函數(shù)調(diào)用。調(diào)試能夠提供關(guān)于應(yīng)用程序的大量信息,但是對于了解操作系統(tǒng)如何執(zhí)行應(yīng)用程序幫助不大。

在進行跟蹤時,監(jiān)視應(yīng)用程序和操作系統(tǒng)之間的交互,常常會檢查應(yīng)用程序在執(zhí)行期間調(diào)用的操作系統(tǒng)函數(shù)。

除了這些差異之外,跟蹤和調(diào)試之間的主要差異是,跟蹤不要求訪問源代碼,也不要求以任何特殊方式編譯應(yīng)用程序。這意味著可以跟蹤操作系統(tǒng)附帶的或第三方廠商提供的應(yīng)用程序。

通過跟蹤應(yīng)用程序,可以查明以下方面的情況:

內(nèi)存使用量和映射內(nèi)存的調(diào)用

在執(zhí)行期間打開和關(guān)閉的文件

對不同文件的讀和寫操作

為給定的應(yīng)用程序裝載的庫

下面先研究一下 truss 的輸出,truss 是一種可以在 Solaris 和 AIX® 上使用的工具。

使用 truss 和 strace

在 Solaris 和 AIX 上可以使用 truss 工具,它能夠跟蹤應(yīng)用程序中的系統(tǒng)調(diào)用和信號。可以在 Linux® 上使用的 strace 工具提供相似的功能。在不同的系統(tǒng)上,還有提供相似信息的其他工具,包括 ktrace (FreeBSD) 和 trace。

truss/strace 概述

truss 和 strace 工具提供相似的信息,但是命令行選項稍有差異。使用這兩種工具的標(biāo)準(zhǔn)方法都是把工具名放在要執(zhí)行的命令前面。

例如,清單 3 給出 truss 對于本教程前面提到的 ageindays 程序的輸出。

清單 3. truss 的輸出

$ truss ./ageindays 24/1/1980 26/3/2009 execve("ageindays", 0x08047BBC, 0x08047BCC) argc = 3 mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFEFB0000 resolvepath("/usr/lib/ld.so.1", "/lib/ld.so.1", 1023) = 12 getcwd("/root", 1013)= 0 resolvepath("/root/ageindays", "/root/ageindays", 1023) = 15 xstat(2, "/root/ageindays", 0x08047880) = 0 open("/var/ld/ld.config", O_RDONLY) = 3 fxstat(2, 3, 0x08047760)= 0 mmap(0x00000000, 144, PROT_READ, MAP_SHARED, 3, 0) = 0xFEFA0000 close(3)= 0 sysconfig(_CONFIG_PAGESIZE) = 4096 xstat(2, "/usr/lib/libc.so.1", 0x08046FA0) = 0 resolvepath("/usr/lib/libc.so.1", "/lib/libc.so.1", 1023) = 14 open("/usr/lib/libc.so.1", O_RDONLY)= 3 mmap(0x00010000, 32768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_ALIGN, 3, 0) = 0xFEF90000 mmap(0x00010000, 1413120, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFEE30000 mmap(0xFEE30000, 1302809, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_TEXT, 3, 0) = 0xFEE30000 mmap(0xFEF7F000, 30862, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED| MAP_INITDATA, 3, 1306624) = 0xFEF7F000 mmap(0xFEF87000, 4776, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) = 0xFEF87000 munmap(0xFEF6F000, 65536)= 0 memcntl(0xFEE30000, 187632, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0 close(3)= 0 mmap(0x00010000, 24576, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFEE20000 munmap(0xFEF90000, 32768)= 0 getcontext(0x080475D0) getrlimit(RLIMIT_STACK, 0x080475C8) = 0 getpid()= 15691 [15690] lwp_private(0, 1, 0xFEE22A00)= 0x000001C3 setustack(0xFEE22A60) sysi86(SI86FPSTART, 0xFEF879BC, 0x0000133F, 0x00001F80) = 0x00000001 ioctl(1, TCGETA, 0x08046C20)= 0 fstat64(1, 0x08046B80) = 0 You have been alive 10654 days write(1, " Y o uh a v eb e e".., 31) = 31 You were born on 24/1/1980 which is a Thursday write(1, " Y o uw e r eb o r".., 47) = 47 _exit(134511508) 

在這兩個輸出中,每個輸出行對應(yīng)于應(yīng)用程序執(zhí)行的一個函數(shù)調(diào)用,其中顯示函數(shù)的參數(shù)和函數(shù)調(diào)用的返回值。與調(diào)試示例不同,列出的每個函數(shù)調(diào)用都是系統(tǒng)或系統(tǒng)庫中的函數(shù),因此表示調(diào)用的函數(shù)的更低層接口。例如,在應(yīng)用程序中可能使用 C 或 C++ 中的 fpopen() 函數(shù)打開文件,但是這個函數(shù)實際上是更低層的 open() 函數(shù)的包裝器。

了解應(yīng)用程序正在執(zhí)行的操作并不需要了解每個函數(shù)的情況。輸出中的許多行與操作系統(tǒng)為裝載和執(zhí)行程序所做的初始化相關(guān)。這兩個跟蹤輸出的基本結(jié)構(gòu)是相同的:

調(diào)用 execve() 函數(shù)以啟動一個新程序。

裝載程序所需的庫。在 Solaris 輸出中,首先使用 resolvepath() 尋找?guī)欤缓笫褂?open() 打開庫。對于 Linux,使用 stat() 檢查庫是否存在,然后使用 open() 打開它。

為進程保留和分配一些內(nèi)存。其中一部分內(nèi)存是為應(yīng)用程序保留的堆棧空間,一部分用來保存程序,其他內(nèi)存保存程序使用的變量。

最后,執(zhí)行程序,調(diào)用 write() 函數(shù)輸出年齡和生日信息。

如果執(zhí)行跟蹤并希望了解每個步驟的具體情況,可以使用 man 命令訪問每個函數(shù)的手冊頁。

識別應(yīng)用程序啟動問題

在啟動應(yīng)用程序時的一個典型問題是,程序無法正確地初始化,但是在終止時給出一個不完整或?qū)е抡`解的消息。對應(yīng)用程序運行跟蹤常常可以揭示這個問題的根源。例如,清單 5 顯示一個測試應(yīng)用程序運行失敗了。

清單 5. 應(yīng)用程序失敗

$ ./errnoacc ERROR: Application failed to initialize 

錯誤消息并沒有提供關(guān)于應(yīng)用程序為什么會啟動失敗的具體信息。在這里,問題是故意引入的,但是您使用的任何命令或應(yīng)用程序都可能出現(xiàn)相同的問題,而錯誤消息沒什么幫助,有時候甚至沒有錯誤消息。

對應(yīng)用程序運行跟蹤可能會提供一些線索(見清單 6)。

清單 6. 運行跟蹤

$ truss ./errnoacc execve("errnoacc", 0x08047B20, 0x08047B28) argc = 1 mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFEFB0000 resolvepath("/usr/lib/ld.so.1", "/lib/ld.so.1", 1023) = 12 getcwd("/export/home/mc", 1014) = 0 resolvepath("/export/home/mc/errnoacc", "/export/home/mc/errnoacc", 1023) = 24 xstat(2, "/export/home/mc/errnoacc", 0x080477E4) = 0 open("/var/ld/ld.config", O_RDONLY) = 3 fxstat(2, 3, 0x080476C4)= 0 mmap(0x00000000, 144, PROT_READ, MAP_SHARED, 3, 0) = 0xFEFA0000 close(3)= 0 sysconfig(_CONFIG_PAGESIZE) = 4096 xstat(2, "/usr/lib/libc.so.1", 0x08046F04) = 0 resolvepath("/usr/lib/libc.so.1", "/lib/libc.so.1", 1023) = 14 open("/usr/lib/libc.so.1", O_RDONLY)= 3 mmap(0x00010000, 32768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_ALIGN, 3, 0) = 0xFEF90000 mmap(0x00010000, 1413120, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFEE30000 mmap(0xFEE30000, 1302809, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_TEXT, 3, 0) = 0xFEE30000 mmap(0xFEF7F000, 30862, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED| MAP_INITDATA, 3, 1306624) = 0xFEF7F000 mmap(0xFEF87000, 4776, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) = 0xFEF87000 munmap(0xFEF6F000, 65536)= 0 memcntl(0xFEE30000, 187632, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0 close(3)= 0 mmap(0x00010000, 24576, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFEE20000 munmap(0xFEF90000, 32768)= 0 getcontext(0x08047534) getrlimit(RLIMIT_STACK, 0x0804752C) = 0 getpid()= 15727 [15726] lwp_private(0, 1, 0xFEE22A00)= 0x000001C3 setustack(0xFEE22A60) sysi86(SI86FPSTART, 0xFEF879BC, 0x0000133F, 0x00001F80) = 0x00000001 open("/etc/shadow", O_RDONLY)Err#13 EACCES [file_dac_read] ioctl(1, TCGETA, 0x08046BB0)= 0 fstat64(1, 0x08046B10) = 0 ERROR: Application failed to initialize write(1, " E R R O R :A p p l i".., 40) = 40 _exit(0) 

問題出現(xiàn)在這一行上:open("/etc/shadow", O_RDONLY) Err#13 EACCES [file_dac_read]。

在這里,應(yīng)用程序試圖打開一個文件,但是因為有文件權(quán)限保護這個文件,運行應(yīng)用程序的用戶沒有訪問權(quán)。因為無法打開這個文件,應(yīng)用程序終止并在進程中寫錯誤消息。

跟蹤正在運行的應(yīng)用程序

希望跟蹤應(yīng)用程序常常是因為應(yīng)用程序已經(jīng)啟動,而您希望查明應(yīng)用程序為什么不工作了。與初始化示例一樣,應(yīng)用程序提供的錯誤消息或其他信息常常沒有準(zhǔn)確地指出問題。

試圖鎖定或訪問另一個進程正在使用的資源會使應(yīng)用程序看起來凍結(jié)了,沒有響應(yīng)。

strace 和 truss 都能夠 “連接 到正在運行的進程。連接到進程的跟蹤與從命令行運行進程的跟蹤相似,也產(chǎn)生程序正在執(zhí)行的系統(tǒng)函數(shù)的列表。實際的跟蹤從跟蹤啟動時執(zhí)行的函數(shù)開始;對于在執(zhí)行期間 “掛起 的程序,跟蹤應(yīng)該會顯示程序正在等待的函數(shù)。

要想跟蹤正在運行的程序,需要指定要跟蹤的進程的進程 ID (PID)。例如,在清單 6 中,跟蹤的程序已經(jīng)停止,但是沒有報告錯誤。這里使用 ps 工具列出正在運行的進程(見清單 7)。

清單 7. 使用 ps 工具列出正在運行的進程

$ ps -ef|grep errlock  mc 15779 157470 18:26:59 pts/20:00 ./errlock  mc 157426800 18:26:36 pts/30:00 ./errlock  mc 15817 157840 18:28:44 pts/40:00 grep errlock  mc 157346800 18:25:00 pts/30:01 /usr/bin/eMacs-nox errlock.c $ truss -p 15779 fcntl(3, F_SETLKW, 0x08047AC4) (sleeping...) 

在輸出中可以看到,已經(jīng)調(diào)用了 fcntl() 函數(shù),它要在一個文件上設(shè)置鎖。在這里,這個函數(shù)會一直等待到成功地設(shè)置鎖,然后才繼續(xù)運行。不幸的是,另一個進程已經(jīng)鎖住了這個文件,所以第二個應(yīng)用程序必須等待第一個應(yīng)用程序使用完文件并釋放鎖。

對于這種情況,truss 有點兒局限性:它無法指出要鎖住哪個文件,也無法指出當(dāng)前鎖住了哪個文件,從而阻礙了第二個程序的執(zhí)行。這是因為跟蹤過程是在已經(jīng)調(diào)用了打開文件的函數(shù)之后啟動的。truss 和 strace 只跟蹤在它們執(zhí)行期間調(diào)用的函數(shù);它們無法查明已經(jīng)調(diào)用的函數(shù)。

獲取堆棧跟蹤

可以看出,truss 對于監(jiān)視整個程序很有用,但是對于監(jiān)視已經(jīng)啟動的程序可能有點兒局限性。如果使用基于 SVR4 的 Unix,比如 Solaris 或 AIX,那么 pstack 命令可能有幫助。

pstack 命令實際上屬于一組進程檢查命令,這些命令輸出正在運行的進程的相關(guān)信息。其他工具包括 pfiles(輸出進程使用的文件的列表)和 psig(顯示信號和信號處理函數(shù)的列表)。

在使用這些命令時,需要指定進程的 PID。pstack 命令輸出一個正在運行的進程的調(diào)用堆棧,顯示在進程到達當(dāng)前函數(shù)之前調(diào)用的函數(shù)。例如,對正在等待被鎖住的文件的進程使用 pstack,會產(chǎn)生清單 8 中的輸出。

清單 8. 對正在等待被鎖住的文件的進程使用 pstack

$ pstack 15828 15828: ./errlock  feef0877 fcntl(3, 7, 8047ac4)  feedcd49 fcntl(3, 7, 8047ac4, 8050e74) + 91  08050f10 main (1, 8047b24, 8047b2c) + d8  08050cdc _start(1, 8047c08, 0, 8047c12, 8047c7d, 8047c8e) + 80 

在這里,它沒有提供我們需要的信息。現(xiàn)在試試 pfiles(見清單 9)。

清單 9. 使用 pfiles

$ pfiles 15856 15856: ./errlock  Current rlimit: 256 file descriptors 0: S_IFCHR mode:0620 dev:292,0 ino:989038936 uid:101 gid:7 rdev:24,3  O_RDWR|O_NOCTTY|O_LARGEFILE  /dev/pts/3 1: S_IFCHR mode:0620 dev:292,0 ino:989038936 uid:101 gid:7 rdev:24,3  O_RDWR|O_NOCTTY|O_LARGEFILE  /dev/pts/3 2: S_IFCHR mode:0620 dev:292,0 ino:989038936 uid:101 gid:7 rdev:24,3  O_RDWR|O_NOCTTY|O_LARGEFILE  /dev/pts/3 3: S_IFREG mode:0666 dev:182,65545 ino:198 uid:101 gid:10 size:0  O_RDWR  advisory write lock set by process 15828  /export/home/mc/lockdemo 

這些輸出就比較有用了。可以看到進程已經(jīng)打開的文件稱為 lockdemo ,因為 truss 顯示正在等待文件鎖,所以可能是這個文件導(dǎo)致了問題。

truss 和 strace 都是被動的跟蹤。可以查看正在執(zhí)行的函數(shù),但是無法了解關(guān)于正在發(fā)生的情況的詳細信息,也無法更有針對性地指定要跟蹤的東西和跟蹤時要輸出的信息。

用 DTrace 進行動態(tài)跟蹤

Solaris、FreeBSD 和 Mac OS X 內(nèi)置的 Dynamic Tracing (DTrace) 功能提供一個更加動態(tài)的跟蹤環(huán)境。與 truss 和相似的工具不同,可以使用 DTrace 檢查正在運行的程序的內(nèi)部情況,而不只是查看系統(tǒng)調(diào)用。另外,可以使用 DTrace 編寫應(yīng)用程序跟蹤腳本,從而定制在跟蹤過程中希望提取的信息。

標(biāo)簽: Unix系統(tǒng)
主站蜘蛛池模板: 亚洲一区二区免费 | 99re久久资源最新地址 | 在线久久 | 国产亚洲精品国产 | 国产亚洲自在精品久久 | 美女操穴视频 | 成人国产精品免费网站 | 亚洲天堂2015 | 国产精品特级毛片一区二区三区 | 一色屋色费精品视频在线看 | 久青草国产手机在线观 | 免费一级毛片无毒不卡 | 免费国产不卡午夜福在线 | 久久国内精品自在自线观看 | 俄罗斯一级黄色片 | 最近日本免费观看视频 | 亚洲高清在线播放 | 免费观看呢日本天堂视频 | 国产综合亚洲专区在线 | 看欧美的一级毛片 | 欧美一级毛片免费看视频 | 美女张开腿让男人桶的 视频 | 日本道色 | 97国产在线观看 | 美国毛片一级视频在线aa | 日本成人午夜 | 免费v片视频在线观看视频 免费v片在线观看 | 久久免费香蕉视频 | 欧美日韩国产在线人成dvd | 毛片免费视频观看 | 人妖欧美一区二区三区四区 | 日本久草视频 | 久久精品一区二区三区四区 | 亚洲深夜| 精品一久久香蕉国产线看观 | 日韩毛片 | 免费一级毛片在线播放放视频 | 福利视频美女国产精品 | 欧美一区二区三区在线播放 | 一级一级毛片看看 | 亚洲a级 |