成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺談iOS Crash(一)

移動開發 iOS
設置Xcode異常斷點后運行程序,發生Crash時,斷點會定位到出錯的代碼行,但僅適用于開發階段。線上APP的Crash還需要通過收集Crash機制來捕獲Crash并記錄在日志中。

一、捕獲iOS Crash

1、設置異常斷點并運行

 

設置異常斷點.png

說明:設置Xcode異常斷點后運行程序,發生Crash時,斷點會定位到出錯的代碼行,但僅適用于開發階段。線上APP的Crash還需要通過收集Crash機制來捕獲Crash并記錄在日志中。

2、Mach異常 和 Unix信號

  • iOS Crash發生時,先產生Mach異常(最底層的內核級異常),然后Mach異常在host層被ux_exception轉換為相應的Unix信號,并通過threadsignal將信號投遞到出錯的線程。
  • 在捕獲Crash事件時,優選Mach異常。因為Mach異常處理會先于Unix信號處理發生,如果Mach異常的handler讓程序exit了,那么Unix信號就永遠不會到達這個進程了。而轉換Unix信號是為了兼容更為流行的POSIX標準(SUS規范),這樣就不必了解Mach內核也可以通過Unix信號的方式來兼容開發。
  • 在方案實現時,通過捕獲Mach異常+Unix信號組合方式來捕獲Crash事件。在選擇具體方案時,可以選擇PLCrashReporter這樣優秀的開源項目,也可以選擇友盟、Bugly 這類完善的Crash上報和統計的產品(試項目需求而定)。

3、捕獲Crash

并不是所有的Crash都可以捕獲到NSException,如果捕獲不到,可以使用signal機制來捕獲Crash發生時的錯誤內容。

