精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

開發一個Linux調試器(七):源碼級斷點

系統 Linux
這篇文章將會添加源碼級斷點到我們的調試器中。通過所有我們已經支持的功能,這要比起最初聽起來容易得多。我們還將添加一個命令來獲取符號的類型和地址,這對于定位代碼或數據以及理解鏈接概念非常有用。

[[204745]]

在內存地址上設置斷點雖然不錯,但它并沒有提供最方便用戶的工具。我們希望能夠在源代碼行和函數入口地址上設置斷點,以便我們可以在與代碼相同的抽象級別中進行調試。

這篇文章將會添加源碼級斷點到我們的調試器中。通過所有我們已經支持的功能,這要比起最初聽起來容易得多。我們還將添加一個命令來獲取符號的類型和地址,這對于定位代碼或數據以及理解鏈接概念非常有用。

系列索引

隨著后面文章的發布,這些鏈接會逐漸生效。

  1. 準備環境
  2. 斷點
  3. 寄存器和內存
  4. Elves 和 dwarves
  5. 源碼和信號
  6. 源碼級逐步執行
  7. 源碼級斷點
  8. 調用棧
  9. 讀取變量
  10. 之后步驟

斷點

DWARF

Elves 和 dwarves 這篇文章,描述了 DWARF 調試信息是如何工作的,以及如何用它來將機器碼映射到高層源碼中。回想一下,DWARF 包含了函數的地址范圍和一個允許你在抽象層之間轉換代碼位置的行表。我們將使用這些功能來實現我們的斷點。

函數入口

如果你考慮重載、成員函數等等,那么在函數名上設置斷點可能有點復雜,但是我們將遍歷所有的編譯單元,并搜索與我們正在尋找的名稱匹配的函數。DWARF 信息如下所示:

  1. < 0><0x0000000b>  DW_TAG_compile_unit 
  2.                     DW_AT_producer              clang version 3.9.1 (tags/RELEASE_391/final) 
  3.                     DW_AT_language              DW_LANG_C_plus_plus 
  4.                     DW_AT_name                  /super/secret/path/MiniDbg/examples/variable.cpp 
  5.                     DW_AT_stmt_list             0x00000000 
  6.                     DW_AT_comp_dir              /super/secret/path/MiniDbg/build 
  7.                     DW_AT_low_pc                0x00400670 
  8.                     DW_AT_high_pc               0x0040069c 
  9. LOCAL_SYMBOLS: 
  10. < 1><0x0000002e>    DW_TAG_subprogram 
  11.                       DW_AT_low_pc                0x00400670 
  12.                       DW_AT_high_pc               0x0040069c 
  13.                       DW_AT_name                  foo 
  14.                       ... 
  15. ... 
  16. <14><0x000000b0>    DW_TAG_subprogram 
  17.                       DW_AT_low_pc                0x00400700 
  18.                       DW_AT_high_pc               0x004007a0 
  19.                       DW_AT_name                  bar 
  20.                       ... 

