mi-cmd-catch.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /* MI Command Set - catch commands.
  2. Copyright (C) 2012-2022 Free Software Foundation, Inc.
  3. Contributed by Intel Corporation.
  4. This file is part of GDB.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include "defs.h"
  16. #include "arch-utils.h"
  17. #include "breakpoint.h"
  18. #include "ada-lang.h"
  19. #include "mi-cmds.h"
  20. #include "mi-getopt.h"
  21. #include "mi-cmd-break.h"
  22. /* Handler for the -catch-assert command. */
  23. void
  24. mi_cmd_catch_assert (const char *cmd, char *argv[], int argc)
  25. {
  26. struct gdbarch *gdbarch = get_current_arch();
  27. std::string condition;
  28. int enabled = 1;
  29. int temp = 0;
  30. int oind = 0;
  31. char *oarg;
  32. enum opt
  33. {
  34. OPT_CONDITION, OPT_DISABLED, OPT_TEMP,
  35. };
  36. static const struct mi_opt opts[] =
  37. {
  38. { "c", OPT_CONDITION, 1},
  39. { "d", OPT_DISABLED, 0 },
  40. { "t", OPT_TEMP, 0 },
  41. { 0, 0, 0 }
  42. };
  43. for (;;)
  44. {
  45. int opt = mi_getopt ("-catch-assert", argc, argv, opts,
  46. &oind, &oarg);
  47. if (opt < 0)
  48. break;
  49. switch ((enum opt) opt)
  50. {
  51. case OPT_CONDITION:
  52. condition.assign (oarg);
  53. break;
  54. case OPT_DISABLED:
  55. enabled = 0;
  56. break;
  57. case OPT_TEMP:
  58. temp = 1;
  59. break;
  60. }
  61. }
  62. /* This command does not accept any argument. Make sure the user
  63. did not provide any. */
  64. if (oind != argc)
  65. error (_("Invalid argument: %s"), argv[oind]);
  66. scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  67. create_ada_exception_catchpoint (gdbarch, ada_catch_assert, std::string (),
  68. condition, temp, enabled, 0);
  69. }
  70. /* Handler for the -catch-exception command. */
  71. void
  72. mi_cmd_catch_exception (const char *cmd, char *argv[], int argc)
  73. {
  74. struct gdbarch *gdbarch = get_current_arch();
  75. std::string condition;
  76. int enabled = 1;
  77. std::string exception_name;
  78. int temp = 0;
  79. enum ada_exception_catchpoint_kind ex_kind = ada_catch_exception;
  80. int oind = 0;
  81. char *oarg;
  82. enum opt
  83. {
  84. OPT_CONDITION, OPT_DISABLED, OPT_EXCEPTION_NAME, OPT_TEMP,
  85. OPT_UNHANDLED,
  86. };
  87. static const struct mi_opt opts[] =
  88. {
  89. { "c", OPT_CONDITION, 1},
  90. { "d", OPT_DISABLED, 0 },
  91. { "e", OPT_EXCEPTION_NAME, 1 },
  92. { "t", OPT_TEMP, 0 },
  93. { "u", OPT_UNHANDLED, 0},
  94. { 0, 0, 0 }
  95. };
  96. for (;;)
  97. {
  98. int opt = mi_getopt ("-catch-exception", argc, argv, opts,
  99. &oind, &oarg);
  100. if (opt < 0)
  101. break;
  102. switch ((enum opt) opt)
  103. {
  104. case OPT_CONDITION:
  105. condition.assign (oarg);
  106. break;
  107. case OPT_DISABLED:
  108. enabled = 0;
  109. break;
  110. case OPT_EXCEPTION_NAME:
  111. exception_name = oarg;
  112. break;
  113. case OPT_TEMP:
  114. temp = 1;
  115. break;
  116. case OPT_UNHANDLED:
  117. ex_kind = ada_catch_exception_unhandled;
  118. break;
  119. }
  120. }
  121. /* This command does not accept any argument. Make sure the user
  122. did not provide any. */
  123. if (oind != argc)
  124. error (_("Invalid argument: %s"), argv[oind]);
  125. /* Specifying an exception name does not make sense when requesting
  126. an unhandled exception breakpoint. */
  127. if (ex_kind == ada_catch_exception_unhandled && !exception_name.empty ())
  128. error (_("\"-e\" and \"-u\" are mutually exclusive"));
  129. scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  130. create_ada_exception_catchpoint (gdbarch, ex_kind,
  131. exception_name,
  132. condition, temp, enabled, 0);
  133. }
  134. /* Handler for the -catch-handlers command. */
  135. void
  136. mi_cmd_catch_handlers (const char *cmd, char *argv[], int argc)
  137. {
  138. struct gdbarch *gdbarch = get_current_arch ();
  139. std::string condition;
  140. int enabled = 1;
  141. std::string exception_name;
  142. int temp = 0;
  143. int oind = 0;
  144. char *oarg;
  145. enum opt
  146. {
  147. OPT_CONDITION, OPT_DISABLED, OPT_EXCEPTION_NAME, OPT_TEMP
  148. };
  149. static const struct mi_opt opts[] =
  150. {
  151. { "c", OPT_CONDITION, 1},
  152. { "d", OPT_DISABLED, 0 },
  153. { "e", OPT_EXCEPTION_NAME, 1 },
  154. { "t", OPT_TEMP, 0 },
  155. { 0, 0, 0 }
  156. };
  157. for (;;)
  158. {
  159. int opt = mi_getopt ("-catch-handlers", argc, argv, opts,
  160. &oind, &oarg);
  161. if (opt < 0)
  162. break;
  163. switch ((enum opt) opt)
  164. {
  165. case OPT_CONDITION:
  166. condition.assign (oarg);
  167. break;
  168. case OPT_DISABLED:
  169. enabled = 0;
  170. break;
  171. case OPT_EXCEPTION_NAME:
  172. exception_name = oarg;
  173. break;
  174. case OPT_TEMP:
  175. temp = 1;
  176. break;
  177. }
  178. }
  179. /* This command does not accept any argument. Make sure the user
  180. did not provide any. */
  181. if (oind != argc)
  182. error (_("Invalid argument: %s"), argv[oind]);
  183. scoped_restore restore_breakpoint_reporting
  184. = setup_breakpoint_reporting ();
  185. create_ada_exception_catchpoint (gdbarch, ada_catch_handlers,
  186. exception_name,
  187. condition, temp, enabled, 0);
  188. }
  189. /* Common path for the -catch-load and -catch-unload. */
  190. static void
  191. mi_catch_load_unload (int load, char *argv[], int argc)
  192. {
  193. const char *actual_cmd = load ? "-catch-load" : "-catch-unload";
  194. int temp = 0;
  195. int enabled = 1;
  196. int oind = 0;
  197. char *oarg;
  198. enum opt
  199. {
  200. OPT_TEMP,
  201. OPT_DISABLED,
  202. };
  203. static const struct mi_opt opts[] =
  204. {
  205. { "t", OPT_TEMP, 0 },
  206. { "d", OPT_DISABLED, 0 },
  207. { 0, 0, 0 }
  208. };
  209. for (;;)
  210. {
  211. int opt = mi_getopt (actual_cmd, argc, argv, opts,
  212. &oind, &oarg);
  213. if (opt < 0)
  214. break;
  215. switch ((enum opt) opt)
  216. {
  217. case OPT_TEMP:
  218. temp = 1;
  219. break;
  220. case OPT_DISABLED:
  221. enabled = 0;
  222. break;
  223. }
  224. }
  225. if (oind >= argc)
  226. error (_("-catch-load/unload: Missing <library name>"));
  227. if (oind < argc -1)
  228. error (_("-catch-load/unload: Garbage following the <library name>"));
  229. scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  230. add_solib_catchpoint (argv[oind], load, temp, enabled);
  231. }
  232. /* Handler for the -catch-load. */
  233. void
  234. mi_cmd_catch_load (const char *cmd, char *argv[], int argc)
  235. {
  236. mi_catch_load_unload (1, argv, argc);
  237. }
  238. /* Handler for the -catch-unload. */
  239. void
  240. mi_cmd_catch_unload (const char *cmd, char *argv[], int argc)
  241. {
  242. mi_catch_load_unload (0, argv, argc);
  243. }
  244. /* Core handler for -catch-throw, -catch-rethrow, and -catch-catch
  245. commands. The argument handling for all of these is identical, we just
  246. pass KIND through to GDB's core to select the correct event type. */
  247. static void
  248. mi_cmd_catch_exception_event (enum exception_event_kind kind,
  249. const char *cmd, char *argv[], int argc)
  250. {
  251. char *regex = NULL;
  252. bool temp = false;
  253. int oind = 0;
  254. char *oarg;
  255. enum opt
  256. {
  257. OPT_TEMP,
  258. OPT_REGEX,
  259. };
  260. static const struct mi_opt opts[] =
  261. {
  262. { "t", OPT_TEMP, 0 },
  263. { "r", OPT_REGEX, 1 },
  264. { 0, 0, 0 }
  265. };
  266. for (;;)
  267. {
  268. int opt = mi_getopt (cmd, argc, argv, opts,
  269. &oind, &oarg);
  270. if (opt < 0)
  271. break;
  272. switch ((enum opt) opt)
  273. {
  274. case OPT_TEMP:
  275. temp = true;
  276. break;
  277. case OPT_REGEX:
  278. regex = oarg;
  279. break;
  280. }
  281. }
  282. scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  283. catch_exception_event (kind, regex, temp, 0 /* from_tty */);
  284. }
  285. /* Handler for -catch-throw. */
  286. void
  287. mi_cmd_catch_throw (const char *cmd, char *argv[], int argc)
  288. {
  289. mi_cmd_catch_exception_event (EX_EVENT_THROW, cmd, argv, argc);
  290. }
  291. /* Handler for -catch-rethrow. */
  292. void
  293. mi_cmd_catch_rethrow (const char *cmd, char *argv[], int argc)
  294. {
  295. mi_cmd_catch_exception_event (EX_EVENT_RETHROW, cmd, argv, argc);
  296. }
  297. /* Handler for -catch-catch. */
  298. void
  299. mi_cmd_catch_catch (const char *cmd, char *argv[], int argc)
  300. {
  301. mi_cmd_catch_exception_event (EX_EVENT_CATCH, cmd, argv, argc);
  302. }