1) 可以捕獲的NSException,通過注冊NSUncaughtExceptionHandler捕獲異常信息

  1. //注冊異常處理函數 
  2.  
  3. NSSetUncaughtExceptionHandler(&uncaught_exception_handler); 
  4.  
  5. //異常處理函數 
  6.  
  7. static void uncaught_exception_handler (NSException *exception) { 
  8.  
  9.   //可以取到 NSException 信息 
  10.  
  11.   //... 
  12.  
  13.   abort(); 
  14.  
  15.  

說明: 使用Objective-C的異常處理是不能得到signal的。

2) 無法捕獲的NSException,利用Unix標準的signal機制,注冊SIGABRT, SIGBUS, SIGSEGV等信號發生時的處理函數。

  1. //注冊處理SIGSEGV信號 
  2.  
  3. signal(SIGSEGV,handleSignal); 
  4.  
  5. // 注冊處理其他信號 .... 
  6.  
  7.   
  8.  
  9. //信號處理函數 
  10.  
  11. static void handleSignal( int sig ) { 
  12.  
  13.  

二、Crash日志組成

上部分介紹了Crash的捕獲,這部分來看看Crash日志的組成。

1、日志內容Demo

日志主要分為六個部分:進程信息、基本信息、異常信息、線程回溯、線程狀態和二進制映像。下面是從某APP具體的Crash日志抽出的主要信息,展示如下:

  1. //1、進程信息 
  2.  
  3. Hardware Model: iPhone9,2 
  4.  
  5. Process: AppName [3580] 
  6.  
  7. Path: /var/containers/Bundle/Application/C7B90C8A-E269-4413-A011-552971D1ED39/AppName.app 
  8.  
  9. Identifier: xxxx.xxx.xxxx.xxx 
  10.  
  11. Version: xx.xx 
  12.  
  13. Code Type: ARM-64 (Native) 
  14.  
  15. Parent Process:  [1] 
  16.  
  17.   
  18.  
  19. //2、基本信息 
  20.  
  21. Date/Time: 2017-05-22 03:05:06.743 +0800 
  22.  
  23. OS Version: iPhone OS 10.2.1 (14D27) 
  24.  
  25.   
  26.  
  27. //3、異常信息 
  28.  
  29. Exception Type: NSInvalidArgumentException(SIGABRT) 
  30.  
  31. Exception Codes: -[NSNull integerValue]: unrecognized selector sent to instance 0x1a9d88ef8 at 0x00000001835c7014 
  32.  
  33. Crashed Thread: 0 
  34.  
  35.   
  36.  
  37. //4、線程回溯 (展示發生Crash線程的回溯信息,其他略) 
  38.  
  39. Thread 0 Crashed: 
  40.  
  41. 0  libsystem_kernel.dylib         0x00000001835c7014 __pthread_kill + 4 
  42.  
  43. 1  libsystem_c.dylib              0x000000018353b400 abort + 140 
  44.  
  45. 2  AppName                         0x0000000100a26704 0x0000000100028000 + 10479360 
  46.  
  47. 3  CoreFoundation                 0x00000001845f9538 ___handleUncaughtException +  644 
  48.  
  49. 2  CoreFoundation                 0x0000000184600268 ___methodDescriptionForSelector 
  50.  
  51. 3  CoreFoundation                 0x00000001845fd270 ____forwarding___ +  916 
  52.  
  53. 4  CoreFoundation                 0x00000001844f680c _CF_forwarding_prep_0 + 80 
  54.  
  55. 5  AppName                         0x0000000100205280 0x0000000100028000 + 1954432 
  56.  
  57. 6  AppName                         0x00000001002ae59c 0x0000000100028000 + 2647440 
  58.  
  59. 7  AppName                         0x0000000100482944 0x0000000100028000 + 4565312 
  60.  
  61. 16 CoreFoundation                 0x00000001845a6810 ___CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ +  12 
  62.  
  63.      +  12 
  64.  
  65. 17 CoreFoundation                 0x00000001845a43fc ___CFRunLoopRun +  1660 
  66.  
  67. 18 CoreFoundation                 0x00000001844d22b8 CFRunLoopRunSpecific + 436 
  68.  
  69.   
  70.  
  71. //5、進程狀態(展示部分) 
  72.  
  73. Thread 0 crashed with ARM 64 Thread State: 
  74.  
  75.      x0:  000000000000000000    x1: 000000000000000000    x2: 000000000000000000     x3: 0xffffffffffffffff 
  76.  
  77.      x4:  0x0000000000000010    x5: 0x0000000000000020    x6: 000000000000000000     x7: 000000000000000000 
  78.  
  79.      x8:  0x0000000008000000    x9: 0x0000000004000000   x10: 000000000000000000    x11: 0x00000001ac336c83 
  80.  
  81.     x12: 0x00000001ac336c83    x13: 0x0000000000000018   x14: 0x0000000000000001    x15: 0x0000000000000881 
  82.  
  83.     x16: 0x0000000000000148    x17: 000000000000000000   x18: 000000000000000000    x19: 0x0000000000000006 
  84.  
  85.   
  86.  
  87. //6、二進制映像 (展示部分) 
  88.  
  89. Binary Images: 
  90.  
  91. 0x100028000 - 0x1011dbfff +AppName arm64  /var/containers/Bundle/Application/C7B90C8A-E269-4413-A011-552971D1ED39/AppName.app/AppName 
  92.  
  93. 0x18368a000 - 0x183693fff  libsystem_pthread.dylib arm64  /usr/lib/system/libsystem_pthread.dylib 
  94.  
  95. 0x1835a8000 - 0x1835ccfff  libsystem_kernel.dylib arm64  /usr/lib/system/libsystem_kernel.dylib 
  96.  
  97. 0x1834b1000 - 0x1834b5fff  libdyld.dylib arm64  /usr/lib/system/libdyld.dylib 
  98.  
  99. 0x1834d8000 - 0x183556fff  libsystem_c.dylib arm64  /usr/lib/system/libsystem_c.dylib 
  100.  
  101. 0x183481000 - 0x1834b0fff  libdispatch.dylib arm64  /usr/lib/system/libdispatch.dylib 
  102.  
  103. 0x183028000 - 0x183401fff  libobjc.A.dylib arm64  /usr/lib/libobjc.A.dylib  

2、日志內容組成分析

整個日志內容中,直接和Crash信息相關,最能幫助開發者定位問題部分是: 異常信息 和 線程回溯部分的內容。

1) 進程信息:發生Crash閃退進程的相關信息

  • Hardware Model : 標識設備類型。 如果很多崩潰日志都是來自相同的設備類型,說明應用只在某特定類型的設備上有問題。上面的日志里,崩潰日志產生的設備是iPhone 7 Plus (iPhone 7 Plus 也是2個版本 iPhone9,2 和 iPhone9,4. 硬件代號為 D11AP 和 D111AP. 型號有: A1661, A1784, A1785 和 A1786. )
  • Process 是應用名稱。中括號里面的數字是閃退時應用的進程ID。

