日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

工程师如何“神还原”用户问题?闲鱼回放技术揭秘

發(fā)布時間:2024/8/23 编程问答 68 豆豆
生活随笔 收集整理的這篇文章主要介紹了 工程师如何“神还原”用户问题?闲鱼回放技术揭秘 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們透過系統(tǒng)底層來捕獲ui事件流和業(yè)務(wù)數(shù)據(jù)的流動,并利用捕獲到的這些數(shù)據(jù)通過事件回放機(jī)制來復(fù)現(xiàn)線上的問題。本文先介紹錄制和回放的整體框架,接著介紹里面涉及到的3個關(guān)鍵技術(shù)點,也是這里最復(fù)雜的技術(shù)(模擬觸摸事件,統(tǒng)一攔截器實現(xiàn),統(tǒng)一hook block)。

背景

現(xiàn)在的app基本都會提供用戶反饋問題的入口,然而提供給用戶反饋問題一般有兩種方式:

?●??直接用文字輸入表達(dá),或者截圖
?●??直接錄制視頻反饋

這兩種反饋方式常常帶來以下抱怨:

?●??用戶:輸入文字好費(fèi)時費(fèi)力
?●??開發(fā)1:看不懂用戶反饋說的是什么意思?
?●??開發(fā)2:大概看懂用戶說的是什么意思了,但是我線下沒辦法復(fù)現(xiàn)哈
?●??開發(fā)3:看了用戶錄制的視頻,但是我線下沒辦法重現(xiàn),也定位不到問題

所以,為了解決以上問題,我們用一套全新的思路來設(shè)計線上問題回放體系。

線上問題回放體系的意義

?●??用戶不需要輸入文字反饋問題,只需要重新操作一下app重現(xiàn)問題步驟即可。
?●??開發(fā)者拿到用戶反饋的問題腳本后,通過線下回放對問題一目了然,跟錄制視頻效果一樣,是的,你沒看錯,就是跟看視頻一樣。
?●??通過腳本的回放實時獲取到app運(yùn)行時相關(guān)數(shù)據(jù)(本地數(shù)據(jù),網(wǎng)絡(luò)數(shù)據(jù),堆棧等等), 以便排查問題。
?●??為后續(xù)自動測試提供想象空間——你懂的。

效果視頻

技術(shù)原理

1.app與外部環(huán)境的關(guān)系

?

從上面的關(guān)系圖可以看出,整個app的運(yùn)行無非是用戶ui操作,然后觸發(fā)app從外界獲取數(shù)據(jù),包括網(wǎng)絡(luò)數(shù)據(jù),gps數(shù)據(jù)等等,也包括從手機(jī)本地獲取數(shù)據(jù),比如相冊數(shù)據(jù),機(jī)器數(shù)據(jù),系統(tǒng)等數(shù)據(jù)。 所以我們要實現(xiàn)問題回放只需要記錄用戶的UI操作和外界數(shù)據(jù),app自身數(shù)據(jù)即可。

app錄制 = 用戶的UI操作 + 外界數(shù)據(jù)(手機(jī)內(nèi)和手機(jī)外) + app自身數(shù)據(jù)

2.線上問題回放架構(gòu)由兩部分組成:錄制和回放

錄制是為回放服務(wù),錄制的信息越詳細(xì),回放成功率就越高,定位問題就越容易

錄制其實就是把ui和數(shù)據(jù)記錄下來,回放其實就是app自動驅(qū)動UI操作并把錄制時的數(shù)據(jù)塞回相應(yīng)的地方。

3.錄制架構(gòu)圖

?

錄制流程:

?

4.回放架構(gòu)圖

?

回放跟錄制框架圖基本一樣,實際上錄制和回放的代碼是在一起,邏輯也是統(tǒng)一的,為了便于表達(dá),我人為劃分成兩個架構(gòu)圖出來。

回放的流程:?

1.啟動app,點擊回放按鈕。

2.引擎加載回放腳本。

3.從腳本中解析出需要注冊的運(yùn)行時事件并注冊,在回放里不需要業(yè)務(wù)上層來注冊事件,這里跟錄制是不一樣的。

4.從腳本中解析出需要注冊的靜態(tài)數(shù)據(jù)事件并注冊。

5.從腳本中解析出需要播放的事件數(shù)據(jù),并組成消費(fèi)隊列。

6.啟動播放器,從消費(fèi)隊列里讀取一個個事件來播放,如果是ui事件則直接播放,如果是靜態(tài)數(shù)據(jù)事件則直接按照指令要求替換數(shù)據(jù)值,如果是非ui運(yùn)行時事件則通過事件指令規(guī)則來確定是主動播放還是等待攔截對應(yīng)的事件,如果需要等待攔截對應(yīng)的事件,則播放器會一直等待此事件直到此事件被app消費(fèi)掉為止。只有此事件被消費(fèi)了,播放器才能播放下一個事件。

7.當(dāng)攔截到被注冊的事件后,根據(jù)此事件指令要求把相應(yīng)的數(shù)據(jù)塞到相應(yīng)的字段里。

8.跳回6繼續(xù)運(yùn)行,直到消費(fèi)隊列里的事件被消費(fèi)完。

注意:回放每個事件時會實時自動打印出相應(yīng)的堆棧信息和事件數(shù)據(jù),有利于排查問題

關(guān)鍵技術(shù)介紹

1.模擬觸摸事件

從ui事件數(shù)據(jù)解中析出被觸摸的view,以及此view所在的視圖樹中的層級關(guān)系,并在當(dāng)前回放界面上查找到對應(yīng)的view,然后往該view上發(fā)送ui操作事件(點擊,雙擊等等),并帶上觸摸事件的坐標(biāo)信息,其實這里是模擬觸摸事件。我們先來介紹觸摸事件的處理流程:

等待觸摸階段

?●??手機(jī)屏幕處于待機(jī)狀態(tài),等待觸摸事件發(fā)生
?●??手指開始觸摸屏幕

系統(tǒng)反應(yīng)階段

?●??屏幕感應(yīng)器接收到觸摸,并將觸摸數(shù)據(jù)傳給系統(tǒng)IOKit(IOKit是蘋果的硬件驅(qū)動框架)
?●??系統(tǒng)IOKit封裝該觸摸事件為IOHIDEvent對象
?●??接著系統(tǒng)IOKit把IOHIDEvent對象轉(zhuǎn)發(fā)給SpringBoard進(jìn)程

SpringBoard進(jìn)程就是iOS的系統(tǒng)桌面,它存在于iDevice的進(jìn)程中,不可清除,它的運(yùn)行原理與Windows中的explorer.exe系統(tǒng)進(jìn)程相類似。它主要負(fù)責(zé)界面管理,所以只有它才知道當(dāng)前觸摸到底有誰來響應(yīng)。

SpringBoard接收階段

?●??SpringBoard收到IOHIDEvent消息后,觸發(fā)runloop中的Source1回調(diào)__IOHIDEventSystemClientQueueCallback()方法。
?●??SpringBoard開始查詢前臺是否存在正在運(yùn)行的app,如果存在,則SpringBoard通過進(jìn)程通信方式把此觸摸事件轉(zhuǎn)發(fā)給前臺當(dāng)前app,如果不存在,則SpringBoard進(jìn)入其自己內(nèi)部響應(yīng)過程。

app處理階段

