亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍

記一次tcmalloc分配內存引起的coredump
來源:易賢網 閱讀:2736 次 日期:2015-04-09 15:03:00
溫馨提示:易賢網小編為您整理了“記一次tcmalloc分配內存引起的coredump”,方便廣大網友查閱!

現象

線上的服務出現coredump,堆棧為:

#0 0x000000000045d145 in GetStackTrace(void**, int, int) ()

#1 0x000000000045ec22 in tcmalloc::PageHeap::GrowHeap(unsigned long) ()

#2 0x000000000045eeb3 in tcmalloc::PageHeap::New(unsigned long) ()

#3 0x0000000000459ee8 in tcmalloc::CentralFreeList::Populate() ()

#4 0x000000000045a088 in tcmalloc::CentralFreeList::FetchFromSpansSafe() ()

#5 0x000000000045a10a in tcmalloc::CentralFreeList::RemoveRange(void**, void**, int) ()

#6 0x000000000045c282 in tcmalloc::ThreadCache::FetchFromCentralCache(unsigned long, unsigned long) ()

#7 0x0000000000470766 in tc_malloc ()

#8 0x00007f75532cd4c2 in __conhash_get_rbnode (node=0x22c86870, hash=30)

at build/release64/cm_sub/conhash/conhash_inter.c:88

#9 0x00007f75532cd76e in __conhash_add_replicas (conhash=0x24fbc7e0, iden=<value optimized out>)

at build/release64/cm_sub/conhash/conhash_inter.c:45

#10 0x00007f75532cd1fa in conhash_add_node (conhash=0x24fbc7e0, iden=0) at build/release64/cm_sub/conhash/conhash.c:72

#11 0x00007f75532c651b in cm_sub::TopoCluster::initLBPolicyInfo (this=0x2593a400)

at build/release64/cm_sub/topo_cluster.cpp:114

#12 0x00007f75532cad73 in cm_sub::TopoClusterManager::processClusterMapTable (this=0xa219e0, ref=0x267ea8c0)

at build/release64/cm_sub/topo_cluster_manager.cpp:396

#13 0x00007f75532c5a93 in cm_sub::SubRespMsgProcess::reinitCluster (this=0x9c2f00, msg=0x4e738ed0)

at build/release64/cm_sub/sub_resp_msg_process.cpp:157

...

查看了應用層相關數據結構,基本數據都是沒有問題的。所以最初懷疑是tcmalloc內部維護了錯誤的內存,在分配內存時出錯,這個堆棧只是問題的表象。幾天后,線上的另一個服務,基于同樣的庫,也core了,堆棧還是一樣的。

最初定位問題都是從最近更新的東西入手,包括依賴的server環境,但都沒有明顯的問題,所以最后只能從core的直接原因入手。

分析GetStackTrace

確認core的詳細位置:

# core在該指令

0x000000000045d145 <_Z13GetStackTracePPvii+21>: mov 0x8(%rax),%r9

(gdb) p/x $rip # core 的指令位置

$9 = 0x45d145

(gdb) p/x $rax

$10 = 0x4e73aa58

(gdb) x/1a $rax+0x8 # rax + 8 = 0x4e73aa60

0x4e73aa60: 0x0

該指令嘗試從[0x4e73aa60]處讀取內容,然后出錯,這個內存單元不可讀。但是具體這個指令在代碼中是什么意思,需要將這個指令對應到代碼中。獲取tcmalloc的源碼,發現GetStackTrace根據編譯選項有很多實現,所以這里選擇最可能的實現,然后對比匯編以確認代碼是否匹配。最初選擇的是stacktrace_x86-64-inl.h,后來發現完全不匹配,又選擇了stacktrace_x86-inl.h。這個實現版本里也有對64位平臺的支持。

stacktrace_x86-inl.h里使用了一些宏來生成函數名和參數,精簡后代碼大概為:

int GET_STACK_TRACE_OR_FRAMES {

void **sp;

unsigned long rbp;

__asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));

sp = (void **) rbp;

int n = 0;

while (sp && n < max_depth) {

if (*(sp+1) == reinterpret_cast<void *>(0)) {

break;

}

void **next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp);

if (skip_count > 0) {

skip_count--;

} else {

result[n] = *(sp+1);

n++;

}

sp = next_sp;

}

return n;

}