2) 基本信息:給出了一些基本信息,包括閃退發生的日期和時間,設備的iOS版本。

3) 異常信息:閃退發生時拋出的異常類型。還能看到異常編碼和拋出異常的線程。

  1. //以上面內容中的異常信息為例: 
  2.  
  3. Exception Type: NSInvalidArgumentException(SIGABRT) 
  4.  
  5. Exception Codes: -[NSNull integerValue]: unrecognized selector sent to instance 0x1a9d88ef8 at 0x00000001835c7014 
  6.  
  7. Crashed Thread: 0  
  • Exception Type異常類型:通常包含1.7中的Signal信號和EXC_BAD_ACCESS,NSRangeException等。
  • Exception Codes:異常編碼:
  • Crashed Thread:發生Crash的線程id

4) 線程回溯:回溯是閃退發生時所有活動幀清單。它包含閃退發生時調用函數的清單。

5) 線程狀態:閃退時寄存器中的值。一般不需要這部分的信息,因為回溯部分的信息已經足夠讓你找出問題所在。

6) 二進制映像:閃退時已經加載的二進制文件。

三、異常信息解讀

1、Exception Type(異常類型)

  • Exception Type:通常包含Signal信號 和 EXC_BAD_ACCESS,NSRangeException等。
異常類型 可能的原因 調試方法
EXC_CRASH unrecognized selector All Exception Point
EXC_BAD_ACCESS 內存訪問錯誤 NSZombie
SIGSEGV 引用了released對象 / 引用未init的對象 / 數組越界/ 試圖往沒有寫權限的內存地址寫數據 NSZombie
SIGABRT 邏輯錯誤導致的Crash,比如嘗試多次釋放同一個沒存 邏輯檢查
SIGPIPE TCP突然斷開,再發送數據 添加signal(SIGPIPE,XX)

具體信號說明參見iOS異常捕獲(http://www.iosxxx.com/blog/2015-08-29-iosyi-chang-bu-huo.html)

2、Exception Code(異常編碼)

  • Exception Code:以一些文字開頭,緊接著是一個或多個十六進制值。這些數值說明了Crash發生的本質。
  • 從Exception Code中,可以區分出Crash是因為程序錯誤、非法內存訪問還是其他原因。常見的異常編碼如下表:
異常編碼 描述
0x8badf00d ate bad food ,表示應用是因為發生watchdog超時而被iOS終止的。通常是應用花費太多時間而無法啟動、終止或響應用系統事件。
0xdeadfa11 dead fall,用戶強制退出。
0xbaaaaaad 用戶按住Home鍵和音量鍵,獲取當前內存狀態,不代表崩潰。
0xbad22222 VoIP 應用因為過于頻繁重啟而被終止
0xc00010ff cool off,因為太燙了被干掉
0xdead10cc dead lock,表明應用因為在后臺運行時占用系統資源(如通訊錄數據庫)
0xbbadbeef bad beef,發生致命錯誤

說明1:詳細的異常編碼代表的含義請參考:Hexspeak

說明2:在后臺任務列表中關閉已掛起的應用不會產生崩潰日志。 因為應用一旦被掛起,它何時被終止都是合理的。所以不會產生崩潰日志。

四、Crash日志符號化

1、概述

線程回溯部分內容如下:

  1. 5 AppName 0x0000000100205280 0x0000000100028000 + 1954432 
  2.  
  3. 6 AppName 0x00000001002ae59c 0x0000000100028000 + 2647440  

這兩條記錄包括四列:(以第一條記錄為例子)

  • 幀編號—— 5(數字越小,發生時間越晚,發生順序越往后,越好鎖定問題的范圍)
  • 二進制庫的名稱 ——此處是 AppName.
  • 調用方法的地址 ——此處是 0x0000000100205280.
  • 第四列分為兩個子列,一個基本地址和一個偏移量。此處是 x0000000100028000 + 1954432, 第一個數字指向文件,第二個數字指向文件中的代碼行。

說明1:線程回溯部分并不是我們習慣使用方法名和行數,而是十六進制地址。所以我們在分析Crash前需要將這些十六進制地址轉化成方法名稱和行數,改過程被稱為符號化。

說明2:符號化Crash日志需要獲取對應的應用二進制文件以及生成二進制文件時產生的 .dSYM 文件(符號表)。必需完全匹配才行。否則,日志將無法被完全符號化。

說明3: Xcode編譯項目后,會得到同名的 dSYM 文件(符號表),dSYM 文件(符號表)是保存 16 進制函數地址映射信息的中轉文件,我們調試的 symbols 都會包含在這個文件中,并且每次編譯項目的時候都會生成一個新的 dSYM 文件,位于 /Users//Library/Developer/Xcode/Archives 目錄下,對于每一個發布版本我們都很有必要保存對應的 Archives 文件。

說明4:符號化可以使用Xcode的兩種命令 symbolicatecrash命令 + atos命令

2、symbolicatecrash命令

1)首選找到symbolicatecrash命令的位置

  1. find /Applications -name symbolicatecrash -type f   
  2.  
  3.   //我的本機命令的位置:/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash  