我們想要匹配 DW_AT_name 并使用 DW_AT_low_pc(函數的起始地址)來設置我們的斷點。

  1. void debugger::set_breakpoint_at_function(const std::string& name) { 
  2.     for (const auto& cu : m_dwarf.compilation_units()) { 
  3.         for (const auto& die : cu.root()) { 
  4.             if (die.has(dwarf::DW_AT::name) && at_name(die) == name) { 
  5.                 auto low_pc = at_low_pc(die); 
  6.                 auto entry = get_line_entry_from_pc(low_pc); 
  7.                 ++entry; //skip prologue 
  8.                 set_breakpoint_at_address(entry->address); 
  9.             } 
  10.         } 
  11.     } 

這代碼看起來有點奇怪的唯一一點是 ++entry。 問題是函數的 DW_AT_low_pc 不指向該函數的用戶代碼的起始地址,它指向 prologue 的開始。編譯器通常會輸出一個函數的 prologue 和 epilogue,它們用于執行保存和恢復堆棧、操作堆棧指針等。這對我們來說不是很有用,所以我們將入口行加一來獲取用戶代碼的***行而不是 prologue。DWARF 行表實際上具有一些功能,用于將入口標記為函數 prologue 之后的***行,但并不是所有編譯器都輸出它,因此我采用了原始的方法。

源碼行

要在高層源碼行上設置一個斷點,我們要將這個行號轉換成 DWARF 中的一個地址。我們將遍歷編譯單元,尋找一個名稱與給定文件匹配的編譯單元,然后查找與給定行對應的入口。

DWARF 看上去有點像這樣:

  1. .debug_line: line number info for a single cu 
  2. Source lines (from CU-DIE at .debug_info offset 0x0000000b): 
  3. NS new statement, BB new basic block, ET end of text sequence 
  4. PE prologue end, EB epilogue begin 
  5. IS=val ISA number, DI=val discriminator value 
  6. <pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath" 
  7. 0x004004a7  [   1, 0] NS uri: "/super/secret/path/a.hpp" 
  8. 0x004004ab  [   2, 0] NS 
  9. 0x004004b2  [   3, 0] NS 
  10. 0x004004b9  [   4, 0] NS 
  11. 0x004004c1  [   5, 0] NS 
  12. 0x004004c3  [   1, 0] NS uri: "/super/secret/path/b.hpp" 
  13. 0x004004c7  [   2, 0] NS 
  14. 0x004004ce  [   3, 0] NS 
  15. 0x004004d5  [   4, 0] NS 
  16. 0x004004dd  [   5, 0] NS 
  17. 0x004004df  [   4, 0] NS uri: "/super/secret/path/ab.cpp" 
  18. 0x004004e3  [   5, 0] NS 
  19. 0x004004e8  [   6, 0] NS 
  20. 0x004004ed  [   7, 0] NS 
  21. 0x004004f4  [   7, 0] NS ET 

所以如果我們想要在 ab.cpp 的第五行設置一個斷點,我們將查找與行 (0x004004e3) 相關的入口并設置一個斷點。

  1. void debugger::set_breakpoint_at_source_line(const std::string& file, unsigned line) { 
  2.     for (const auto& cu : m_dwarf.compilation_units()) { 
  3.         if (is_suffix(file, at_name(cu.root()))) { 
  4.             const auto& lt = cu.get_line_table(); 
  5.             for (const auto& entry : lt) { 
  6.                 if (entry.is_stmt && entry.line == line) { 
  7.                     set_breakpoint_at_address(entry.address); 
  8.                     return
  9.                 } 
  10.             } 
  11.         } 
  12.     } 

我這里做了 is_suffix hack,這樣你可以輸入 c.cpp 代表 a/b/c.cpp 。當然你實際上應該使用大小寫敏感路徑處理庫或者其它東西,但是我比較懶。entry.is_stmt 是檢查行表入口是否被標記為一個語句的開頭,這是由編譯器根據它認為是斷點的***目標的地址設置的。

符號查找

當我們在對象文件層時,符號是王者。函數用符號命名,全局變量用符號命名,你得到一個符號,我們得到一個符號,每個人都得到一個符號。 在給定的對象文件中,一些符號可能引用其他對象文件或共享庫,鏈接器將從符號引用創建一個可執行程序。

可以在正確命名的符號表中查找符號,它存儲在二進制文件的 ELF 部分中。幸運的是,libelfin 有一個不錯的接口來做這件事,所以我們不需要自己處理所有的 ELF 的事情。為了讓你知道我們在處理什么,下面是一個二進制文件的 .symtab 部分的轉儲,它由 readelf 生成:

  1. Num:    Value          Size Type    Bind   Vis      Ndx Name 
  2.  0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  3.  1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1 
  4.  2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2 
  5.  3: 0000000000400278     0 SECTION LOCAL  DEFAULT    3 
  6.  4: 00000000004002c8     0 SECTION LOCAL  DEFAULT    4 
  7.  5: 0000000000400430     0 SECTION LOCAL  DEFAULT    5 
  8.  6: 00000000004004e4     0 SECTION LOCAL  DEFAULT    6 
  9.  7: 0000000000400508     0 SECTION LOCAL  DEFAULT    7 
  10.  8: 0000000000400528     0 SECTION LOCAL  DEFAULT    8 
  11.  9: 0000000000400558     0 SECTION LOCAL  DEFAULT    9 
  12. 10: 0000000000400570     0 SECTION LOCAL  DEFAULT   10 
  13. 11: 0000000000400714     0 SECTION LOCAL  DEFAULT   11 
  14. 12: 0000000000400720     0 SECTION LOCAL  DEFAULT   12 
  15. 13: 0000000000400724     0 SECTION LOCAL  DEFAULT   13 
  16. 14: 0000000000400750     0 SECTION LOCAL  DEFAULT   14 
  17. 15: 0000000000600e18     0 SECTION LOCAL  DEFAULT   15 
  18. 16: 0000000000600e20     0 SECTION LOCAL  DEFAULT   16 
  19. 17: 0000000000600e28     0 SECTION LOCAL  DEFAULT   17 
  20. 18: 0000000000600e30     0 SECTION LOCAL  DEFAULT   18 
  21. 19: 0000000000600ff0     0 SECTION LOCAL  DEFAULT   19 
  22. 20: 0000000000601000     0 SECTION LOCAL  DEFAULT   20 
  23. 21: 0000000000601018     0 SECTION LOCAL  DEFAULT   21 
  24. 22: 0000000000601028     0 SECTION LOCAL  DEFAULT   22 
  25. 23: 0000000000000000     0 SECTION LOCAL  DEFAULT   23 
  26. 24: 0000000000000000     0 SECTION LOCAL  DEFAULT   24 
  27. 25: 0000000000000000     0 SECTION LOCAL  DEFAULT   25 
  28. 26: 0000000000000000     0 SECTION LOCAL  DEFAULT   26 
  29. 27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27 
  30. 28: 0000000000000000     0 SECTION LOCAL  DEFAULT   28 
  31. 29: 0000000000000000     0 SECTION LOCAL  DEFAULT   29 
  32. 30: 0000000000000000     0 SECTION LOCAL  DEFAULT   30 
  33. 31: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS init.c 
  34. 32: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c 
  35. 33: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   17 __JCR_LIST__ 
  36. 34: 00000000004005a0     0 FUNC    LOCAL  DEFAULT   10 deregister_tm_clones 
  37. 35: 00000000004005e0     0 FUNC    LOCAL  DEFAULT   10 register_tm_clones 
  38. 36: 0000000000400620     0 FUNC    LOCAL  DEFAULT   10 __do_global_dtors_aux 
  39. 37: 0000000000601028     1 OBJECT  LOCAL  DEFAULT   22 completed.6917 
  40. 38: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   16 __do_global_dtors_aux_fin 
  41. 39: 0000000000400640     0 FUNC    LOCAL  DEFAULT   10 frame_dummy 
  42. 40: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   15 __frame_dummy_init_array_ 
  43. 41: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /super/secret/path/MiniDbg/ 
  44. 42: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c 
  45. 43: 0000000000400818     0 OBJECT  LOCAL  DEFAULT   14 __FRAME_END__ 
  46. 44: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   17 __JCR_END__ 
  47. 45: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
  48. 46: 0000000000400724     0 NOTYPE  LOCAL  DEFAULT   13 __GNU_EH_FRAME_HDR 
  49. 47: 0000000000601000     0 OBJECT  LOCAL  DEFAULT   20 _GLOBAL_OFFSET_TABLE_ 
  50. 48: 0000000000601028     0 OBJECT  LOCAL  DEFAULT   21 __TMC_END__ 
  51. 49: 0000000000601020     0 OBJECT  LOCAL  DEFAULT   21 __dso_handle 
  52. 50: 0000000000600e20     0 NOTYPE  LOCAL  DEFAULT   15 __init_array_end 
  53. 51: 0000000000600e18     0 NOTYPE  LOCAL  DEFAULT   15 __init_array_start 
  54. 52: 0000000000600e30     0 OBJECT  LOCAL  DEFAULT   18 _DYNAMIC 
  55. 53: 0000000000601018     0 NOTYPE  WEAK   DEFAULT   21 data_start 
  56. 54: 0000000000400710     2 FUNC    GLOBAL DEFAULT   10 __libc_csu_fini 
  57. 55: 0000000000400570    43 FUNC    GLOBAL DEFAULT   10 _start 
  58. 56: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__ 
  59. 57: 0000000000400714     0 FUNC    GLOBAL DEFAULT   11 _fini 
  60. 58: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_ 
  61. 59: 0000000000400720     4 OBJECT  GLOBAL DEFAULT   12 _IO_stdin_used 
  62. 60: 0000000000601018     0 NOTYPE  GLOBAL DEFAULT   21 __data_start 
  63. 61: 00000000004006a0   101 FUNC    GLOBAL DEFAULT   10 __libc_csu_init 
  64. 62: 0000000000601028     0 NOTYPE  GLOBAL DEFAULT   22 __bss_start 
  65. 63: 0000000000601030     0 NOTYPE  GLOBAL DEFAULT   22 _end 
  66. 64: 0000000000601028     0 NOTYPE  GLOBAL DEFAULT   21 _edata 
  67. 65: 0000000000400670    44 FUNC    GLOBAL DEFAULT   10 main 
  68. 66: 0000000000400558     0 FUNC    GLOBAL DEFAULT    9 _init 

你可以在對象文件中看到用于設置環境的很多符號,***還可以看到 main 符號。

我們對符號的類型、名稱和值(地址)感興趣。我們有一個該類型的 symbol_type 枚舉,并使用一個 std::string 作為名稱,std::uintptr_t 作為地址:

  1. enum class symbol_type { 
  2.     notype,            // No type (e.g., absolute symbol) 
  3.     object,            // Data object 
  4.     func,              // Function entry point 
  5.     section,           // Symbol is associated with a section 
  6.     file,              // Source file associated with the 
  7. };                     // object file 
  8. std::string to_string (symbol_type st) { 
  9.     switch (st) { 
  10.     case symbol_type::notype: return "notype"
  11.     case symbol_type::object: return "object"
  12.     case symbol_type::func: return "func"
  13.     case symbol_type::sectionreturn "section"
  14.     case symbol_type::file: return "file"
  15.     } 
  16. struct symbol { 
  17.     symbol_type type; 
  18.     std::string name
  19.     std::uintptr_t addr; 
  20. }; 

我們需要將從 libelfin 獲得的符號類型映射到我們的枚舉,因為我們不希望依賴關系破環這個接口。幸運的是,我為所有的東西選了同樣的名字,所以這樣很簡單:

  1. symbol_type to_symbol_type(elf::stt sym) { 
  2.     switch (sym) { 
  3.     case elf::stt::notype: return symbol_type::notype; 
  4.     case elf::stt::object: return symbol_type::object; 
  5.     case elf::stt::func: return symbol_type::func; 
  6.     case elf::stt::sectionreturn symbol_type::section
  7.     case elf::stt::file: return symbol_type::file; 
  8.     defaultreturn symbol_type::notype; 
  9.     } 
  10. }; 

***我們要查找符號。為了說明的目的,我循環查找符號表的 ELF 部分,然后收集我在其中找到的任意符號到 std::vector 中。更智能的實現可以建立從名稱到符號的映射,這樣你只需要查看一次數據就行了。

  1. std::vector<symbol> debugger::lookup_symbol(const std::string& name) { 
  2.     std::vector<symbol> syms; 
  3.     for (auto &sec : m_elf.sections()) { 
  4.         if (sec.get_hdr().type != elf::sht::symtab && sec.get_hdr().type != elf::sht::dynsym) 
  5.             continue
  6.         for (auto sym : sec.as_symtab()) { 
  7.             if (sym.get_name() == name) { 
  8.                 auto &d = sym.get_data(); 
  9.                 syms.push_back(symbol{to_symbol_type(d.type()), sym.get_name(), d.value}); 
  10.             } 
  11.         } 
  12.     } 
  13.     return syms; 

添加命令

一如往常,我們需要添加一些更多的命令來向用戶暴露功能。對于斷點,我使用 GDB 風格的接口,其中斷點類型是通過你傳遞的參數推斷的,而不用要求顯式切換:

  • 0x<hexadecimal> -> 斷點地址
  • <line>:<filename> -> 斷點行號
  • <anything else> -> 斷點函數名
  1. else if(is_prefix(command, "break")) { 
  2.     if (args[1][0] == '0' && args[1][1] == 'x') { 
  3.         std::string addr {args[1], 2}; 
  4.         set_breakpoint_at_address(std::stol(addr, 0, 16)); 
  5.     } 
  6.     else if (args[1].find(':') != std::string::npos) { 
  7.         auto file_and_line = split(args[1], ':'); 
  8.         set_breakpoint_at_source_line(file_and_line[0], std::stoi(file_and_line[1])); 
  9.     } 
  10.     else { 
  11.         set_breakpoint_at_function(args[1]); 
  12.     } 

對于符號,我們將查找符號并打印出我們發現的任何匹配項:

  1. else if(is_prefix(command, "symbol")) { 
  2.     auto syms = lookup_symbol(args[1]); 
  3.     for (auto&& s : syms) { 
  4.         std::cout << s.name << ' ' << to_string(s.type) << " 0x" << std::hex << s.addr << std::endl; 
  5.     } 

測試一下

在一個簡單的二進制文件上啟動調試器,并設置源代碼級別的斷點。在一些 foo 函數上設置一個斷點,看到我的調試器停在它上面是我這個項目最有價值的時刻之一。

符號查找可以通過在程序中添加一些函數或全局變量并查找它們的名稱來進行測試。請注意,如果你正在編譯 C++ 代碼,你還需要考慮名稱重整。

本文就這些了。下一次我將展示如何向調試器添加堆棧展開支持。

你可以在這里找到這篇文章的代碼。 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2017-06-28 14:21:22

Linux調試器斷點

2017-08-28 15:29:19

Linux調試器源碼級逐步執行

2017-08-28 14:40:57

Linux調試器源碼和信號

2017-06-22 10:44:55

Linux調試器準備環境

2017-10-09 10:56:49

Linux調試器處理變量

2017-10-12 18:20:44

Linux調試器高級主題

2017-10-09 10:26:01

Linux調試器堆棧展開

2017-07-25 10:30:32

Linux調試器Elves和dwarv

2017-07-05 14:37:07

Linux調試器寄存器和內存

2022-05-23 09:22:20

Go語言調試器Delve

2017-04-19 21:35:38

Linux調試器工作原理

2011-08-25 16:34:27

Lua調試器

2020-03-16 10:05:13

EmacsGUDLinux

2010-03-01 11:06:52

Python 調試器

2009-12-14 10:57:34

Ruby調試器

2011-08-31 16:51:12

Lua調試器

2019-12-06 14:30:41

GNU調試器GDB修復代碼

2024-03-13 08:00:00

Linux調試器應用程序

2023-02-28 11:39:55

CMake腳本項目

2011-08-24 11:08:09

Lua
點贊
收藏

51CTO技術棧公眾號

国产主播欧美精品| 亚洲国产成人精品女人久久久| 少妇精品久久久久久久久久| 中文字幕精品一区二| 欧美第十八页| 欧美一级视频精品观看| 日韩欧美视频网站| 秋霞a级毛片在线看| 国产成人一区在线| 8x海外华人永久免费日韩内陆视频| 中文在线永久免费观看| 992tv国产精品成人影院| 亚洲少妇30p| 久久精品日韩| 国产国语亲子伦亲子| 免费看的黄色欧美网站| 久久亚洲综合国产精品99麻豆精品福利| 久久av一区二区三| jizz免费一区二区三区| 亚洲成av人片在www色猫咪| 久久资源av| www.久久精品.com| 日本女优在线视频一区二区 | 免费黄色在线| 91在线视频观看| 亚洲一区二区中文字幕| 亚洲色成人www永久网站| 亚洲福利久久| 中文字幕一区电影| 亚洲AV无码国产精品| 国产精品igao视频网网址不卡日韩| 图片区日韩欧美亚洲| 三上悠亚免费在线观看| www免费网站在线观看| 99视频在线精品| 96成人在线视频| 中文字幕一区二区人妻| 日韩高清一区二区| 色综合久综合久久综合久鬼88| 久久精品三级视频| 亚洲精品456| 精品国产免费一区二区三区四区| 男人午夜视频在线观看| 日韩一级视频| 欧美性xxxxx极品少妇| 国产精品欧美激情在线观看| 国产传媒在线观看| 亚洲国产人成综合网站| 成人在线国产视频| 日本高清成人vr专区| 最新日韩在线视频| 国产精品亚洲天堂| 免费日本一区二区三区视频| 国产精品视频麻豆| 先锋影音日韩| 9191在线| 亚洲欧洲另类国产综合| 一区二区不卡在线观看| 日日夜夜精品一区| 综合激情成人伊人| 亚洲欧美一二三| 欧美精品videos另类| 国产欧美日韩激情| 一区二区成人国产精品 | 欧美激情在线观看视频免费| 欧美日韩国产不卡在线看| 五月天婷婷在线观看| 99re免费视频精品全部| 欧美日韩无遮挡| 国产乱理伦片a级在线观看| 国产日产欧美一区二区视频| 日韩色妇久久av| 一广人看www在线观看免费视频| 欧美国产日韩a欧美在线观看| 色99中文字幕| 免费在线观看av片| 亚洲最大成人网4388xx| 欧洲精品一区二区三区久久| 国产精品蜜芽在线观看| 色婷婷久久一区二区三区麻豆| 亚洲性生活网站| 欧美高清免费| 日韩免费观看高清完整版| 成人区人妻精品一区二| 特黄特色欧美大片| 色哟哟入口国产精品| 五月天av网站| 99精品国产福利在线观看免费| 欧美尤物巨大精品爽| 欧美男人天堂网| 国产一区不卡在线| 精品中文字幕人| 91啦中文在线| 亚洲国产日韩精品| 欧美成人三级在线播放| 88久久精品| 亚洲女同精品视频| 极品久久久久久| 欧美一级二区| 亚洲va电影大全| 欧美日本网站| 亚洲精品日日夜夜| 日本老熟妇毛茸茸| 中文字幕区一区二区三| 在线国产精品视频| 国产大片中文字幕在线观看| 免费亚洲电影在线| 国产偷国产偷亚洲高清97cao| 国产h在线观看| 亚洲午夜精品一区二区三区他趣| chinese少妇国语对白| 在线综合色站| 久久精品国产久精国产一老狼| 久久夜色精品亚洲| 国内精品自线一区二区三区视频| 久久国产精品99久久久久久丝袜| 乱人伦中文视频在线| 色综合久久综合网97色综合| 成人三级做爰av| 日本大胆欧美| 日韩**中文字幕毛片| www.黄色av| 亚洲欧洲av另类| 欧美 国产 小说 另类| silk一区二区三区精品视频| www.欧美精品| 欧美国产一级片| 97久久精品人人做人人爽| 国产免费xxx| 天堂久久一区| 中文字幕精品国产| 日本久久综合网| 97精品电影院| 成人午夜视频在线观看免费| 日韩一二三区| 久久亚洲春色中文字幕| 在线观看免费黄色小视频| 久久久久国产成人精品亚洲午夜| 国产原创中文在线观看| 亚洲日本va| 欧美激情奇米色| wwwav在线播放| 亚洲精品高清在线| 91视频福利网| 成人久久电影| 国产精品久久久久久久av电影| 日韩欧美电影在线观看| 偷拍亚洲欧洲综合| 欲求不满的岳中文字幕| 极品av少妇一区二区| 成人免费91在线看| ririsao久久精品一区| 欧美不卡123| 国产一级做a爱免费视频| 国产91色综合久久免费分享| 黄色片免费在线观看视频| 欧美专区视频| 久久久久久久网站| 亚洲av激情无码专区在线播放| 亚洲午夜影视影院在线观看| 国产xxxx视频| 媚黑女一区二区| 日韩欧美亚洲精品| 欧美极品在线| 九九精品视频在线观看| 高h震动喷水双性1v1| 五月综合激情婷婷六月色窝| 粉嫩av懂色av蜜臀av分享| 国产欧美日韩综合一区在线播放| 久久综合九色99| 国模视频一区| 色噜噜狠狠狠综合曰曰曰88av | 久久青青色综合| 亚洲精美色品网站| 成人小视频在线播放| 国产精品久久毛片av大全日韩| 午夜天堂在线视频| 一区免费在线| 日韩精品一区二区三区外面| 玖玖精品在线| 久久久久久九九九| 欧美精品久久久久久久久久丰满| 欧美羞羞免费网站| 久久久久99精品成人片试看| 99久久er热在这里只有精品66| 激情六月丁香婷婷| 忘忧草精品久久久久久久高清| 97人人模人人爽人人少妇| 国产高清中文字幕在线| 色噜噜亚洲精品中文字幕| 99国产揄拍国产精品| 粉嫩老牛aⅴ一区二区三区| 婷婷综合在线视频| 成人福利视频网站| 性生活免费在线观看| 亚洲无吗在线| 一区二区三区在线观看www| silk一区二区三区精品视频| 国产精品日韩在线观看| 丁香花在线高清完整版视频| 国产一级揄自揄精品视频| 精品国产99久久久久久宅男i| 欧美日韩国产精品专区| 神马午夜精品91| 97久久精品人人爽人人爽蜜臀| 女人高潮一级片| 老司机午夜免费精品视频| 欧美视频在线第一页| 成人激情开心网| 精品卡一卡二| 欧美日韩黄网站| 国产精品视频一区国模私拍| gogo久久| 毛片精品免费在线观看| youjizz在线播放| 日韩精品视频免费| 性少妇videosexfreexxx片| 91久久精品一区二区二区| 久久综合加勒比| 亚洲色图视频网| 国产探花视频在线播放| 99精品视频在线观看| 第一页在线视频| 久久国产精品99久久人人澡| 国产黄色特级片| 999在线观看精品免费不卡网站| 中文字幕在线亚洲精品| jlzzjlzz亚洲女人| 欧美日本亚洲| 一本久久青青| 精品视频第一区| 国产精品色呦| av在线不卡一区| 国模大尺度视频一区二区| 国产精品视频永久免费播放| 国产v综合v| 国产成人久久久精品一区| 涩涩在线视频| 国产91|九色| 性国裸体高清亚洲| 91精品国产乱码久久久久久蜜臀| 国产精品69xx| 欧美激情乱人伦一区| 天堂8中文在线| 欧美国产日韩二区| 色呦呦在线播放| 欧美韩日一区二区| 美女网站视频在线| 色综合久久久888| 午夜dj在线观看高清视频完整版| 久久这里只有精品视频首页| 国产视频一区二区| 裸体女人亚洲精品一区| av在线free| 欧美激情国内偷拍| 国产理论电影在线| 91精品国产色综合久久不卡98| 55av亚洲| 日本视频久久久| 一二区成人影院电影网| 国产精品入口福利| 91成人在线网站| 91观看网站| 久本草在线中文字幕亚洲| 快播日韩欧美| 精品色999| 最新av在线免费观看| 欧美特黄视频| 欧美s码亚洲码精品m码| 可以看av的网站久久看| 中文字幕 91| 国产一区二区精品在线观看| 最新国产精品自拍| 91麻豆免费在线观看| 精品人妻中文无码av在线| 中文字幕一区二区5566日韩| 麻豆明星ai换脸视频| 亚洲午夜私人影院| 无码人妻精品一区二区三区不卡| 欧美色综合影院| 国产成人精品无码高潮| 亚洲精品videossex少妇| 波多野结衣在线影院| 美女性感视频久久久| 国内精彩免费自拍视频在线观看网址| 日韩美女视频免费在线观看| 欧美性aaa| 国产一区高清视频| 欧美色图在线播放| 99热这里只有精品免费| 久久九九电影| 一级片免费在线观看视频| 久久中文字幕电影| 手机在线免费看片| 日韩欧美精品在线观看| 99产精品成人啪免费网站| 亚洲激情视频网站| 麻豆传媒在线免费看| 午夜精品福利在线观看| 四虎精品一区二区免费| 精品国产免费人成电影在线观...| 日本不卡电影| 日本少妇高潮喷水视频| 狠狠色综合色综合网络| 丰满少妇在线观看资源站| 亚洲欧美一区二区久久| 国产精品视频123| 日韩一区二区麻豆国产| 福利在线播放| 97色在线观看| 欧美高清hd| 亚洲欧美日韩精品综合在线观看| 亚洲免费成人| 91人妻一区二区三区| 国产精品久久久一本精品| 亚洲欧美偷拍视频| 精品国产乱码久久久久久1区2区 | 久久免费电影网| 久久久一二三区| 欧美精品777| 国产高清视频在线| 欧美在线亚洲在线| 精品成人自拍视频| 一本色道久久88亚洲精品综合| 青青草原综合久久大伊人精品优势| 一本加勒比波多野结衣| 一区二区三区日本| 国产精品视频一区二区三区,| 夜夜嗨av一区二区三区免费区| 黑森林国产精品av| 国产乱码精品一区二区三区日韩精品 | 精品孕妇一区二区三区| 国产精品视频一区二区三区四 | 成人性生交大片免费| 国产男女猛烈无遮挡在线喷水| 在线免费精品视频| 欧洲毛片在线| 欧美孕妇孕交黑巨大网站| 理论片一区二区在线| 欧美又粗又长又爽做受| 国产精品18久久久久久久久| 三级全黄做爰视频| 欧美丰满嫩嫩电影| 麻豆视频网站在线观看| 国产一区二中文字幕在线看| 成人一区不卡| 天天操,天天操| 国产精品素人视频| 亚洲专区第一页| 久久精品福利视频| 国内精品视频| cao在线观看| av成人动漫在线观看| 在线观看日韩中文字幕| 亚洲美女视频网站| jizz亚洲女人高潮大叫| 亚洲一区二区不卡视频| 久久99久久精品| 538精品在线视频| 精品精品国产高清a毛片牛牛| 精灵使的剑舞无删减版在线观看| 国产精品亚洲综合| 国产亚洲高清视频| 亚洲黄色免费视频| 欧美另类变人与禽xxxxx| www.久久ai| 国产综合色一区二区三区| 久久久久看片| 国产精品suv一区二区88| 欧美一区二区网站| 波多野结衣中文在线| 欧美极品色图| 麻豆中文一区二区| 欧美日韩精品在线观看视频| 亚洲成人精品在线| 依依综合在线| 欧美亚洲视频一区| 成人精品国产免费网站| 久久久久女人精品毛片九一| 自拍偷拍亚洲精品| 欧美视频精品全部免费观看| 黄色av网址在线播放| 亚洲国产成人午夜在线一区| 国产裸体无遮挡| 91高清免费视频| 99久久婷婷| 久久午夜夜伦鲁鲁片| 精品视频在线看| 91福利在线尤物| 五月天婷亚洲天综合网鲁鲁鲁| 国产综合成人久久大片91| 日本熟女一区二区| 中文字幕亚洲一区在线观看| 99a精品视频在线观看| 国产真实乱子伦| 一区二区三区在线视频播放| 欧美91精品久久久久国产性生爱| 91久久在线观看| 久久久久久久欧美精品| 激情视频在线播放|