debugger-mi.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #!/usr/bin/python
  2. # Copyright 2016 Steven Watanabe
  3. # Distributed under the Boost Software License, Version 1.0.
  4. # (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
  5. # Test the mi interface for the debugger
  6. import BoostBuild
  7. import TestCmd
  8. import re
  9. def split_stdin_stdout(text):
  10. """stdin is all text after the prompt up to and including
  11. the next newline. Everything else is stdout. stdout
  12. may contain regular expressions enclosed in {{}}."""
  13. prompt = re.escape('(gdb) \n')
  14. pattern = re.compile('(?<=%s)((?:\d*-.*)\n)' % prompt)
  15. stdin = ''.join(re.findall(pattern, text))
  16. stdout = re.sub(pattern, '', text)
  17. outside_pattern = re.compile(r'(?:\A|(?<=\}\}))(?:[^\{]|(?:\{(?!\{)))*(?:(?=\{\{)|\Z)')
  18. def escape_line(line):
  19. line = re.sub(outside_pattern, lambda m: re.escape(m.group(0)), line)
  20. return re.sub(r'\{\{|\}\}', '', line)
  21. stdout = '\n'.join([escape_line(line) for line in stdout.split('\n')])
  22. return (stdin,stdout)
  23. def run(tester, io):
  24. (input,output) = split_stdin_stdout(io)
  25. tester.run_build_system(stdin=input, stdout=output, match=TestCmd.match_re)
  26. def make_tester():
  27. return BoostBuild.Tester(["-dmi"], pass_toolset=False, pass_d0=False,
  28. use_test_config=False, ignore_toolset_requirements=False, match=TestCmd.match_re)
  29. def test_exec_run():
  30. t = make_tester()
  31. t.write("test.jam", """\
  32. UPDATE ;
  33. """)
  34. run(t, """\
  35. =thread-group-added,id="i1"
  36. (gdb)
  37. 72-exec-run -ftest.jam
  38. =thread-created,id="1",group-id="i1"
  39. 72^running
  40. (gdb)
  41. *stopped,reason="exited-normally"
  42. (gdb)
  43. 73-gdb-exit
  44. 73^exit
  45. """)
  46. t.cleanup()
  47. def test_exit_status():
  48. t = make_tester()
  49. t.write("test.jam", """\
  50. EXIT : 1 ;
  51. """)
  52. run(t, """\
  53. =thread-group-added,id="i1"
  54. (gdb)
  55. 72-exec-run -ftest.jam
  56. =thread-created,id="1",group-id="i1"
  57. 72^running
  58. (gdb)
  59. *stopped,reason="exited",exit-code="1"
  60. (gdb)
  61. 73-gdb-exit
  62. 73^exit
  63. """)
  64. t.cleanup()
  65. def test_exec_step():
  66. t = make_tester()
  67. t.write("test.jam", """\
  68. rule g ( )
  69. {
  70. a = 1 ;
  71. b = 2 ;
  72. }
  73. rule f ( )
  74. {
  75. g ;
  76. c = 3 ;
  77. }
  78. f ;
  79. """)
  80. run(t, """\
  81. =thread-group-added,id="i1"
  82. (gdb)
  83. -break-insert f
  84. ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
  85. (gdb)
  86. 72-exec-run -ftest.jam
  87. =thread-created,id="1",group-id="i1"
  88. 72^running
  89. (gdb)
  90. *stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="8"},thread-id="1",stopped-threads="all"
  91. (gdb)
  92. 1-exec-step
  93. 1^running
  94. (gdb)
  95. *stopped,reason="end-stepping-range",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1"
  96. (gdb)
  97. 2-exec-step
  98. 2^running
  99. (gdb)
  100. *stopped,reason="end-stepping-range",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="4"},thread-id="1"
  101. (gdb)
  102. 3-exec-step
  103. 3^running
  104. (gdb)
  105. *stopped,reason="end-stepping-range",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="9"},thread-id="1"
  106. (gdb)
  107. 73-gdb-exit
  108. 73^exit
  109. """)
  110. t.cleanup()
  111. def test_exec_next():
  112. t = make_tester()
  113. t.write("test.jam", """\
  114. rule g ( )
  115. {
  116. a = 1 ;
  117. }
  118. rule f ( )
  119. {
  120. g ;
  121. b = 2 ;
  122. c = 3 ;
  123. }
  124. rule h ( )
  125. {
  126. f ;
  127. g ;
  128. }
  129. h ;
  130. d = 4 ;
  131. """)
  132. run(t, """\
  133. =thread-group-added,id="i1"
  134. (gdb)
  135. -break-insert f
  136. ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
  137. (gdb)
  138. 72-exec-run -ftest.jam
  139. =thread-created,id="1",group-id="i1"
  140. 72^running
  141. (gdb)
  142. *stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="7"},thread-id="1",stopped-threads="all"
  143. (gdb)
  144. 1-exec-next
  145. 1^running
  146. (gdb)
  147. *stopped,reason="end-stepping-range",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="8"},thread-id="1"
  148. (gdb)
  149. 2-exec-next
  150. 2^running
  151. (gdb)
  152. *stopped,reason="end-stepping-range",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="9"},thread-id="1"
  153. (gdb)
  154. 3-exec-next
  155. 3^running
  156. (gdb)
  157. *stopped,reason="end-stepping-range",frame={func="h",args=[],file="test.jam",fullname="{{.*}}test.jam",line="14"},thread-id="1"
  158. (gdb)
  159. 4-exec-next
  160. 4^running
  161. (gdb)
  162. *stopped,reason="end-stepping-range",frame={func="module scope",args=[],file="test.jam",fullname="{{.*}}test.jam",line="17"},thread-id="1"
  163. (gdb)
  164. 73-gdb-exit
  165. 73^exit
  166. """)
  167. t.cleanup()
  168. def test_exec_finish():
  169. t = make_tester()
  170. t.write("test.jam", """\
  171. rule f ( )
  172. {
  173. a = 1 ;
  174. }
  175. rule g ( )
  176. {
  177. f ;
  178. b = 2 ;
  179. i ;
  180. }
  181. rule h ( )
  182. {
  183. g ;
  184. i ;
  185. }
  186. rule i ( )
  187. {
  188. c = 3 ;
  189. }
  190. h ;
  191. d = 4 ;
  192. """)
  193. run(t, """\
  194. =thread-group-added,id="i1"
  195. (gdb)
  196. -break-insert f
  197. ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
  198. (gdb)
  199. 72-exec-run -ftest.jam
  200. =thread-created,id="1",group-id="i1"
  201. 72^running
  202. (gdb)
  203. *stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1",stopped-threads="all"
  204. (gdb)
  205. 1-exec-finish
  206. 1^running
  207. (gdb)
  208. *stopped,reason="end-stepping-range",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="8"},thread-id="1"
  209. (gdb)
  210. 2-exec-finish
  211. 2^running
  212. (gdb)
  213. *stopped,reason="end-stepping-range",frame={func="h",args=[],file="test.jam",fullname="{{.*}}test.jam",line="14"},thread-id="1"
  214. (gdb)
  215. 3-exec-finish
  216. 3^running
  217. (gdb)
  218. *stopped,reason="end-stepping-range",frame={func="module scope",args=[],file="test.jam",fullname="{{.*}}test.jam",line="21"},thread-id="1"
  219. (gdb)
  220. 73-gdb-exit
  221. 73^exit
  222. """)
  223. t.cleanup()
  224. def test_breakpoints():
  225. """Tests the interaction between the following commands:
  226. break, clear, delete, disable, enable"""
  227. t = make_tester()
  228. t.write("test.jam", """\
  229. rule f ( )
  230. {
  231. a = 1 ;
  232. }
  233. rule g ( )
  234. {
  235. b = 2 ;
  236. }
  237. rule h ( )
  238. {
  239. c = 3 ;
  240. d = 4 ;
  241. }
  242. f ;
  243. g ;
  244. h ;
  245. UPDATE ;
  246. """)
  247. run(t, """\
  248. =thread-group-added,id="i1"
  249. (gdb)
  250. -break-insert f
  251. ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
  252. (gdb)
  253. 72-exec-run -ftest.jam
  254. =thread-created,id="1",group-id="i1"
  255. 72^running
  256. (gdb)
  257. *stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1",stopped-threads="all"
  258. (gdb)
  259. -interpreter-exec console kill
  260. ^done
  261. (gdb)
  262. -break-insert g
  263. ^done,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",func="g"}
  264. (gdb)
  265. -break-disable 1
  266. ^done
  267. (gdb)
  268. 73-exec-run -ftest.jam
  269. =thread-created,id="1",group-id="i1"
  270. 73^running
  271. (gdb)
  272. *stopped,reason="breakpoint-hit",bkptno="2",disp="keep",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="7"},thread-id="1",stopped-threads="all"
  273. (gdb)
  274. -interpreter-exec console kill
  275. ^done
  276. (gdb)
  277. -break-enable 1
  278. ^done
  279. (gdb)
  280. 74-exec-run -ftest.jam
  281. =thread-created,id="1",group-id="i1"
  282. 74^running
  283. (gdb)
  284. *stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1",stopped-threads="all"
  285. (gdb)
  286. -interpreter-exec console kill
  287. ^done
  288. (gdb)
  289. -break-delete 1
  290. ^done
  291. (gdb)
  292. 75-exec-run -ftest.jam
  293. =thread-created,id="1",group-id="i1"
  294. 75^running
  295. (gdb)
  296. *stopped,reason="breakpoint-hit",bkptno="2",disp="keep",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="7"},thread-id="1",stopped-threads="all"
  297. (gdb)
  298. 76-gdb-exit
  299. 76^exit
  300. """)
  301. t.cleanup()
  302. test_exec_run()
  303. test_exit_status()
  304. test_exec_step()
  305. test_exec_next()
  306. test_exec_finish()
  307. test_breakpoints()