2)找到線上版本對應的xcarchive文件。從中找到.dSYM和.app文件

xcarchive所在的路徑一般在: /Users//Library/Developer/Xcode/Archives 目錄下

3)獲取crash日志文件

  • 線上App的Crash日志經由Crash日志收集服務獲得(主要來源)。
  • 也可以從真機上獲取Crash日志文件。點擊Window -> Devices,選擇你自己的機器,然后點擊View Device Logs,右鍵可以導出Crash文件。
  • 獲取的這些日志文件都需要符號化處理。

4)將symbolicatecrash、.dSYM、.app、crash.crash拷貝到桌面下同一個文件夾下

5)檢查 xx.app 和 xx.app.dSYM 文件以及crash 文件這三種的 UUID是否一致。

查看 xx.app 文件的 UUID,terminal 中輸入命令 :

  1. dwarfdump --uuid xx.app/xx (xx代表你的項目名) 

查看 xx.app.dSYM 文件的 UUID ,在 terminal 中輸入命令:

  1. dwarfdump --uuid xx.app.dSYM 

查看crash 日志中的Incident Identifier (crash 文件的 UUID)

6)使用命令,生成“可定位問題的crash文件”

  1. //symbolreportXXX.crash就是符號化后的文件 
  2.  
  3. ./symbolicatecrash crashXXX.crash appName.app.dSYM > symbolreportXXX.crash  

7) 根據符號化后的線程回溯信息,可以幫助定位出問題的代碼行。

說明:如果執行symbolicatecrash命令出現 Error: “DEVELOPER_DIR” is not defined at ./symbolicatecrash…這樣的錯誤,可以在執行命令前,輸入export DEVELOPER_DIR=”/Applications/XCode.app/Contents/Developer”

3、atos命令

在符號化時候,還可以使用atos命令。發現armv7處理器上的crash使用symbolicatecrash無法符號化。

1)將.dSYM、.app、crash.crash放到同一個文件夾下。

2) 知道crash文件的UUID:執行grep “AppName arm” *crash,得到結果

  1. crash1.crash:0x100040000 - 0x100e23fff +AppName arm64  /var/containers/Bundle/Application/55A4D641-847F-4D24-86E1-129B28461858/AppName.app/AppName 
  2.  
  3. crash2.crash:0x100060000 - 0x100e43fff +AppName arm64  /var/containers/Bundle/Application/3229ED68-8D19-406D-A3F5-EC0310C9DB7C/QAppName.app/AppName 
  4.  
  5. crash3.crash:    0x5000 -   0xce8fff +AppName armv7  /var/containers/Bundle/Application/C6BE271D-2EAC-42C0-8E72-4523F88C76B2/AppName.app/AppName  

其中0x100040000、0x100060000、0x5000是加載地址(loadingAddress), 而arm64、armv7 是 architecture 的值(architectureValue),這兩個值后面都要用。

3)然后執行atos命令,輸入成功,進入待輸入狀態

  1. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l loadingAddress -arch architectureValue 