?●??前臺app主線程Runloop收到SpringBoard轉(zhuǎn)發(fā)來的消息,并觸發(fā)對應(yīng)runloop 中的Source1回調(diào)_UIApplicationHandleEventQueue()。
?●??_UIApplicationHandleEventQueue()把IOHIDEvent處理包裝成UIEvent進(jìn)行處理分發(fā)。
?●??Soucre0回調(diào)內(nèi)部UIApplication的sendEvent:方法,將UIEvent傳給UIWindow。
?●??在UIWindow為根節(jié)點的整棵視圖樹上通過hitTest(_:with:)和point(inside:with:)這兩個方法遞歸查找到合適響應(yīng)這個觸摸事件的視圖。
?●??找到最終的葉子節(jié)點視圖后,就開始觸發(fā)此視圖綁定的相應(yīng)事件,比如跳轉(zhuǎn)頁面等等。

從上面觸摸事件處理過程中我們可以看出要錄制ui事件只需要在app處理階段中的UIApplication sendEvent方法處截獲觸摸數(shù)據(jù),回放時也是在這里把觸摸模擬回去。

下面是觸摸事件錄制的代碼,就是把UITouch相應(yīng)的數(shù)據(jù)保存下來即可 這里有一個關(guān)鍵點,需要把touch.timestamp的時間戳記錄下來,以及把當(dāng)前touch事件距離上一個touch事件的時間間隔記錄下來,因為這個涉及到觸摸引起慣性加速度問題。比如我們平時滑動列表視圖時,手指離開屏幕后,列表視圖還要慣性地滑動一小段時間。

- (void)handleUIEvent:(UIEvent?*)event{if?(!self.isEnabled)?return;if?(event.type !=?UIEventTypeTouches)?return;NSSet?*allTouches = [event?allTouches];UITouch?*touch = (UITouch?*)[allTouches anyObject];if?(touch.view) {if?(self.filter && !self.filter(touch.view)) {return;}}switch?(touch.phase) {case?UITouchPhaseBegan:{self.machAbsoluteTime = mach_absolute_time();self.systemStartUptime = touch.timestamp;self.tuochArray = [NSMutableArray?array];[self?recordTouch:touch click:self.machAbsoluteTime];break;}case?UITouchPhaseStationary:{[self?recordTouch:touch click:mach_absolute_time()];break;}case?UITouchPhaseCancelled:{[self?recordTouch:touch click:mach_absolute_time()];[[NSNotificationCenter?defaultCenter] postNotificationName:@"notice_ui_test"?object:self.tuochArray];break;}case?UITouchPhaseEnded:{[self?recordTouch:touch click:mach_absolute_time()];[[NSNotificationCenter?defaultCenter] postNotificationName:@"notice_ui_test"?object:self.tuochArray];break;}case?UITouchPhaseMoved:{[self?recordTouch:touch click:mach_absolute_time()];}default:break;}}

我們來看一下代碼怎么模擬單擊觸摸事件(為了容易理解,我把有些不是關(guān)鍵,復(fù)雜的代碼已經(jīng)去掉),接著我們來看一下模擬觸摸事件代碼 一個基本的觸摸事件一般由三部分組成:

?●??UITouch對象 - 將用于觸摸
?●??第一個UIEvent Began觸摸
?●??第二個UIEvent Ended觸摸

實現(xiàn)步驟:

1.代碼的前面部分都是一些UITouch和UIEvent私有接口,私有變量字段,由于蘋果并不公開它們,為了讓其編譯不報錯,所以我們需要把這些字段包含進(jìn)來,回放是在線下,所以不必?fù)?dān)心私有接口被拒的事情。

2.構(gòu)造觸摸對象:UITouch和UIEvent,把記錄對應(yīng)的字段值塞回相應(yīng)的字段。塞回去就是用私有接口和私有字段。

3.觸摸的view位置轉(zhuǎn)換為Window坐標(biāo),然后往app里發(fā)送事件 [[UIApplication sharedApplication] sendEvent:event];

4.要回放這些觸摸事件,我們需要把他丟到CADisplayLink里面來執(zhí)行。

//// SimulationTouch.m//// Created by 詩壯殷 on 2018/5/15.//#import "SimulationTouch.h"#import <objc/runtime.h>#include?<mach/mach_time.h>@implementation?UITouch?(replay)-?(id)initPoint:(CGPoint)point window:(UIWindow?*)window{NSParameterAssert(window);self?=?[super?init];if?(self)?{[self?setTapCount:1];[self?setIsTap:YES];[self?setPhase:UITouchPhaseBegan];[self?setWindow:window];[self?_setLocationInWindow:point resetPrevious:YES];[self?setView:[window hitTest:point withEvent:nil]];[self?_setIsFirstTouchForView:YES];[self?setTimestamp:[[NSProcessInfo?processInfo]?systemUptime]];}return?self;}@end@interface?UIInternalEvent?:?UIEvent-?(void)_setHIDEvent:(IOHIDEventRef)event;@end@interface?UITouchesEvent?:?UIInternalEvent-?(void)_addTouch:(UITouch?*)touch forDelayedDelivery:(BOOL)delayedDelivery;-?(void)_clearTouches;@endtypedef?enum?{kIOHIDDigitizerEventRange?=?0x00000001,kIOHIDDigitizerEventTouch?=?0x00000002,kIOHIDDigitizerEventPosition?=?0x00000004,}?IOHIDDigitizerEventMask;IOHIDEventRef?IOHIDEventCreateDigitizerFingerEvent(CFAllocatorRef?allocator,AbsoluteTime?timeStamp,uint32_t?index,uint32_t?identity,IOHIDDigitizerEventMask?eventMask,IOHIDFloat?x,IOHIDFloat?y,IOHIDFloat?z,IOHIDFloat?tipPressure,IOHIDFloat?twist,Boolean?range,Boolean?touch,IOOptionBits?options);@implementation?SimulationTouch-?(void)performTouchInView:(UIView?*)view start:(bool)start{UIWindow?*_window?=?view.window;CGRect?fInWindow;if?([view isKindOfClass:[UIWindow?class]]){fInWindow?=?view.frame;}else{fInWindow?=?[_window convertRect:view.frame fromView:view.superview];}CGPoint?point?=CGPointMake(fInWindow.origin.x?+?fInWindow.size.width/2,fInWindow.origin.y?+?fInWindow.size.height/2);if(start){self.touch?=?[[UITouch?alloc]?initPoint:point window:_window];[self.touch setPhase:UITouchPhaseBegan];}else{[self.touch _setLocationInWindow:point resetPrevious:NO];[self.touch setPhase:UITouchPhaseEnded];}CGPoint?currentTouchLocation?=?point;UITouchesEvent?*event?=?[[UIApplication?sharedApplication]?_touchesEvent];[event?_clearTouches];uint64_t?machAbsoluteTime?=?mach_absolute_time();AbsoluteTime?timeStamp;timeStamp.hi?=?(UInt32)(machAbsoluteTime?>>?32);timeStamp.lo?=?(UInt32)(machAbsoluteTime);[self.touch setTimestamp:[[NSProcessInfo?processInfo]?systemUptime]];IOHIDDigitizerEventMask?eventMask?=?(self.touch.phase?==?UITouchPhaseMoved)??kIOHIDDigitizerEventPosition:?(kIOHIDDigitizerEventRange?|?kIOHIDDigitizerEventTouch);Boolean?isRangeAndTouch?=?(self.touch.phase?!=?UITouchPhaseEnded);IOHIDEventRef?hidEvent?=?IOHIDEventCreateDigitizerFingerEvent(kCFAllocatorDefault,timeStamp,0,2,eventMask,currentTouchLocation.x,currentTouchLocation.y,0,0,0,isRangeAndTouch,isRangeAndTouch,0);if?([self.touch respondsToSelector:@selector(_setHidEvent:)])?{[self.touch _setHidEvent:hidEvent];}[event?_setHIDEvent:hidEvent];[event?_addTouch:self.touch forDelayedDelivery:NO];[[UIApplication?sharedApplication]?sendEvent:event];}@end