NextStackFrame是一個模板函數,包含一大堆代碼,精簡后非常簡單:

template<bool STRICT_UNWINDING, bool WITH_CONTEXT>

static void **NextStackFrame(void **old_sp, const void *uc) {

void **new_sp = (void **) *old_sp;

if (STRICT_UNWINDING) {

if (new_sp <= old_sp) return NULL;

if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;

} else {

if (new_sp == old_sp) return NULL;

if ((new_sp > old_sp)

&& ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;

}

if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;

return new_sp;

}

上面這個代碼到匯編的對比過程還是花了些時間,其中匯編中出現的一些常量可以大大縮短對比時間,例如上面出現了100000,匯編中就有:

0x000000000045d176 <_Z13GetStackTracePPvii+70>: cmp $0x186a0,%rbx # 100000=0x186a0

注意NextStackFrame中的 if (STRICT_UNWINDING)使用的是模板參數,這導致生成的代碼中根本沒有else部分,也就沒有1000000這個常量

在對比代碼的過程中,可以知道關鍵的幾個寄存器、內存位置對應到代碼中的變量,從而可以還原core時的現場環境。分析過程中不一定要從第一行匯編讀,可以從較明顯的位置讀,從而還原整個代碼,函數返回指令、跳轉指令、比較指令、讀內存指令、參數寄存器等都是比較明顯對應的地方。

另外注意GetStackTrace在RecordGrowth中調用,傳入了3個參數:

GetStackTrace(t->stack, kMaxStackDepth-1, 3); // kMaxStackDepth = 31

以下是我分析的簡單注解:

(gdb) disassemble

Dump of assembler code for function _Z13GetStackTracePPvii:

0x000000000045d130 <_Z13GetStackTracePPvii+0>: push %rbp

0x000000000045d131 <_Z13GetStackTracePPvii+1>: mov %rsp,%rbp

0x000000000045d134 <_Z13GetStackTracePPvii+4>: push %rbx

0x000000000045d135 <_Z13GetStackTracePPvii+5>: mov %rbp,%rax

0x000000000045d138 <_Z13GetStackTracePPvii+8>: xor %r8d,%r8d

0x000000000045d13b <_Z13GetStackTracePPvii+11>: test %rax,%rax

0x000000000045d13e <_Z13GetStackTracePPvii+14>: je 0x45d167 <_Z13GetStackTracePPvii+55>

0x000000000045d140 <_Z13GetStackTracePPvii+16>: cmp %esi,%r8d # while ( .. max_depth > n ?

0x000000000045d143 <_Z13GetStackTracePPvii+19>: jge 0x45d167 <_Z13GetStackTracePPvii+55>

0x000000000045d145 <_Z13GetStackTracePPvii+21>: mov 0x8(%rax),%r9 # 關鍵位置:*(sp+1) -> r9, rax 對應 sp變量

0x000000000045d149 <_Z13GetStackTracePPvii+25>: test %r9,%r9 # *(sp+1) == 0 ?

0x000000000045d14c <_Z13GetStackTracePPvii+28>: je 0x45d167 <_Z13GetStackTracePPvii+55>

0x000000000045d14e <_Z13GetStackTracePPvii+30>: mov (%rax),%rcx # new_sp = *old_sp,這里已經是NextStackFrame的代碼

0x000000000045d151 <_Z13GetStackTracePPvii+33>: cmp %rcx,%rax # new_sp <= old_sp ?

0x000000000045d154 <_Z13GetStackTracePPvii+36>: jb 0x45d170 <_Z13GetStackTracePPvii+64> # new_sp > old_sp 跳轉

0x000000000045d156 <_Z13GetStackTracePPvii+38>: xor %ecx,%ecx

0x000000000045d158 <_Z13GetStackTracePPvii+40>: test %edx,%edx # skip_count > 0 ?

0x000000000045d15a <_Z13GetStackTracePPvii+42>: jle 0x45d186 <_Z13GetStackTracePPvii+86>

0x000000000045d15c <_Z13GetStackTracePPvii+44>: sub $0x1,%edx # skip_count--

0x000000000045d15f <_Z13GetStackTracePPvii+47>: mov %rcx,%rax

0x000000000045d162 <_Z13GetStackTracePPvii+50>: test %rax,%rax # while (sp ?

0x000000000045d165 <_Z13GetStackTracePPvii+53>: jne 0x45d140 <_Z13GetStackTracePPvii+16>

0x000000000045d167 <_Z13GetStackTracePPvii+55>: pop %rbx

0x000000000045d168 <_Z13GetStackTracePPvii+56>: leaveq

0x000000000045d169 <_Z13GetStackTracePPvii+57>: mov %r8d,%eax # r8 存儲了返回值,r8=n

0x000000000045d16c <_Z13GetStackTracePPvii+60>: retq # return n

0x000000000045d16d <_Z13GetStackTracePPvii+61>: nopl (%rax)

0x000000000045d170 <_Z13GetStackTracePPvii+64>: mov %rcx,%rbx

0x000000000045d173 <_Z13GetStackTracePPvii+67>: sub %rax,%rbx # offset = new_sp - old_sp

0x000000000045d176 <_Z13GetStackTracePPvii+70>: cmp $0x186a0,%rbx # offset > 100000 ?

0x000000000045d17d <_Z13GetStackTracePPvii+77>: ja 0x45d156 <_Z13GetStackTracePPvii+38> # return NULL

0x000000000045d17f <_Z13GetStackTracePPvii+79>: test $0x7,%cl # new_sp & (sizeof(void*) - 1)

0x000000000045d182 <_Z13GetStackTracePPvii+82>: je 0x45d158 <_Z13GetStackTracePPvii+40>

0x000000000045d184 <_Z13GetStackTracePPvii+84>: jmp 0x45d156 <_Z13GetStackTracePPvii+38>

0x000000000045d186 <_Z13GetStackTracePPvii+86>: movslq %r8d,%rax # rax = n

0x000000000045d189 <_Z13GetStackTracePPvii+89>: add $0x1,%r8d # n++

0x000000000045d18d <_Z13GetStackTracePPvii+93>: mov %r9,(%rdi,%rax,8)# 關鍵位置:result[n] = *(sp+1)

0x000000000045d191 <_Z13GetStackTracePPvii+97>: jmp 0x45d15f <_Z13GetStackTracePPvii+47>

分析過程比較耗時,同時還可以分析下GetStackTrace函數的實現原理,其實就是利用RBP寄存器不斷回溯,從而得到整個調用堆棧各個函數的地址(嚴格來說是返回地址)。簡單示意下函數調用中RBP的情況:

...

saved registers # i.e push rbx

local variabes # i.e sub 0x10, rsp

return address # call xxx

last func RBP # push rbp; mov rsp, rbp

saved registers

local variables

return address

last func RBP

... # rsp

總之,一般情況下,任何一個函數中,RBP寄存器指向了當前函數的棧基址,該棧基址中又存儲了調用者的棧基址,同時該棧基址前面還存儲了調用者的返回地址。所以,GetStackTrace的實現,簡單來說大概就是:

sp = rbp // 取得當前函數GetStackTrace的棧基址

while (n < max_depth) {

new_sp = *sp

result[n] = *(new_sp+1)

n++

}

以上,最終就知道了以下關鍵信息:

r8 對應變量 n,表示當前取到第幾個棧幀了

rax 對應變量 sp,代碼core在 *(sp+1)

rdi 對應變量 result,用于存儲取得的各個地址

然后可以看看現場是怎樣的:

(gdb) x/10a $rdi

0x1ffc9b98: 0x45a088 <_ZN8tcmalloc15CentralFreeList18FetchFromSpansSafeEv+40> 0x45a10a <_ZN8tcmalloc15CentralFreeList11RemoveRangeEPPvS2_i+106>

0x1ffc9ba8: 0x45c282 <_ZN8tcmalloc11ThreadCache21FetchFromCentralCacheEmm+114> 0x470766 <tc_malloc+790>

0x1ffc9bb8: 0x7f75532cd4c2 <__conhash_get_rbnode+34> 0x0

0x1ffc9bc8: 0x0 0x0

0x1ffc9bd8: 0x0 0x0

(gdb) p/x $r8

$3 = 0x5

(gdb) p/x $rax

$4 = 0x4e73aa58

小結:

GetStackTrace在取調用__conhash_get_rbnode的函數時出錯,取得了5個函數地址。當前使用的RBP為0x4e73aa58。

錯誤的RBP

RBP也是從堆棧中取出來的,既然這個地址有問題,首先想到的就是有代碼局部變量/數組寫越界。例如sprintf的使用。而且,一般寫越界破壞堆棧,都可能是把調用者的堆棧破壞了,例如:

char s[32];

memcpy(s, p, 1024);

因為寫入都是從低地址往高地址寫,而調用者的堆棧在高地址。當然,也會遇到寫壞調用者的調用者的堆棧,也就是跨棧幀越界寫,例如以前遇到的:

len = vsnprintf(buf, sizeof(buf), fmt, wtf-long-string);

buf[len] = 0;

__conhash_get_rbnode的RBP是在tcmalloc的堆棧中取的:

(gdb) f 7

#7 0x0000000000470766 in tc_malloc ()

(gdb) x/10a $rsp

0x4e738b80: 0x4e73aa58 0x22c86870

0x4e738b90: 0x4e738bd0 0x85

0x4e738ba0: 0x4e73aa58 0x7f75532cd4c2 <__conhash_get_rbnode+34> # 0x4e73aa58

所以這里就會懷疑是tcmalloc這個函數里有把堆棧破壞,這個時候就是讀代碼,看看有沒有疑似危險的地方,未果。這里就陷入了僵局,懷疑又遇到了跨棧幀破壞的情況,這個時候就只能__conhash_get_rbnode調用棧中周圍的函數翻翻,例如調用__conhash_get_rbnode的函數__conhash_add_replicas中恰好有字符串操作:

void __conhash_add_replicas(conhash_t *conhash, int32_t iden)

{

node_t* node = __conhash_create_node(iden, conhash->replica);

...

char buf[buf_len]; // buf_len = 64

...

snprintf(buf, buf_len, VIRT_NODE_HASH_FMT, node->iden, i);

uint32_t hash = conhash->cb_hashfunc(buf);

if(util_rbtree_search(&(conhash->vnode_tree), hash) == NULL)

{

util_rbtree_node_t* rbnode = __conhash_get_rbnode(node, hash);

...

這段代碼最終發現是沒有問題的,這里又耗費了不少時間。后來發現若干個函數里的RBP都有點奇怪,這個調用棧比較正常的范圍是:0x4e738c90

(gdb) f 8

#8 0x00007f75532cd4c2 in __conhash_get_rbnode (node=0x22c86870, hash=30)

(gdb) p/x $rbp

$6 = 0x4e73aa58 # 這個還不算特別可疑

(gdb) f 9

#9 0x00007f75532cd76e in __conhash_add_replicas (conhash=0x24fbc7e0, iden=<value optimized out>)

(gdb) p/x $rbp

$7 = 0x4e738c60 # 這個也不算特別可疑

(gdb) f 10

#10 0x00007f75532cd1fa in conhash_add_node (conhash=0x24fbc7e0, iden=0) at build/release64/cm_sub/conhash/conhash.c:72

(gdb) p/x $rbp # 可疑

$8 = 0x0

(gdb) f 11

#11 0x00007f75532c651b in cm_sub::TopoCluster::initLBPolicyInfo (this=0x2593a400)

(gdb) p/x $rbp # 可疑

$9 = 0x2598fef0

為什么很多函數中RBP都看起來不正常? 想了想真要是代碼里把堆棧破壞了,這錯誤得發生得多巧妙?

錯誤RBP的來源

然后轉機來了,腦海中突然閃出-fomit-frame-pointer。編譯器生成的代碼中是可以不需要棧基址指針的,也就是RBP寄存器不作為棧基址寄存器。大部分函數或者說開啟了frame-pointer的函數,其函數頭都會有以下指令:

push %rbp

mov %rsp,%rbp

...

表示保存調用者的棧基址到棧中,以及設置自己的棧基址。看下__conhash系列函數;

Dump of assembler code for function __conhash_get_rbnode:

0x00007f75532cd4a0 <__conhash_get_rbnode+0>: mov %rbx,-0x18(%rsp)

0x00007f75532cd4a5 <__conhash_get_rbnode+5>: mov %rbp,-0x10(%rsp)

...

這個庫是單獨編譯的,沒有顯示指定-fno-omit-frame-pointer,查閱gcc手冊,o2優化是開啟了omit-frame-pinter 的。

在沒有RBP的情況下,tcmalloc的GetStackTrace嘗試讀RBP取獲取調用返回地址,自然是有問題的。但是,如果整個調用棧中的函數,要么有RBP,要么沒有RBP,那么GetStackTrace取出的結果最多就是跳過一些棧幀,不會出錯。 除非,這中間的某個函數把RBP寄存器另作他用(編譯器省出這個寄存器肯定是要另作他用的)。所以這里繼續追查這個錯誤地址0x4e73aa58的來源。

來源已經比較明顯,肯定是__conhash_get_rbnode中設置的,因為這個函數的RBP是在被調用者tcmalloc中保存的。

Dump of assembler code for function __conhash_get_rbnode:

0x00007f75532cd4a0 <__conhash_get_rbnode+0>: mov %rbx,-0x18(%rsp)

0x00007f75532cd4a5 <__conhash_get_rbnode+5>: mov %rbp,-0x10(%rsp)

0x00007f75532cd4aa <__conhash_get_rbnode+10>: mov %esi,%ebp # 改寫了RBP

0x00007f75532cd4ac <__conhash_get_rbnode+12>: mov %r12,-0x8(%rsp)

0x00007f75532cd4b1 <__conhash_get_rbnode+17>: sub $0x18,%rsp

0x00007f75532cd4b5 <__conhash_get_rbnode+21>: mov %rdi,%r12

0x00007f75532cd4b8 <__conhash_get_rbnode+24>: mov $0x30,%edi

0x00007f75532cd4bd <__conhash_get_rbnode+29>: callq 0x7f75532b98c8 <> # 調用tcmalloc,匯編到這里即可

這里打印RSI寄存器的值可能會被誤導,因為任何時候打印寄存器的值可能都是錯的,除非它有被顯示保存。不過這里可以看出RSI的值來源于參數(RSI對應第二個參數):

void __conhash_add_replicas(conhash_t *conhash, int32_t iden)

{

node_t* node = __conhash_create_node(iden, conhash->replica);

...

char buf[buf_len]; // buf_len = 64

...

snprintf(buf, buf_len, VIRT_NODE_HASH_FMT, node->iden, i);

uint32_t hash = conhash->cb_hashfunc(buf); // hash值由一個字符串哈希函數計算

if(util_rbtree_search(&(conhash->vnode_tree), hash) == NULL)

{

util_rbtree_node_t* rbnode = __conhash_get_rbnode(node, hash); // hash值

...

追到__conhash_add_replicas:

0x00007f75532cd764 <__conhash_add_replicas+164>: mov %ebx,%esi # 來源于rbx

0x00007f75532cd766 <__conhash_add_replicas+166>: mov %r15,%rdi

0x00007f75532cd769 <__conhash_add_replicas+169>: callq 0x7f75532b9e48 <>

(gdb) p/x $rbx

$11 = 0x4e73aa58

(gdb) p/x hash

$12 = 0x4e73aa58 # 0x4e73aa58

找到了0x4e73aa58的來源。這個地址值竟然是一個字符串哈希算法算出來的!這里還可以看看這個字符串的內容:

(gdb) x/1s $rsp

0x4e738bd0: "conhash-00000-00133"

這個碉堡的哈希函數是conhash_hash_def。

coredump的條件

以上,既然只要某個庫omit-frame-pointer,那tcmalloc就可能出錯,為什么發生的頻率并不高呢?這個可以回到GetStackTrace尤其是NextStackFrame的實現,其中包含了幾個合法RBP的判定:

if (new_sp <= old_sp) return NULL; // 上一個棧幀的RBP肯定比當前的大

if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; // 指針值范圍還必須在100000內

...

if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; // 由于本身保存的是指針,所以還必須是sizeof(void*)的整數倍,對齊

有了以上條件,才使得這個core幾率變得很低。

總結

最后,如果你很熟悉tcmalloc,整個問題估計就被秒解了:tcmalloc INSTALL

另外附上另一個有意思的東西。

在分析__conhash_add_replicas時,其內定義了一個64字節的字符數組,查看其堆棧:

(gdb) x/20a $rsp

0x4e738bd0: 0x2d687361686e6f63 0x30302d3030303030 # 這些是字符串conhash-00000-00133

0x4e738be0: 0x333331 0x0

0x4e738bf0: 0x0 0x7f75532cd69e <__conhash_create_node+78>

0x4e738c00: 0x24fbc7e0 0x4e738c60

0x4e738c10: 0x24fbc7e0 0x7f75532cd6e3 <__conhash_add_replicas+35>

0x4e738c20: 0x0 0x24fbc7e8

0x4e738c30: 0x4e738c20 0x24fbc7e0

0x4e738c40: 0x22324360 0x246632c0

0x4e738c50: 0x0 0x0

0x4e738c60: 0x0 0x7f75532cd1fa <conhash_add_node+74>

最開始我覺得buf占64字節,也就是整個[0x4e738bd0, 0x4e738c10)內存,但是這塊內存里居然有函數地址,這一度使我懷疑這里有問題。后來醒悟這些地址是定義buf前調用__conhash_create_node產生的,調用過程中寫到堆棧里,調用完后棧指針改變,但并不需要清空棧中的內容。

更多信息請查看IT技術專欄

更多信息請查看技術文章
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點

版權所有:易賢網

亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍
国产精品99免费看| 午夜影院日韩| 国产亚洲第一区| 国产欧美日韩综合一区在线观看| 亚洲伦伦在线| 欧美精品一区三区在线观看| 亚洲高清视频一区二区| 国产精品美女黄网| 欧美日韩一区自拍| 亚洲深夜福利| 午夜欧美精品| 国产欧美一区二区三区另类精品 | 久久综合五月| 一区在线免费观看| 性一交一乱一区二区洋洋av| 国精品一区二区三区| 国产精品视区| 亚洲二区视频| 欧美欧美全黄| 免费看黄裸体一级大秀欧美| 亚洲黄色成人久久久| 欧美精品福利| 先锋影音久久久| 亚洲美女色禁图| 欧美性天天影院| 乱人伦精品视频在线观看| 亚洲电影在线| 国产精品99一区二区| 男人的天堂亚洲| 国产精品午夜av在线| 亚洲视频狠狠| 激情久久一区| 亚洲一级影院| 亚洲午夜精品久久| 好看的亚洲午夜视频在线| 欧美国产高潮xxxx1819| 久久久久九九九| 久久久蜜桃一区二区人| 美女精品国产| 久久久久高清| 欧美区亚洲区| 欧美精品一卡| 国产综合18久久久久久| 欧美精品一区三区在线观看| 欧美成人嫩草网站| 久久亚洲国产精品日日av夜夜| 亚洲综合欧美日韩| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲欧美高清| 久久婷婷亚洲| 国产精品v日韩精品v欧美精品网站 | 亚洲精品一级| 亚洲国产精品一区二区第四页av| 国产综合精品一区| 国产综合第一页| 狠久久av成人天堂| 亚洲欧洲精品一区二区三区波多野1战4| 合欧美一区二区三区| 亚洲香蕉网站| 99国产精品久久久久久久 | 久久在线精品| 韩国av一区| 亚洲激情网址| 午夜在线精品| 欧美激情aⅴ一区二区三区| 欧美日韩精品免费看| 一区久久精品| 亚洲在线不卡| 欧美在线网站| 激情综合久久| 国产精品色网| 欧美日韩综合| 国产精品免费一区二区三区在线观看 | 性刺激综合网| 狠狠色噜噜狠狠色综合久 | 在线看片成人| 亚洲免费网址| 伊人激情综合| 欧美国产高潮xxxx1819| 亚洲电影成人| 欧美成人亚洲| 国产精品一区免费观看| 国产一区二区无遮挡| 亚洲一区二区三区午夜| 欧美午夜不卡| 免费久久久一本精品久久区| 狠狠久久婷婷| 欧美在线亚洲综合一区| 国产日韩欧美一区二区| 精品成人免费| 欧美人与禽猛交乱配视频| 国产精品亚洲综合久久| 在线播放一区| 国产精品v欧美精品v日本精品动漫| 亚洲一区二区三区午夜| 亚洲少妇在线| 一本色道久久综合亚洲精品不| 欧美日韩另类综合| 欧美阿v一级看视频| 美女久久一区| 午夜一区二区三视频在线观看| 99香蕉国产精品偷在线观看 | 亚洲少妇一区| 亚洲巨乳在线| 91久久极品少妇xxxxⅹ软件| 国产精品v欧美精品v日本精品动漫 | 国产日韩精品一区观看 | 伊人蜜桃色噜噜激情综合| 久久一区中文字幕| 欧美在线综合| 老司机精品久久| 欧美在线亚洲综合一区| 蜜桃久久精品乱码一区二区| 99伊人成综合| 亚洲无毛电影| 欧美日韩亚洲一区二区三区在线 | 亚洲国产精品123| 国产美女诱惑一区二区| 激情久久久久久| 欧美激情第六页| 亚洲综合国产| 中日韩视频在线观看| 亚洲激情偷拍| 亚洲欧美综合国产精品一区| 韩日成人av| 欧美亚洲免费高清在线观看| 国产主播一区| 欧美.www| 久久婷婷激情| 美女视频一区免费观看| 国产亚洲激情| 亚洲精品乱码久久久久久蜜桃麻豆 | 久久国产精品毛片| 亚洲精品乱码视频| 99在线精品免费视频九九视| 亚洲尤物在线| 亚洲精选国产| 欧美日韩天堂| 91久久国产综合久久蜜月精品| 亚洲综合好骚| 99精品久久久| 黄色av成人| 欧美色图麻豆| 国产欧美精品| 亚洲经典在线| 亚洲黄色av| 激情自拍一区| 极品日韩久久| 黄色成人在线网站| 亚洲一级黄色| 亚洲精品一区二区三区樱花 | 一本一本a久久| 久久久水蜜桃av免费网站| 国产精品黄色| 亚洲特级毛片| 一区二区三区精品视频在线观看| 亚洲国产一区二区三区高清| 日韩亚洲精品在线| 中国女人久久久| 性欧美暴力猛交另类hd| 国产精品久久久一区二区三区| 欧美日本亚洲| 最近看过的日韩成人| 一区二区三区欧美成人| 亚洲欧美日韩在线观看a三区| 久久久99国产精品免费| 国产主播一区二区三区四区| 在线欧美福利| 一区二区精品国产| 一区二区自拍| 亚洲在线黄色| 欧美日韩一区二区国产| 一本不卡影院| 老司机午夜精品视频| 精品成人一区| 久久亚洲一区二区| 国产嫩草一区二区三区在线观看 | 国产欧美日韩亚洲| 美女国产精品| 红桃视频国产一区| 亚洲一区二区三区精品动漫| 午夜日本精品| 国产精品一区二区a| 欧美特黄视频| 免费亚洲婷婷| 亚洲激情一区二区三区| 久久综合影视| 亚洲一区成人| 午夜精品网站| 国产精品www.| 久久av最新网址| 亚洲国产免费| 国产一区二区三区四区三区四| 国产精品毛片| 亚洲看片免费| 欧美精品自拍| 亚洲无玛一区| 午夜激情一区| 久久精品国产清高在天天线| 99成人免费视频| 亚洲网站啪啪| 欧美日韩亚洲一区| 欧美高清视频一区| 欧美特黄a级高清免费大片a级| 亚洲欧美日韩精品综合在线观看| 亚洲国产精品123| 国产中文一区二区| 国产在线成人| 黄色av日韩| 午夜一区二区三区不卡视频| 亚洲欧美一级二级三级| 老妇喷水一区二区三区| 另类av一区二区| 久久国产精品久久精品国产 | 99视频+国产日韩欧美| 国产欧美日韩综合一区在线观看| 在线免费观看欧美| 影音先锋中文字幕一区| 欧美性色综合| 黄色av日韩| 亚洲精品精选| 欧美一区2区三区4区公司二百| 麻豆精品传媒视频| 久久裸体视频| 亚洲欧美在线网| 欧美区日韩区| 欧美日韩一视频区二区| 欧美激情1区2区3区| 一本综合精品| 欧美一级专区| 欧美一区2区三区4区公司二百| 欧美精品18| 亚洲视频观看| 亚洲精品在线二区| 欧美日韩一区在线播放| 欧美激情一区| 狠狠色丁香久久综合频道| 亚洲黄色免费| 母乳一区在线观看| 欧美在线免费| 亚洲国产精品第一区二区三区 | 伊甸园精品99久久久久久| 亚洲精品九九| 久久久久网站| 国产女主播一区二区三区| 久久婷婷激情| 伊人久久av导航| 亚洲一区激情| 国产精品第十页| 一区二区亚洲精品| 欧美色123| 日韩网站在线| 久久综合九色综合久99| 在线观看视频日韩| 久久久久天天天天| 美日韩精品免费| 亚洲一区3d动漫同人无遮挡| 午夜视频一区| 亚洲一区二区三区涩| 欧美日韩精品综合| 国产日韩欧美一区| 国产自产在线视频一区| 黑丝一区二区| 久久精品123| 激情一区二区| 欧美96在线丨欧| 午夜亚洲一区| 一区二区三区四区五区精品| 欧美精品v日韩精品v国产精品| 99re6热在线精品视频播放速度 | 欧美精品aa| 日韩午夜免费| 午夜日本精品| 久久福利电影| 国产精品久久亚洲7777| 国产精品综合色区在线观看| 黑人中文字幕一区二区三区| 久久精品日韩| 性8sex亚洲区入口| 亚洲一区影院| 久久综合图片| 男女精品视频| 午夜综合激情| 午夜亚洲伦理| 国产欧美日本| 国产精品试看| 国产区欧美区日韩区| 亚洲精品在线视频观看| 欧美日韩一区在线视频| 欧美一区不卡| 中文一区二区| 欧美 日韩 国产精品免费观看| 亚洲一区日韩在线| 亚洲欧美国产不卡| 亚洲欧美日韩精品久久久| 亚洲欧美bt| 黄色国产精品| 亚洲黄色三级| 国产亚洲第一区| 校园激情久久| 午夜激情一区| 国产精品免费看| 免费在线日韩av| 老牛嫩草一区二区三区日本| 久久婷婷激情| 欧美日本中文| 亚洲在线电影| 老司机免费视频久久| 欧美日一区二区在线观看 | 在线观看成人av| 美女黄色成人网| 欧美激情1区| 伊人影院久久| 一区二区精品在线| 蜜桃av综合| 一级成人国产| 欧美xxx在线观看| 亚洲人成人一区二区三区| 一区二区三区精品国产| 午夜一级久久| 国产伦精品一区二区| 欧美va亚洲va日韩∨a综合色| 亚洲视频日本| 欧美精品一区二区三区在线看午夜 | 在线视频国内自拍亚洲视频| 日韩一级欧洲| 久久久久综合| 亚洲国产成人不卡| 狠狠色综合网| 美日韩精品免费| 黄色日韩精品| 美日韩精品视频| 亚洲精品美女91| 亚洲高清免费| 久久综合狠狠综合久久综青草| 激情一区二区| 狂野欧美一区| 亚洲一区二区三区精品动漫| 亚洲一卡久久| 在线日韩电影| 欧美一区久久| 亚洲影院免费| 欧美久久久久久| 午夜精品视频在线观看一区二区| 精品91在线| 欧美黄色大片网站| 亚洲欧美日韩精品在线| 亚洲高清精品中出| 99热这里只有成人精品国产| 欧美日韩国产精品一卡| 久久成人亚洲| 国产一区二区三区成人欧美日韩在线观看| 美女精品在线| 欧美日本一区| 久久久久久国产精品mv| 国产日韩欧美一区在线 | 免费日韩一区二区| 99re热精品| 亚洲国产精品久久久久久女王| 欧美黄色免费| 欧美jizzhd精品欧美巨大免费| 午夜宅男久久久| 亚洲一区二区三区精品视频| 国产欧美日韩综合一区在线播放| 国产精品普通话对白| 一本色道久久综合亚洲精品婷婷| 在线观看一区| 亚洲高清视频一区| 亚洲成人资源| 麻豆av一区二区三区久久| 国产精品久久波多野结衣| 国产日韩欧美在线播放不卡| 一区二区黄色| 亚洲一区在线免费| 狠狠爱www人成狠狠爱综合网| 欧美日韩一区二区国产| 国产字幕视频一区二区| 一区久久精品| 久久福利影视| 欧美国产日本| 影音先锋久久久| 日韩视频一区| 99在线精品视频在线观看| 可以看av的网站久久看| 午夜日韩在线| 亚洲第一网站| 国产伦精品一区二区三区| 国产一区激情| 校园春色综合网| 久久免费黄色| 欧美精品尤物在线| 亚洲大胆视频| 欧美粗暴jizz性欧美20| 黄页网站一区| 一本一道久久综合狠狠老精东影业 | 久久久亚洲一区| 欧美日本一区| 亚洲国产黄色| 国产欧美一级| 久久精品盗摄|