4) 此時輸入App對應的Crash地址,得到發生crash的信息。

實例1:

  1. grep "AppName arm" *crash 
  2.  
  3. xcrun atos -o AppName.app.dSYM/Contents/Resources/DWARF/AppName -l 0x100040000 -arch arm64  

實例2:

  1. grep "AppName arm" *crash 
  2.  
  3. xcrun atos -o AppName.app.dSYM/Contents/Resources/DWARF/AppName -l 0x5000 -arch armv7  

五、常見的Crash

有一些Crash比較常見,下面羅列出5種常見的Crash。

1、數組操作

  • 場景1:取數據索引越界。一般發生在UITableView的使用中,因為cellForRowAtIndexPath代理方法是異步執行的,UITableView對象的dataSource一旦在加載數據過程中發生變化,極有可能發生數組越界的異常。在多線程場景下,列表界面的數據有可能經常變化,很可能發生;當列表界面數據不怎么變化的時候,幾乎感知不到這種異常的存在。解決辦法:從數組中取數據前,校驗索引是否正確。
  1. @implementation NSMutableArray (Safe) 
  2.  
  3.   
  4.  
  5. - (id)safeObjectAtIndex:(NSUInteger)index
  6.  
  7.   
  8.  
  9.      if (index < self.count){ 
  10.  
  11.          return [self objectAtIndex:index]; 
  12.  
  13.      }else
  14.  
  15.          NSLog(@"警告:數組越界!!!"); 
  16.  
  17.      }     
  18.  
  19.      return nil; 
  20.  
  21.  
  22.   
  23.  
  24. @end  
  • 場景2:數組添加數據對象時nil解決辦法:添加對象到數組前,判斷是否是nil

說明:數組的刪除等操作處理類似,數組操作前要進行數據校驗。

2、多線程下的Crash

一般多線程發生的Crash,會收到SIGSEGV信號,表明試圖訪問未分配給自己的內存, 或試圖往沒有寫權限的內存地址寫數據。

  • 場景1:子線程中更新UI

解決辦法:將UI更新操作放在主線程中,可以使用performSelectorOnMainThread 或 GCD

  1. //子線程中,使用宏將更新UI的任務派發到主隊列 
  2.  
  3.   #define dispatch_main_sync_safe(block) \ 
  4.  
  5.   if ([NSThread isMainThread]) { \ 
  6.  
  7.      block(); \ 
  8.  
  9.   } else { \ 
  10.  
  11.       dispatch_sync(dispatch_get_main_queue(), block); \ 
  12.  
  13.   } 
  14.  
  15.   
  16.  
  17.   #define dispatch_async_main(block)              dispatch_async(dispatch_get_main_queue(), block)  
  • 場景2:多線程中創建單例解決辦法:使用dispatch_once,保證代碼只執行一次,保證線程安全。
  1. //以QSAccountManager單例為例 
  2.  
  3.   static QSAccountManager *_shareManager = nil; 
  4.  
  5.   + (instancetype)shareManager{ 
  6.  
  7.   
  8.  
  9.       static dispatch_once_t once; 
  10.  
  11.       dispatch_once(&once, ^{ 
  12.  
  13.           _shareManager = [[self alloc] init]; 
  14.  
  15.       }); 
  16.  
  17.       return _shareManager; 
  18.  
  19.   } 
  20.  
  21.   
  22.  
  23.   + (instancetype)allocWithZone:(struct _NSZone *)zone{ 
  24.  
  25.   
  26.  
  27.       static dispatch_once_t onceToken; 
  28.  
  29.       dispatch_once(&onceToken, ^{ 
  30.  
  31.           _shareManager = [super allocWithZone:zone]; 
  32.  
  33.       }); 
  34.  
  35.       return _shareManager; 
  36.  
  37.   } 
  38.  
  39.   
  40.  
  41. - (nonnull id)copyWithZone:(nullable NSZone *)zone{ 
  42.  
  43.       return _shareManager; 
  44.  
  45.   }  
  • 場景3:多線程下非線程安全類的使用,如NSMutableArray、NSMutableDictionary解決辦法:使用派發隊列或鎖保證數據讀寫安全。具體實現詳見 iOS實錄12:NSMutableArray使用中忽視的問題中第一部分。
  • 場景4:數據緩存到磁盤和讀取。解決辦法:使用派發隊列或鎖保證數據讀寫安全。如將數據的讀取和寫異步放入串行同步隊列,保證數據同步,線程安全。