總的來說就下載蘋果提供觸摸事件的源碼庫,分析源碼,然后設(shè)置斷掉調(diào)試,甚至反匯編來理解觸摸事件的原理。

2.統(tǒng)一攔截器

錄制和回放都居于事件流來處理的,而數(shù)據(jù)的事件流其實就是對一些關(guān)鍵方法的hook,由于我們?yōu)榱吮WC對業(yè)務(wù)代碼無侵入和擴(kuò)展性(隨便注冊事件),我們需要對所有方法統(tǒng)一hook,所有的方法由同一個鉤子來響應(yīng)處理。如下圖所示

?

這個鉤子是用用匯編編寫,由于匯編代碼比較多,而且比較難讀懂,所以這里暫時不附上源碼,匯編層主要把硬件里面的一些數(shù)據(jù)統(tǒng)一讀取出來,比如通用寄存器數(shù)據(jù)和浮點寄存器數(shù)據(jù),堆棧信息等等,甚至前面的前面的方法參數(shù)都可以讀取出來,最后轉(zhuǎn)發(fā)給c語言層處理。

匯編層把硬件相關(guān)信息組裝好后調(diào)用c層統(tǒng)一攔截接口,匯編層是為c層服務(wù)。c層無法讀取硬件相關(guān)信息,所以這里只能用匯編來讀取。c層接口通過硬件相關(guān)信息定位到當(dāng)前的方法是屬于哪個事件,知道了事件,也意味著知道了事件指令,知道了事件指令,也知道了哪些字段需要塞回去,也知道了被hook的原始方法。

c層代碼介紹如下: 由于是統(tǒng)一調(diào)用這個攔截器,所以攔截器并不知道當(dāng)前是哪個業(yè)務(wù)代碼執(zhí)行過來的,也不知道當(dāng)前這個業(yè)務(wù)方法有多少個參數(shù),每個參數(shù)類型是什么等等,這個接口代碼處理過程大概如下:

?●??通過寄存器獲取對象self
?●??通過寄存器獲取方法sel
?●??通過self和sel獲取對應(yīng)的事件指令
?●??通過事件指令回調(diào)上層來決定是否往下執(zhí)行
?●??獲取需要回放該事件的數(shù)據(jù)
?●??把數(shù)據(jù)塞回去,比如塞到某個寄存器里,或者塞到某個寄存器所指向的對象的某個字段等等
?●??如果需要立即回放則調(diào)用原來被hook的原始方法,如果不是立即回放,則需要把現(xiàn)場信息保存起來,并等待合適的時機(jī)由播放隊列來播放(調(diào)用)

//xRegs 表示統(tǒng)一匯編器傳入當(dāng)前所有的通用寄存器數(shù)據(jù),它們地址存在一個數(shù)組指針里//dRegs 表示統(tǒng)一匯編器傳入當(dāng)前所有的浮點寄存器數(shù)據(jù),它們地址也存在一個數(shù)組指針里//dRegs 表示統(tǒng)一匯編器傳入當(dāng)前堆棧指針//fp 表示調(diào)用棧幀指針void?replay_entry_start(void* xRegs,?void* dRegs,?void* spReg,?CallBackRetIns?*retIns,StackFrame?*fp,?void?*con_stub_lp){void?*objAdr = (((void?**)xRegs)[0]);//獲取對象本身self或者block對象本身EngineManager?*manager = [EngineManager?sharedInstance];ReplayEventIns?*node = [manager getEventInsWithBlock:objAdr];id obj = (__bridge id)objAdr;void?*xrArg = ((void?**)xRegs)+2;if(nil?== node){SEL selecter = (SEL)(((void?**)xRegs)[1]);?//對應(yīng)的對象調(diào)用的方法Class?tclass = [obj?class];//object_getClass(obj);object_getClass方法只能通過對象獲取它的類,不能傳入class 返回class本身,do{node = [manager getEventIns:tclass sel:selecter];//通過對象和方法獲取對應(yīng)的事件指令節(jié)點}while(nil?== node && (tclass = class_getSuperclass(tclass)));}else{xrArg = ((void?**)xRegs)+1;}assert(node &&?"node is nil in replay_call_start");//回調(diào)通知上層當(dāng)前回放是否打斷if(node.BreakCurReplayExe?&& node.BreakCurReplayExe(obj,node,xrArg,dRegs)){retIns->nodeAddr = NULL;retIns->recordOrReplayData = NULL;retIns->return_address = NULL;return;}bool?needReplay =?true;//回調(diào)通知上層當(dāng)前即將回放該事件if(node.willReplay){needReplay = (*(node.willReplay))(obj,node,xrArg,dRegs);}if(needReplay){ReplayEventData?*replayData =?nil;if(node.getReplayData){//獲取回放該事件對應(yīng)的數(shù)據(jù)replayData = (*(node.getReplayData))(obj,node,xrArg,dRegs);}else//默認(rèn)獲取方法{replayData = [manager getNextReplayEventData:node];}//以下就是真正的回放,即是把數(shù)據(jù)塞回去,并調(diào)用原來被hook的方法if(replayData){if(replay_type_intercept_call == node.replayType){sstuffArg(xRegs,dRegs,spReg,node,replayData.orgDic);NSArray?*arglist = fetchAllArgInReplay(xRegs, dRegs, spReg, node);ReplayInvocation?*funobj = [[ReplayInvocation?alloc] initWithFunPtr:node.callBack ? node.callBack : [node getOrgFun]args:arglistargType:[node getFunTypeStr]retType:rf_return_type_v];if([[EngineManager?sharedInstance] setRepalyEventReady:replayData funObj:funobj]){//放到播放隊列里播放,返回沒調(diào)用地址,讓其不往下走retIns->return_address = NULL;return?;}}else{//塞數(shù)據(jù)sstuffArg(xRegs,dRegs,spReg,node,replayData.orgDic);}}retIns->nodeAddr = (__bridge?void?*)node;retIns->recordOrReplayData = (__bridge?void?*)replayData;retIns->return_address = node.callBack ? node.callBack : [node getOrgFun];replayData.runStatus = relay_event_run_status_runFinish;}else{retIns->nodeAddr = NULL;retIns->recordOrReplayData = NULL;retIns->return_address = [node getOrgFun];}}

3.怎樣統(tǒng)一hook block

如果你只是想大概理解block的底層技術(shù),你只需google一下即可。 如果你想全面深入的理解block底層技術(shù),那網(wǎng)上的那些資料遠(yuǎn)遠(yuǎn)滿足不了你的需求。 只能閱讀蘋果編譯器clang源碼和列出比較有代表性的block例子源碼,然后轉(zhuǎn)成c語言和匯編,通過c語言結(jié)合匯編研究底層細(xì)節(jié)。

何謂 oc block?

?●??block就是閉包,跟回調(diào)函數(shù)callback很類似,閉包也是對象。
?●??blcok的特點: 1.可有參數(shù)列表 2.可有返回值 3.有方法體 4.capture上下文變量 5.有對象引用計數(shù)的內(nèi)存管理策略(block生命周期)。
?●??block的一般存儲在內(nèi)存中形態(tài)有三種 _NSConcretStackBlock(棧)_NSConcretGlobalBlock(全局)_NSConcretMallocBlock(堆)。

系統(tǒng)底層怎樣表達(dá)block?

我們先來看一下block的例子:

void?test(){__block?int?var1 =?8;?//上下文變量NSString?*var2 = @"我是第二個變量”; //上下文變量void (^block)(int) = ^(int arg)//參數(shù)列表{var1 = 6;NSLog(@"arg = %d,var1 = %d, var2 = %@", arg, var1, var2);};block(1);//調(diào)用block語法dispatch_async(dispatch_get_global_queue(0, 0), ^{block(2); //異步調(diào)用block});}

這段代碼首先定義兩個變量,接著定義一個block,最后調(diào)用block。

?●??兩個變量:這兩個變量都是被block引用,第一個變量有關(guān)鍵字__block,表示可以在block里對該變量賦值,第二個變量沒有__block關(guān)鍵字,在block里只能讀,不能寫。
?●??兩個調(diào)用block的語句:第一個直接在當(dāng)前方法test()里調(diào)用,此時的block內(nèi)存數(shù)據(jù)在棧上,第二個是異步調(diào)用,就是說當(dāng)執(zhí)行block(2)時test()可能已經(jīng)運(yùn)行完了,test()調(diào)用棧可能已經(jīng)被銷毀。那這種情況block的數(shù)據(jù)肯定不能在棧上,只能在堆上或者在全局區(qū)。

系統(tǒng)底層表達(dá)block比較重要的幾種數(shù)據(jù)結(jié)構(gòu)如下:

注意:雖然底層是用這些結(jié)構(gòu)體來表達(dá)block,但是它們并不是源碼,是二進(jìn)制代碼

enum{BLOCK_REFCOUNT_MASK = (0xffff),BLOCK_NEEDS_FREE = (1?<<?24),BLOCK_HAS_COPY_DISPOSE = (1?<<?25),BLOCK_HAS_CTOR = (1?<<?26),//todo == BLOCK_HAS_CXX_OBJ?BLOCK_IS_GC = (1?<<?27),BLOCK_IS_GLOBAL = (1?<<?28),BLOCK_HAS_DESCRIPTOR = (1?<<?29),//todo == BLOCK_USE_STRET?BLOCK_HAS_SIGNATURE = (1?<<?30),OBLOCK_HAS_EXTENDED_LAYOUT = (1?<<?31)};enum{BLOCK_FIELD_IS_OBJECT =?3,BLOCK_FIELD_IS_BLOCK =?7,BLOCK_FIELD_IS_BYREF =?8,OBLOCK_FIELD_IS_WEAK =?16,OBLOCK_BYREF_CALLER =?128};typedef?struct?block_descriptor_head{unsigned?long?int?reserved;unsigned?long?int?size;?//表示主體block結(jié)構(gòu)體的內(nèi)存大小}block_descriptor_head;typedef?struct?block_descriptor_has_help{unsigned?long?int?reserved;unsigned?long?int?size;?//表示主體block結(jié)構(gòu)體的內(nèi)存大小void?(*copy)(void?*dst,?void?*src);//當(dāng)block被retain時會執(zhí)行此函數(shù)指針void?(*dispose)(void?*);//block被銷毀時調(diào)用struct?block_arg_var_descriptor *argVar;}block_descriptor_has_help;typedef?struct?block_descriptor_has_sig{unsigned?long?int?reserved;unsigned?long?int?size;const?char?*signature;//block的簽名信息struct?block_arg_var_descriptor *argVar;}block_descriptor_has_sig;typedef?struct?block_descriptor_has_all{unsigned?long?int?reserved;unsigned?long?int?size;void?(*copy)(void?*dst,?void?*src);void?(*dispose)(void?*);const?char?*signature;struct?block_arg_var_descriptor *argVar;}block_descriptor_has_all;typedef?struct?block_info_1{void?*isa;//表示當(dāng)前blcok是在堆上還是在棧上,或在全局區(qū)_NSConcreteGlobalBlockint?flags;?//對應(yīng)上面的enum值,這些枚舉值是我從編譯器源碼拷貝過來的int?reserved;void?(*invoke)(void?*, ...);//block對應(yīng)的方法體(執(zhí)行體,就是代碼段)void?*descriptor;//此處指向上面幾個結(jié)構(gòu)體中的一個,具體哪一個根據(jù)flags值來定,它用來進(jìn)一步來描述block信息//從這個字段開始起,后面的字段表示的都是此block對外引用的變量。NSString?*var2;byref_var1_1 var1;} block_info_1;

這個例子中的block在底層表達(dá)大概如下圖:

?

首先用block_info_1來表達(dá)block本身,然后用block_desc_1來具體描述block相關(guān)信息(比如block_info_1結(jié)構(gòu)體大小,在堆上還是在棧上?copy或dispose時調(diào)用哪個方法等等),然而block_desc_1具體是哪個結(jié)構(gòu)體是由block_info_1中flags字段來決定的,block_info_1里的invoke字段是指向block方法體,即是代碼段。block的調(diào)用就是執(zhí)行這個函數(shù)指針。由于var1是可寫的,所以需要設(shè)計一個結(jié)構(gòu)體(byref_var1_1)來表達(dá)var1,為什么var2直接用他原有的類型表達(dá),而var1要用結(jié)構(gòu)體來表達(dá)。篇幅有限,這個自己想想吧?

block小結(jié)

?●??為了表達(dá)block,底層設(shè)計三種結(jié)構(gòu)體:block_info_1,block_desc_1,byref_var1_1,三種函數(shù)指針: block invoke方法體,copy方法,dispose方法
?●??其實表達(dá)block是非常復(fù)雜的,還涉及到block的生命周期,內(nèi)存管理問題等等,我在這里只是簡單的貫穿主流程來介紹的,很多細(xì)節(jié)都沒介紹。

怎樣統(tǒng)一 hook block?

通過上面的分析,得知oc里的block就是一個結(jié)構(gòu)體指針,所以我在源碼里可以直接把它轉(zhuǎn)成結(jié)構(gòu)體指針來處理。 統(tǒng)一hook block源碼如下:

VoidfunBlock?createNewBlock(VoidfunBlock?orgblock,?ReplayEventIns?*blockEvent,bool?isRecord){if(orgblock && blockEvent){VoidfunBlock?newBlock = ^(void){orgblock();if(nil?== blockEvent){assert(0);}};trace_block_layout *blockLayout = (__bridge trace_block_layout *)newBlock;blockLayout->invoke = (void?(*)(void?*, ...))(isRecord?hook_var_block_callBack_record:hook_var_block_callBack_replay);return?newBlock;}return?nil;}

我們首先新建一個新的block newBlock,然后把原來的block orgblock 和 事件指令blockEvent包到新的blcok中,這樣達(dá)到引用的效果。然后把

新的block轉(zhuǎn)

成結(jié)構(gòu)體指針,并把結(jié)構(gòu)體指針中的字段invoke(方法體)指向統(tǒng)一回調(diào)方法。你可能詫異新的block是沒有參數(shù)類型的,原來block是有參數(shù)類型,

外面調(diào)用原

來block傳遞參數(shù)時會不會引起crash?答案是否定的,因為這里構(gòu)造新的block時 我們只用block數(shù)據(jù)結(jié)構(gòu),block的回調(diào)方法字段已經(jīng)被閹割,回

調(diào)方法已經(jīng)指

向統(tǒng)一方法了,這個統(tǒng)一方法可以接受任何類型的參數(shù),包括沒有參數(shù)類型。這個統(tǒng)一方法也是匯編實現(xiàn),代碼實現(xiàn)跟上面的匯編層代碼類似,這

里就不附上源

碼了。

那怎樣在新的blcok里讀取原來的block和事件指令對象呢? 代碼如下:

void?var_block_callback_start_record(trace_block_layout * blockLayout){VoidfunBlock?orgBlock = (__bridge?VoidfunBlock)(*((void?**)((char?*)blockLayout +?sizeof(trace_block_layout))));ReplayEventIns?*node = (__bridge?ReplayEventIns?*)(*((void?**)((char?*)blockLayout +?40)));}

總結(jié)

本文大概介紹了問題回放框架,接著介紹三個關(guān)鍵技術(shù)。這三個技術(shù)相對比較深入,歡迎在留言區(qū)評論,我們期待與大家交流,共同探討。


阿里云雙十一1折拼團(tuán)活動:滿6人,就是最低折扣了!
【滿6人】1核2G云服務(wù)器99.5元一年298.5元三年 2核4G云服務(wù)器545元一年 1227元三年
【滿6人】1核1G MySQL數(shù)據(jù)庫 119.5元一年
【滿6人】3000條國內(nèi)短信包 60元每6月
參團(tuán)地址:http://click.aliyun.com/m/1000020293/


原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。

總結(jié)

以上是生活随笔為你收集整理的工程师如何“神还原”用户问题?闲鱼回放技术揭秘的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

久久理论影院 | 免费情缘 | 日韩理论片中文字幕 | a级国产片 | 国内小视频 | 91精品在线观看视频 | 免费看一级特黄a大片 | 国产精品一区在线观看 | 91精品夜夜 | 久久一区国产 | 国产成人av网| 久久国产精品99久久久久久进口 | 欧美激情视频一二三区 | 久久精品久久久久久久 | 精品一区二区亚洲 | 婷婷久久网站 | 爱爱一区 | 日韩小视频 | 久久狠狠一本精品综合网 | 欧美日韩一区二区三区在线观看视频 | 免费人成在线观看 | 能在线观看的日韩av | 亚洲免费国产视频 | 男女免费视频观看 | 亚洲欧美婷婷六月色综合 | 黄色免费电影网站 | 国产精品露脸在线 | 夜夜骑天天操 | 日韩一区二区三区免费视频 | 国产亚洲无 | 日本在线观看视频一区 | 亚洲成年人免费网站 | 久久精品高清视频 | 国产精品久久久久一区 | 亚洲黄色区 | 色综合狠狠干 | 国产一级视频在线 | 亚洲精品大片www | 日日干干夜夜 | 亚洲国产无 | 国产一区二区三区四区大秀 | 久久免费视频99 | 久久中国精品 | 日本最新中文字幕 | 综合视频在线 | 伊人影院99 | 色99视频| 精品女同一区二区三区在线观看 | 日韩高清无线码2023 | 337p西西人体大胆瓣开下部 | 精品在线观看国产 | 久久久久久久综合色一本 | 日日爽夜夜爽 | 黄色av网站在线免费观看 | 国产色影院 | sm免费xx网站 | 亚洲精品欧美专区 | 亚洲精品乱码久久久久久久久久 | 午夜影院一级片 | 中文字幕乱码日本亚洲一区二区 | 五月婷婷影院 | 国产麻豆精品免费视频 | 国产精品一区电影 | 99精品视频免费看 | 五月天国产精品 | 夜夜视频欧洲 | 国产精品毛片完整版 | 96av麻豆蜜桃一区二区 | av电影中文| 日韩理论在线 | 国产午夜一级毛片 | 久久久国产精品麻豆 | 国产手机视频在线播放 | 操操综合 | 国产一区观看 | 午夜美女网站 | 成人a v视频 | 亚洲欧洲美洲av | 亚洲成年片 | 波多野结衣在线观看一区二区三区 | 亚洲精品在线视频 | 日韩在线中文字幕视频 | 亚洲一区在线看 | 西西人体4444www高清视频 | 黄色一级大片免费看 | 伊人春色电影网 | 人人干人人超 | 日韩综合第一页 | 在线国产中文字幕 | 久久超碰97| 日韩和的一区二在线 | 亚一亚二国产专区 | 午夜av激情| 日韩精品在线免费观看 | 天堂久久电影网 | 日日精品 | 中文字幕久久久精品 | 日日夜精品 | 精品国产乱码久久久久久三级人 | 四虎影视www | 久久久久久久久免费视频 | 亚洲精品乱码久久久久久蜜桃不爽 | 视频一区在线免费观看 | 九九免费在线视频 | 久久久国产精品久久久 | 久香蕉| 国产一区二区在线免费观看 | 久久精品79国产精品 | 黄a在线观看 | 丁香婷婷色 | 午夜精品视频免费在线观看 | 欧美国产91| 中文字幕一区二区三区乱码在线 | 国产一区二区在线影院 | 午夜精品一区二区三区视频免费看 | 午夜黄色一级片 | 91在线蜜桃臀 | 欧美国产91 | 99视频免费播放 | 97精品在线| 日韩理论电影网 | www.香蕉视频在线观看 | 精品在线视频观看 | 美女视频黄频大全免费 | 精品国产精品久久一区免费式 | 成人黄色电影免费观看 | 免费在线观看a v | 91亚洲欧美激情 | 在线观看视频99 | 久久精品影片 | 97在线免费观看 | 免费在线观看av电影 | aav在线 | 国产成人精品综合久久久久99 | 99精品久久99久久久久 | 成人av高清 | 天天操天天玩 | 午夜av在线播放 | 在线国产能看的 | 国产又黄又爽又猛视频日本 | 亚州国产精品视频 | 日韩精品视频免费专区在线播放 | 国产亚洲精品久久久久久网站 | av黄色影院 | 日韩欧美视频一区二区三区 | 欧美另类v | 亚洲国产三级 | 久久久色| 精品国产99国产精品 | 天天操天天吃 | 国产999精品久久久久久 | 日韩一区二区三 | 久久久久久久久影院 | 人成午夜视频 | 国产精品大片 | 免费十分钟 | 久久久久欠精品国产毛片国产毛生 | 国产亚洲精品成人av久久ww | 超碰在线1| 婷婷色在线资源 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 国产va在线 | 国产香蕉97碰碰久久人人 | 精品久久久久一区二区国产 | 在线日本看片免费人成视久网 | 成人在线网站观看 | 91免费网站在线观看 | 日韩在线观看的 | 99精品国产高清在线观看 | 国产精品女人网站 | 成人av电影在线播放 | 色婷婷色 | 亚色视频在线观看 | 一区二区三区 中文字幕 | 91精品电影 | 欧美日韩一区二区在线观看 | www.xxx.性狂虐 | 五月婷婷六月丁香 | 麻花豆传媒mv在线观看 | 日韩av电影免费观看 | 成人夜晚看av| 国产亚洲精品久久久久久 | 国产视频一区在线播放 | 91av在线播放视频 | 国产高清视频在线免费观看 | 日韩综合在线观看 | 国产在线久久久 | 91黄视频在线观看 | 免费又黄又爽 | 九九免费观看视频 | 久久久久久久久久网 | 国产一区自拍视频 | 欧美成人在线免费 | 日韩欧美精品在线 | 久久电影日韩 | 精品免费一区二区三区 | 国产一级a毛片视频爆浆 | 精品一二三区视频 | 精品99999 | 超碰电影在线观看 | 天天操天天色天天射 | 人人干97 | 天天爽网站 | 91丨九色丨高潮 | 青草视频在线 | 国内精品一区二区 | 国产国语在线 | 四虎影视精品永久在线观看 | 美女网站在线免费观看 | 丁香久久 | 久久精品99| 日韩一三区 | 国产精品对白一区二区三区 | 成人小视频在线播放 | 看污网站| 五月婷婷导航 | 久草视频免费播放 | 国产精品爽爽久久久久久蜜臀 | 国产欧美日韩一区 | 在线 国产 亚洲 欧美 | 国产一区二区三区视频在线 | 成人免费在线观看入口 | 中文字幕av免费在线观看 | 精品国产一区二区三区久久久 | 国产一区二区三区免费视频 | 91麻豆操 | 国产精品av电影 | 日韩有码在线观看视频 | 久久九九影院 | 免费午夜av | www成人精品 | 夜夜夜夜夜夜操 | 国产一区二区三区四区大秀 | 97看片 | 麻豆视频在线免费 | 制服丝袜亚洲 | 日韩天堂在线观看 | 国产精品涩涩屋www在线观看 | 亚洲精品在线观看不卡 | 色偷偷中文字幕 | 蜜臀av免费一区二区三区 | 日韩av电影一区 | 国产精品99久久久久久久久久久久 | 久操免费视频 | 亚洲成人黄色在线 | 久久精品人人做人人综合老师 | 亚洲黄色影院 | 国产精品久久久久久久av大片 | 丁香九月婷婷综合 | 国产无套精品久久久久久 | 精品久久久久久久久久岛国gif | www.国产毛片 | 98涩涩国产露脸精品国产网 | 中文字幕一区二区在线观看 | 亚洲小视频在线 | 97看片网 | 国产精品免费成人 | 激情网色 | 在线色吧 | 97高清视频 | 精品国产久| 日韩av一区在线观看 | 手机av资源 | 在线一二三四区 | 亚洲精品国产高清 | 久久色视频 | 成人午夜电影免费在线观看 | 色综合久久精品 | 五月天色综合 | 日韩av快播电影网 | 日韩欧美视频免费看 | 免费成人黄色 | 中文在线中文资源 | 久久涩视频 | 国产精品va在线观看入 | 久久国产热 | 日韩精品一区二区在线观看 | 亚洲视频综合在线 | 国产亚洲精品综合一区91 | 三三级黄色片之日韩 | 成人在线观看日韩 | 毛片永久新网址首页 | 在线视频 日韩 | 欧美精品在线免费 | 激情综合亚洲 | 国产免费专区 | 日韩xxxbbb| 丁香六月婷婷开心婷婷网 | 在线视频观看91 | 久久国产色 | 狠狠色丁婷婷日日 | 久久黄色a级片 | 午夜国产一区二区三区四区 | 一级欧美黄 | 亚洲九九九在线观看 | 五月婷婷丁香激情 | 97精产国品一二三产区在线 | 亚洲 欧美 综合 在线 精品 | 91精品国产欧美一区二区 | 91av色| 亚洲干| 婷婷综合亚洲 | 综合天天色 | 国产一区二区三区四区在线 | 成人精品一区二区三区中文字幕 | 国产91全国探花系列在线播放 | 中文字幕久久网 | 在线观看中文字幕亚洲 | 在线观看视频黄色 | 色久天 | 亚洲第一成网站 | 麻豆91视频 | 在线a亚洲视频播放在线观看 | 日韩欧美大片免费观看 | 九九九电影免费看 | 欧美日bb | av高清一区二区三区 | 欧美aaaxxxx做受视频 | 青青河边草免费 | 五月天网站在线 | 一区二区三区四区五区在线 | 国产老太婆免费交性大片 | 欧美精彩视频在线观看 | 女人18片毛片90分钟 | 奇米影视四色8888 | 91亚洲精品久久久中文字幕 | 久草视频99 | 国内精品在线看 | 香蕉影院在线播放 | 在线www色 | 亚洲无人区小视频 | 国产精品久久一区二区三区, | 久久久久亚洲精品成人网小说 | 久久任你操| 一区二区三区在线电影 | 91豆麻精品91久久久久久 | 五月婷婷中文 | 日韩免费福利 | 日韩三级视频 | 久久99国产精品自在自在app | 国产精品久久久99 | 综合黄色网 | 国产精品18p | 在线国产专区 | 国产视频一区二区在线观看 | 成人国产一区二区 | 久久一区二区三区四区 | 在线观看中文字幕第一页 | 久久这里只有精品23 | 在线免费观看黄网站 | 久久综合成人网 | 97视频久久久 | 狠狠色噜噜狠狠狠狠2022 | 免费一级日韩欧美性大片 | 国产亚洲精品免费 | 91精品一区二区三区蜜臀 | 国产资源精品在线观看 | 久久人人爽爽 | 中文字幕在线播放一区二区 | 国产精品久久免费看 | 国语麻豆 | 欧美特一级 | 就要干b | 亚洲综合精品视频 | 精品国产aⅴ一区二区三区 在线直播av | 亚洲精品av在线 | 亚洲最新av在线网址 | 欧美黄色免费 | 国内丰满少妇猛烈精品播放 | 中文字幕在线观看视频一区二区三区 | 日日夜夜中文字幕 | 国产亚洲精品久久久久久移动网络 | 日韩av一区二区三区 | 欧美一区成人 | 国产视频亚洲精品 | 国产高清在线免费视频 | 欧美激情视频在线观看免费 | 久久伊人精品天天 | 国产区在线看 | 国产视频一区在线免费观看 | 国产一级片免费观看 | 国产视频不卡一区 | 欧美a级在线免费观看 | 天天干天天操人体 | 麻豆精品传媒视频 | 国产三级久久久 | 伊人日日干 | 免费人成网 | av高清一区二区三区 | 日韩欧美久久 | 欧美analxxxx | 欧美福利视频 | 久久久精品网站 | 激情综合啪啪 | 啪啪肉肉污av国网站 | 日韩性xxxx| 丁香婷婷综合色啪 | 五月婷婷在线视频观看 | 欧美日本一二三 | 亚洲视频www | 久久99操| 91少妇精拍在线播放 | 日本aa在线| 天天干,狠狠干 | 国语黄色片| 久久在线视频精品 | 久久人视频 | 国产一区免费 | 日韩欧美高清一区二区三区 | 狠狠干网站 | 91精品国产92久久久久 | 成人18视频 | 久久精品视频观看 | 波多野结衣在线视频免费观看 | 亚洲精品资源在线 | 免费在线观看成年人视频 | 999成人 | 在线视频久 | 五月天婷婷在线播放 | 国产精品自产拍在线观看蜜 | 美女视频a美女大全免费下载蜜臀 | 国产精品麻豆99久久久久久 | 在线观看的av| 开心丁香婷婷深爱五月 | 久久a免费视频 | 欧美另类网站 | 丁香激情网 | 中文字幕国产在线 | 欧美日韩国产精品一区 | 中文av资源站| 日韩在线视频网址 | 亚洲人成在线电影 | 久久久一本精品99久久精品66 | 91大神一区二区三区 | 97超碰国产精品 | 在线免费视频 你懂得 | 国产剧在线观看片 | 午夜性盈盈 | 在线看一区 | 高潮久久久久久久久 | 成人在线免费观看视视频 | 亚洲国产成人在线播放 | 亚洲综合在| 精品 激情 | 丁香婷婷久久久综合精品国产 | 日韩在线欧美在线 | 久久99久久久久 | 天天爱天天射天天干天天 | 欧美特一级 | 国产一级大片在线观看 | 欧美日韩视频在线观看免费 | 免费看污的网站 | 在线看黄色的网站 | 国产精品一区二区三区在线免费观看 | 久久这里只有精品23 | 久久午夜剧场 | 美女黄频视频大全 | 日韩理论电影网 | 国产老妇av | 国产v在线播放 | 成人午夜片av在线看 | 久久国产亚洲 | 日韩av一区二区三区四区 | 99久久99精品| 日韩精品无码一区二区三区 | 夜色在线资源 | 四虎海外影库www4hu | 国产视频亚洲精品 | 婷婷av在线 | se视频网址 | 亚洲丁香久久久 | 在线视频日韩欧美 | 国产精品99久久久精品 | 国产一卡二卡四卡国 | 99久久精品视频免费 | 国产福利在线免费观看 | 天天操夜夜操天天射 | www.伊人网| 在线观看自拍 | 三上悠亚一区二区在线观看 | 久久精品网站免费观看 | 中文字幕乱在线伦视频中文字幕乱码在线 | 精产嫩模国品一二三区 | 国产高清免费观看 | 97超碰影视| a资源在线| 欧美91精品 | 国产不卡视频在线播放 | 在线国产能看的 | 亚洲精品福利在线观看 | 国产原创91 | 天天爱av导航 | 国产高清精品在线 | 亚洲综合在线一区二区三区 | 一本一本久久a久久 | 国产99久久九九精品免费 | 久综合网 | 制服丝袜一区二区 | 精品一区二区久久久久久久网站 | 久久tv视频 | 国产亚洲成av片在线观看 | 国产黄色电影 | 欧美精品一区二区在线观看 | 久久这里只有精品首页 | 欧美在线观看视频一区二区三区 | 免费视频久久久久 | 一区二区视频在线免费观看 | 国产精品综合久久久久 | 中文字幕有码在线播放 | 亚洲理论在线 | 久久久精品午夜 | 国产精品白浆 | 黄色一级片视频 | 国产精品女同一区二区三区久久夜 | www亚洲一区 | 超黄视频网站 | 天天干天天碰 | 97精品一区二区三区 | 欧美人交a欧美精品 | 毛片在线网 | 91av网址 | 麻豆视频在线看 | 日韩精品久久久久 | 久久精品国产免费 | 久草在线视频首页 | 色姑娘综合网 | 欧美激情视频在线观看免费 | 在线黄色国产 | 国产护士在线 | 国产一区二区精品久久 | 天天操天天射天天爱 | 免费黄av| 国产美女无遮挡永久免费 | 在线电影播放 | 国产久草在线 | 国产精品99免视看9 国产精品毛片一区视频 | 97在线免费 | 99久久精品国产免费看不卡 | 天天射综合 | 亚一亚二国产专区 | 91视频亚洲| 久久99久久99精品免观看软件 | 在线视频第一页 | 99免在线观看免费视频高清 | 九九免费在线视频 | 国产xx在线 | 99久久视频| 月下香电影 | 国产999精品久久久 免费a网站 | 久久久综合精品 | 日本久久视频 | 91最新地址永久入口 | 又湿又紧又大又爽a视频国产 | 日韩免费在线观看 | 国产视频不卡一区 | 日韩欧美视频免费看 | 成人在线免费视频观看 | 国产69久久久 | 在线观看亚洲成人 | 国产午夜精品福利视频 | 亚洲欧洲国产视频 | 新av在线 | 99亚洲精品视频 | 久久婷婷精品 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 911国产 | 国产精品视频99 | 69国产精品成人在线播放 | av黄色av | 久久国产精品偷 | 久久视频99 | 欧美亚洲国产一卡 | 美女网站视频免费都是黄 | 黄色成品视频 | 亚洲精品三级 | 五月婷在线播放 | 综合激情网 | 国产精品激情偷乱一区二区∴ | 久久免费精彩视频 | 日韩久久精品一区二区三区下载 | 香蕉视频免费看 | 7777xxxx| 在线看av网址 | 在线免费观看欧美日韩 | 人人爽人人爽人人片av | 久久精品日本啪啪涩涩 | 日韩欧美国产激情在线播放 | 国产精品不卡在线播放 | 天天曰天天爽 | 一区二区三区精品在线视频 | 欧美日韩成人 | 亚洲mv大片欧洲mv大片免费 | 国产精品美乳一区二区免费 | 不卡的av在线播放 | 午夜精品久久久久久久99婷婷 | 亚洲欧美日韩一区二区三区在线观看 | 国产精品都在这里 | 午夜婷婷网| 夜夜骑日日操 | 在线观看一级视频 | 一级淫片a | 国产日韩精品在线观看 | 国产精品99蜜臀久久不卡二区 | 韩国精品在线 | 四虎影视www | 人人艹人人 | 免费网站在线观看成人 | 日韩高清在线不卡 | www.97视频| 天天插天天操天天干 | 久久夜靖品 | 午夜精品99久久免费 | 亚洲精品在线观看不卡 | 91福利视频在线 | 国产高清av在线播放 | 国产99在线 | 一级做a视频 | 亚洲午夜剧场 | 久久99国产综合精品 | 久久激情久久 | 国产三级视频在线 | 国产美女精品视频 | 色偷偷888欧美精品久久久 | 97免费视频在线播放 | www.com久久 | 五月婷丁香 | av片在线观看免费 | 探花视频免费观看 | 精品亚洲国产视频 | 丁香六月av | 99操视频 | 国产色婷婷 | 国产丝袜一区二区三区 | 国产黄色网 | 国产999视频| 日韩免费一级a毛片在线播放一级 | 麻豆国产视频 | 人人干天天射 | 99视频在线免费观看 | 国产精久久久久久妇女av | 国产成人福利在线观看 | 黄色三级视频片 | 亚洲japanese制服美女 | 国产色久 | 久久美女免费视频 | 国产一级性生活 | 视频精品一区二区三区 | 悠悠av资源片 | 一本一本久久a久久精品牛牛影视 | 五月激情在线 | 97精品国产97久久久久久 | 午夜精品中文字幕 | 2024国产精品视频 | x99av成人免费 | 亚洲理论在线观看电影 | 九九热av| 天天曰天天干 | 午夜精品麻豆 | 亚洲九九九 | 欧美成人手机版 | 激情九九 | 午夜免费福利视频 | 91丨九色丨高潮 | 在线观看久久久久久 | 狠狠狠狠狠狠狠狠干 | 中文理论片 | 久久不卡国产精品一区二区 | 91视频观看免费 | 欧美日韩裸体免费视频 | 日韩综合一区二区 | 在线影院 国内精品 | 99色精品视频 | 欧美人交a欧美精品 | 国产精品不卡一区 | 久久爱综合 | 天天爱天天 | www视频在线观看 | 亚洲h色精品 | 久久精品视频国产 | 亚洲三级网| av五月婷婷 | 久久久久久久久久网站 | 国产精品国产三级国产 | av日韩av | 国产日韩欧美视频 | 久影院| 九九久久精品视频 | 久久在线一区 | 成年人免费在线 | 亚洲欧洲成人 | 麻豆久久精品 | 国产一区在线视频播放 | 在线观看麻豆av | 九九99| 午夜久久久久久久久久久 | h网站免费在线观看 | 日韩视频一区二区在线 | 激情欧美日韩一区二区 | 在线观看视频99 | 欧美在线观看视频一区二区 | a黄色片在线观看 | 欧美 亚洲 另类 激情 另类 | 久久免费99精品久久久久久 | 在线免费观看视频一区二区三区 | 色com | 国产成人三级三级三级97 | 97精品国产手机 | 人人藻人人澡人人爽 | 午夜av免费在线观看 | 欧美美女激情18p | 亚洲精品视频在线播放 | 久久久99精品免费观看乱色 | 国产精品嫩草影院99网站 | 久久九九免费视频 | 粉嫩av一区二区三区四区 | 日韩精品免费一区二区三区 | 久久久免费观看视频 | 一区二区三区韩国免费中文网站 | 91香蕉嫩草 | 欧美性护士 | 亚洲激情六月 | 欧美精品视 | 中文字幕中文字幕在线中文字幕三区 | 99视频这里有精品 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 国产国语在线 | 久久99电影| 最近免费在线观看 | 成人黄色小说在线观看 | 91av手机在线 | 狠狠成人| 亚洲一级二级 | 黄色免费av | 国产精品你懂的在线观看 | 三级小视频在线观看 | 国产免费成人av | 欧美日韩国产在线精品 | 国产精品成人免费精品自在线观看 | 美女久久久久久久久久久 | 成人试看120秒 | 婷婷丁香激情五月 | 91成熟丰满女人少妇 | 国产精品入口久久 | 亚洲热久久| 麻豆视频在线观看免费 | 天堂入口网站 | 99精品观看 | 91中文字幕视频 | 在线免费高清视频 | av福利免费 | 欧产日产国产69 | 亚洲欧美国产视频 | 日本三级吹潮在线 | 91视频在线免费观看 | 在线观看亚洲精品视频 | 在线国产黄色 | 中文字幕精品一区二区三区电影 | 美女视频黄色免费 | 五月开心婷婷 | 99免费精品视频 | 国产在线视频一区二区三区 | 国产福利精品一区二区 | 国产一区av在线 | 人人草网站 | 安徽妇搡bbbb搡bbbb | 一区二区三区日韩在线 | 久久天天躁狠狠躁夜夜不卡公司 | 精品毛片一区二区免费看 | 国产精品999久久久 久产久精国产品 | 国产精品视频一二三 | 中文字幕在线观看免费高清完整版 | 最近中文字幕视频网 | 欧美中文字幕第一页 | 免费在线观看不卡av | 欧美日韩国产一区二 | 国产精品 中文字幕 亚洲 欧美 | 四虎影视www | 亚洲毛片久久 | 欧美性免费 | 激情久久综合网 | 久久久福利视频 | 日韩亚洲在线视频 | 夜色成人av | 国产精品久久久久久久久岛 | www激情com| 国产一级免费播放 | 国产精品久久网站 | 成人黄色在线 | 91九色视频导航 | 色国产精品 | 亚洲精品视频在线播放 | 一级黄色片在线观看 | 91久久久久久久一区二区 | 99久久婷婷国产精品综合 | av日韩国产 | 99视频在线免费看 | 色开心| 亚洲一区二区三区毛片 | 亚洲精品欧洲精品 | 成人在线视频观看 | 日本午夜在线亚洲.国产 | 人人擦 | 久久久久久久免费 | 中文电影网 | 五月婷婷六月丁香 | 国内精品久久久久久久影视麻豆 | 天天爽天天搞 | 天天操天天综合网 | 亚洲欧洲成人精品av97 | 男女激情麻豆 | 日韩一级电影在线观看 | 亚洲影视九九影院在线观看 | 国产艹b视频| 91精品视频导航 | 在线不卡a | 免费精品国产va自在自线 | 国内亚洲精品 | 999成人国产 | 久久免费精品 | 人人射 | www.久久色.com| 久久a v视频 | 国产精品永久免费观看 | 五月天电影免费在线观看一区 | 免费视频二区 | 9i看片成人免费看片 | 91一区二区三区在线观看 | 97精品国产一二三产区 | 久久99在线视频 | 正在播放 国产精品 | 91视频在线国产 | 国产精品免费在线播放 | 91在线一区 | 色婷婷综合久久久久 | 国产91精品久久久久久 | 三级黄色片在线观看 | 欧美精品日韩 | 四虎在线免费视频 | 成人免费在线观看电影 | 天堂网在线视频 | 免费观看一级特黄欧美大片 | 日本不卡一区二区三区在线观看 | 天天射天天射 | 色片网站在线观看 | 在线中文字幕电影 | 国产成人亚洲精品自产在线 | 深爱激情综合网 | 国产97av | 国产97色在线 | 国产精品免费观看网站 | 欧美日韩二区三区 | 久久免费av| av免费看看| 久久爱992xxoo | 在线观看aa | 国产精品成人自产拍在线观看 | 91日韩精品一区 | 在线a视频 | 免费电影播放 | 视频 国产区| 国产免费av一区二区三区 | 日韩中文字幕在线不卡 | 天天操天天吃 | 国产精品毛片久久久久久 | 五月天伊人网 | 国产一区在线精品 | 国产999视频在线观看 | 91人人揉日日捏人人看 | 国产在线一线 | av久久久 | 99久热| 日韩av一区二区三区在线观看 | 国产精品一级视频 | 欧美一区二区三区激情视频 | 亚洲国产婷婷 | 在线观看中文字幕av | 日韩在线视频精品 | 免费网站看v片在线a | 亚洲国产成人精品在线 | 国产群p| 精品96久久久久久中文字幕无 | 在线电影中文字幕 | 亚洲欧洲视频 | 丁香六月伊人 | 国产一区二区不卡在线 | 日韩欧美成人网 | 在线91观看 | 国产毛片久久 | 天天激情天天干 | 亚洲免费av网站 | 九九久久精品 | 国产 中文 日韩 欧美 | 国产网红在线观看 | 日本视频精品 | 在线免费观看黄色av | 国产一区二区三区在线免费观看 | 天天综合网~永久入口 | 国产系列 在线观看 | 亚欧日韩成人h片 | 精品国产一区二区三区久久久蜜臀 | 9999激情 | a爱爱视频 | 日韩免费在线视频 | 天堂中文在线播放 | 在线 你懂 | 狠狠躁夜夜躁人人爽超碰91 | av女优中文字幕在线观看 | 久久久国产高清 | 99热播精品| 在线观看福利网站 | 99re国产 | 狠狠操夜夜 | 97超视频免费观看 | 日日久视频| 97成人在线观看视频 | 免费一级特黄录像 | 欧美精品中文字幕亚洲专区 | 97色婷婷成人综合在线观看 | 亚洲黄色一级大片 | 婷婷激情在线观看 | 免费能看的黄色片 | av电影在线观看完整版一区二区 | 久久精品视频18 | 91av视频在线观看 | 色婷婷激情电影 | 免费人人干 | 国产视频一区在线播放 | 日韩久久一区二区 | 四虎伊人| 国产精品美女久久 | 久久99亚洲网美利坚合众国 | 欧美成人理伦片 | 中文字幕电影一区 | 色午夜影院 | 天天玩天天干天天操 | 96av在线视频| 黄色亚洲片 | 日韩中文字幕免费视频 | 极品美女被弄高潮视频网站 | 国产a级免费 | 欧美另类一二三四区 | 天天干天天摸天天操 | 天天搞天天 | 国产成人三级 | 九九视频在线观看视频6 | 91av99| 色99网| 久久女同性恋中文字幕 | 狠狠狠狠狠狠狠 | 亚洲日本va中文字幕 | 亚洲 欧洲 国产 日本 综合 | 一区二区三区精品在线视频 | 天天摸天天操天天爽 | 一区二区三区在线看 | 欧美另类xxx| 综合网中文字幕 | 久久久久久久久久久黄色 | 日韩在线网址 | 五月婷婷在线观看视频 | 99精品欧美一区二区三区黑人哦 | 亚洲国产高清在线观看视频 | 国产成人777777 | 天天色天天射天天综合网 | 久久手机视频 | 日韩在线欧美在线 | 久久久免费看片 | 91精品在线播放 | 亚洲三级在线播放 | 久久久国产一区二区三区四区小说 | 777久久久 | 成人在线视频观看 | 亚洲精品美女久久17c | 99精品网站| 久久区二区 | 国产精品综合在线 | 日韩动态视频 | 国产裸体无遮挡 | 啪啪免费观看网站 | 欧美一级黄色片 | 国产午夜精品一区二区三区 | 色综合天天狠天天透天天伊人 | 亚洲精品在线国产 | 91久久爱热色涩涩 | 97爱爱爱 | 久久久久一区二区三区四区 | 久久99九九99精品 | 97在线看 | 一区二区三区高清在线观看 | 香蕉视频在线免费 | 国产手机视频在线观看 | 免费视频一级片 | 日韩精品免费在线观看 | 久久成人国产精品一区二区 | 欧美亚洲另类在线视频 | 亚洲一区二区视频在线播放 | 一级黄色片在线免费看 | 99人久久精品视频最新地址 | 亚洲精品国产精品乱码在线观看 |