replay-debugging.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * replay-debugging.c
  3. *
  4. * Copyright (c) 2010-2020 Institute for System Programming
  5. * of the Russian Academy of Sciences.
  6. *
  7. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  8. * See the COPYING file in the top-level directory.
  9. *
  10. */
  11. #include "qemu/osdep.h"
  12. #include "qapi/error.h"
  13. #include "sysemu/replay.h"
  14. #include "sysemu/runstate.h"
  15. #include "replay-internal.h"
  16. #include "monitor/hmp.h"
  17. #include "monitor/monitor.h"
  18. #include "qapi/qapi-commands-replay.h"
  19. #include "qapi/qmp/qdict.h"
  20. #include "qemu/timer.h"
  21. #include "block/snapshot.h"
  22. #include "migration/snapshot.h"
  23. static bool replay_is_debugging;
  24. static int64_t replay_last_breakpoint;
  25. static int64_t replay_last_snapshot;
  26. bool replay_running_debug(void)
  27. {
  28. return replay_is_debugging;
  29. }
  30. void hmp_info_replay(Monitor *mon, const QDict *qdict)
  31. {
  32. if (replay_mode == REPLAY_MODE_NONE) {
  33. monitor_printf(mon, "Record/replay is not active\n");
  34. } else {
  35. monitor_printf(mon,
  36. "%s execution '%s': instruction count = %"PRId64"\n",
  37. replay_mode == REPLAY_MODE_RECORD ? "Recording" : "Replaying",
  38. replay_get_filename(), replay_get_current_icount());
  39. }
  40. }
  41. ReplayInfo *qmp_query_replay(Error **errp)
  42. {
  43. ReplayInfo *retval = g_new0(ReplayInfo, 1);
  44. retval->mode = replay_mode;
  45. if (replay_get_filename()) {
  46. retval->filename = g_strdup(replay_get_filename());
  47. }
  48. retval->icount = replay_get_current_icount();
  49. return retval;
  50. }
  51. static void replay_break(uint64_t icount, QEMUTimerCB callback, void *opaque)
  52. {
  53. assert(replay_mode == REPLAY_MODE_PLAY);
  54. assert(replay_mutex_locked());
  55. assert(replay_break_icount >= replay_get_current_icount());
  56. assert(callback);
  57. replay_break_icount = icount;
  58. if (replay_break_timer) {
  59. timer_del(replay_break_timer);
  60. }
  61. replay_break_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
  62. callback, opaque);
  63. }
  64. static void replay_delete_break(void)
  65. {
  66. assert(replay_mode == REPLAY_MODE_PLAY);
  67. assert(replay_mutex_locked());
  68. if (replay_break_timer) {
  69. timer_free(replay_break_timer);
  70. replay_break_timer = NULL;
  71. }
  72. replay_break_icount = -1ULL;
  73. }
  74. static void replay_stop_vm(void *opaque)
  75. {
  76. vm_stop(RUN_STATE_PAUSED);
  77. replay_delete_break();
  78. }
  79. void qmp_replay_break(int64_t icount, Error **errp)
  80. {
  81. if (replay_mode == REPLAY_MODE_PLAY) {
  82. if (icount >= replay_get_current_icount()) {
  83. replay_break(icount, replay_stop_vm, NULL);
  84. } else {
  85. error_setg(errp,
  86. "cannot set breakpoint at the instruction in the past");
  87. }
  88. } else {
  89. error_setg(errp, "setting the breakpoint is allowed only in play mode");
  90. }
  91. }
  92. void hmp_replay_break(Monitor *mon, const QDict *qdict)
  93. {
  94. int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
  95. Error *err = NULL;
  96. qmp_replay_break(icount, &err);
  97. if (err) {
  98. error_report_err(err);
  99. return;
  100. }
  101. }
  102. void qmp_replay_delete_break(Error **errp)
  103. {
  104. if (replay_mode == REPLAY_MODE_PLAY) {
  105. replay_delete_break();
  106. } else {
  107. error_setg(errp, "replay breakpoints are allowed only in play mode");
  108. }
  109. }
  110. void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
  111. {
  112. Error *err = NULL;
  113. qmp_replay_delete_break(&err);
  114. if (err) {
  115. error_report_err(err);
  116. return;
  117. }
  118. }
  119. static char *replay_find_nearest_snapshot(int64_t icount,
  120. int64_t *snapshot_icount)
  121. {
  122. BlockDriverState *bs;
  123. QEMUSnapshotInfo *sn_tab;
  124. QEMUSnapshotInfo *nearest = NULL;
  125. char *ret = NULL;
  126. int rv;
  127. int nb_sns, i;
  128. AioContext *aio_context;
  129. *snapshot_icount = -1;
  130. bs = bdrv_all_find_vmstate_bs(NULL, false, NULL, NULL);
  131. if (!bs) {
  132. goto fail;
  133. }
  134. aio_context = bdrv_get_aio_context(bs);
  135. aio_context_acquire(aio_context);
  136. nb_sns = bdrv_snapshot_list(bs, &sn_tab);
  137. aio_context_release(aio_context);
  138. for (i = 0; i < nb_sns; i++) {
  139. rv = bdrv_all_has_snapshot(sn_tab[i].name, false, NULL, NULL);
  140. if (rv < 0)
  141. goto fail;
  142. if (rv == 1) {
  143. if (sn_tab[i].icount != -1ULL
  144. && sn_tab[i].icount <= icount
  145. && (!nearest || nearest->icount < sn_tab[i].icount)) {
  146. nearest = &sn_tab[i];
  147. }
  148. }
  149. }
  150. if (nearest) {
  151. ret = g_strdup(nearest->name);
  152. *snapshot_icount = nearest->icount;
  153. }
  154. g_free(sn_tab);
  155. fail:
  156. return ret;
  157. }
  158. static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp)
  159. {
  160. char *snapshot = NULL;
  161. int64_t snapshot_icount;
  162. if (replay_mode != REPLAY_MODE_PLAY) {
  163. error_setg(errp, "replay must be enabled to seek");
  164. return;
  165. }
  166. snapshot = replay_find_nearest_snapshot(icount, &snapshot_icount);
  167. if (snapshot) {
  168. if (icount < replay_get_current_icount()
  169. || replay_get_current_icount() < snapshot_icount) {
  170. vm_stop(RUN_STATE_RESTORE_VM);
  171. load_snapshot(snapshot, NULL, false, NULL, errp);
  172. }
  173. g_free(snapshot);
  174. }
  175. if (replay_get_current_icount() <= icount) {
  176. replay_break(icount, callback, NULL);
  177. vm_start();
  178. } else {
  179. error_setg(errp, "cannot seek to the specified instruction count");
  180. }
  181. }
  182. void qmp_replay_seek(int64_t icount, Error **errp)
  183. {
  184. replay_seek(icount, replay_stop_vm, errp);
  185. }
  186. void hmp_replay_seek(Monitor *mon, const QDict *qdict)
  187. {
  188. int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
  189. Error *err = NULL;
  190. qmp_replay_seek(icount, &err);
  191. if (err) {
  192. error_report_err(err);
  193. return;
  194. }
  195. }
  196. static void replay_stop_vm_debug(void *opaque)
  197. {
  198. replay_is_debugging = false;
  199. vm_stop(RUN_STATE_DEBUG);
  200. replay_delete_break();
  201. }
  202. bool replay_reverse_step(void)
  203. {
  204. Error *err = NULL;
  205. assert(replay_mode == REPLAY_MODE_PLAY);
  206. if (replay_get_current_icount() != 0) {
  207. replay_seek(replay_get_current_icount() - 1,
  208. replay_stop_vm_debug, &err);
  209. if (err) {
  210. error_free(err);
  211. return false;
  212. }
  213. replay_is_debugging = true;
  214. return true;
  215. }
  216. return false;
  217. }
  218. static void replay_continue_end(void)
  219. {
  220. replay_is_debugging = false;
  221. vm_stop(RUN_STATE_DEBUG);
  222. replay_delete_break();
  223. }
  224. static void replay_continue_stop(void *opaque)
  225. {
  226. Error *err = NULL;
  227. if (replay_last_breakpoint != -1LL) {
  228. replay_seek(replay_last_breakpoint, replay_stop_vm_debug, &err);
  229. if (err) {
  230. error_free(err);
  231. replay_continue_end();
  232. }
  233. return;
  234. }
  235. /*
  236. * No breakpoints since the last snapshot.
  237. * Find previous snapshot and try again.
  238. */
  239. if (replay_last_snapshot != 0) {
  240. replay_seek(replay_last_snapshot - 1, replay_continue_stop, &err);
  241. if (err) {
  242. error_free(err);
  243. replay_continue_end();
  244. }
  245. replay_last_snapshot = replay_get_current_icount();
  246. } else {
  247. /* Seek to the very first step */
  248. replay_seek(0, replay_stop_vm_debug, &err);
  249. if (err) {
  250. error_free(err);
  251. replay_continue_end();
  252. }
  253. }
  254. }
  255. bool replay_reverse_continue(void)
  256. {
  257. Error *err = NULL;
  258. assert(replay_mode == REPLAY_MODE_PLAY);
  259. if (replay_get_current_icount() != 0) {
  260. replay_seek(replay_get_current_icount() - 1,
  261. replay_continue_stop, &err);
  262. if (err) {
  263. error_free(err);
  264. return false;
  265. }
  266. replay_last_breakpoint = -1LL;
  267. replay_is_debugging = true;
  268. replay_last_snapshot = replay_get_current_icount();
  269. return true;
  270. }
  271. return false;
  272. }
  273. void replay_breakpoint(void)
  274. {
  275. assert(replay_mode == REPLAY_MODE_PLAY);
  276. replay_last_breakpoint = replay_get_current_icount();
  277. }
  278. void replay_gdb_attached(void)
  279. {
  280. /*
  281. * Create VM snapshot on temporary overlay to allow reverse
  282. * debugging even if snapshots were not enabled.
  283. */
  284. if (replay_mode == REPLAY_MODE_PLAY
  285. && !replay_snapshot) {
  286. if (!save_snapshot("start_debugging", true, NULL, false, NULL, NULL)) {
  287. /* Can't create the snapshot. Continue conventional debugging. */
  288. }
  289. }
  290. }