3、WatchDog 超時造成的Crash

  • 一般異常編碼是0x8badf00d ,表示應用是因為發生watchdog超時而被iOS終止的。通常是應用花費太多時間而無法啟動、終止或響應用系統事件。
  • 場景1:主線程中執行耗時的操作,導致主線程被卡超過一定的時間。解決辦法:主線程中只負責UI的更新和響應,將耗時的操作采用異步的方式放到后臺線程執行。耗時操作包括:網絡請求,數據庫讀寫等。

4、performSelector:withObject:afterDelay下的Crash

  • 場景1:對象釋放比performSelector:afterDelay要早解決辦法:在對應類的dealloc中執行cancelPreviousPerformRequestsWithTarget取消執行。

5、SIGPIPE導致的程序退出

  • 當服務器close一個連接時,若client端接著發數據。根據TCP協議的規定,會收到一個RST響應,client再往這個服務器發送數據時,系統會發出一個SIGPIPE信號給進程,告訴進程這個連接已經斷開了,不要再寫了。而根據信號的默認處理規則,SIGPIPE信號的默認執行動作是terminate(終止、退出),所以client會退出。
  • 場景:長連接socket或重定向管道進入后臺,沒有關閉解決辦法1:切換到后臺時,關閉長連接和管道,回到前臺再重建;解決辦法2:使用signal(SIGPIPE,SIG_IGN),將SIGPIPE交給了系統處理。這么做將SIGPIPE設為SIG_IGN,使得客戶端不執行默認動作,即不退出。 
責任編輯:龐桂玉 來源: iOS大全
相關推薦

2017-07-25 12:40:42

iOSCrash僵尸對象

2011-07-07 11:03:07

iOS MVC Objective-

2018-10-16 15:08:20

屏幕圖像對象

2017-11-10 13:02:44

iOSUI代碼

2011-07-28 10:01:19

IOS 內存優化

2011-07-28 17:20:55

2011-08-02 10:50:56

iOS開發 內存緩存

2018-04-09 13:47:39

Crash日志App

2010-05-26 15:18:28

桌面虛擬化

2010-08-06 13:40:06

DB2建立nickna

2011-07-29 09:45:11

iOS 圖形圖像 Core Anima

2023-10-07 08:45:47

2022-09-19 21:10:25

CRM銷售管理系統

2021-03-05 07:14:08

Linuxcrashvmcore

2014-07-29 15:44:33

Linux內核Crash

2020-07-21 18:29:19

LinuxUnixiOS

2020-10-15 14:00:20

網絡攻擊溯源

2023-02-01 07:34:41

讀寫分離數據庫

2012-10-29 11:25:05

IBMdw

2021-12-30 10:43:21

Android函數Crash
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 毛片久久久 | 精品一区二区av | 亚洲 欧美 精品 | 国产精品一区二区在线 | 日韩在线国产 | 亚洲+变态+欧美+另类+精品 | 欧美精品国产一区二区 | 天堂亚洲网 | 精品国产一区二区三区久久久蜜月 | 久久久久国产一区二区三区四区 | 久草久草久草 | 一呦二呦三呦国产精品 | 一区二区三区四区电影视频在线观看 | 国产精品久久久 | 色资源站| 国产高清视频一区 | 国产精品免费在线 | 日日干日日操 | 日韩中文字幕免费在线观看 | 高清一区二区三区 | 亚洲福利在线视频 | 久久久久久久久91 | k8久久久一区二区三区 | 国产欧美一级 | 亚洲少妇综合网 | 亚洲国产一区二区三区 | 国产偷久久一级精品60部 | 国产一区二区不卡 | 欧美亚洲视频在线观看 | 欧美不卡一区二区三区 | 毛片网在线观看 | 91成人在线视频 | 国产1区2区在线观看 | 国产丝袜一区二区三区免费视频 | 久久中文字幕av | 国产精品国产成人国产三级 | 国产一级特黄真人毛片 | 激情婷婷 | 毛片高清| 精品久久久999| 欧美日韩在线一区 |