gdbint.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /* GDB interface for Guile
  2. * Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2, or (at your option)
  7. * any later version.
  8. *
  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. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this software; see the file COPYING. If not, write to
  16. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  17. * Boston, MA 02111-1307 USA
  18. *
  19. * As a special exception, the Free Software Foundation gives permission
  20. * for additional uses of the text contained in its release of GUILE.
  21. *
  22. * The exception is that, if you link the GUILE library with other files
  23. * to produce an executable, this does not by itself cause the
  24. * resulting executable to be covered by the GNU General Public License.
  25. * Your use of that executable is in no way restricted on account of
  26. * linking the GUILE library code into it.
  27. *
  28. * This exception does not however invalidate any other reasons why
  29. * the executable file might be covered by the GNU General Public License.
  30. *
  31. * This exception applies only to the code released by the
  32. * Free Software Foundation under the name GUILE. If you copy
  33. * code from other Free Software Foundation releases into a copy of
  34. * GUILE, as the General Public License permits, the exception does
  35. * not apply to the code that you add in this way. To avoid misleading
  36. * anyone as to the status of such modified files, you must delete
  37. * this exception notice from them.
  38. *
  39. * If you write modifications of your own for GUILE, it is your choice
  40. * whether to permit this exception to apply to your modifications.
  41. * If you do not wish that, delete this exception notice.
  42. *
  43. * The author can be reached at djurfeldt@nada.kth.se
  44. * Mikael Djurfeldt, SANS/NADA KTH, 10044 STOCKHOLM, SWEDEN */
  45. #include "libguile/_scm.h"
  46. #include <stdio.h>
  47. #ifdef HAVE_UNISTD_H
  48. #include <unistd.h>
  49. #endif
  50. #include "libguile/tag.h"
  51. #include "libguile/strports.h"
  52. #include "libguile/read.h"
  53. #include "libguile/eval.h"
  54. #include "libguile/chars.h"
  55. #include "libguile/modules.h"
  56. #include "libguile/ports.h"
  57. #include "libguile/root.h"
  58. #include "libguile/strings.h"
  59. #include "libguile/init.h"
  60. #include "libguile/gdbint.h"
  61. /* {Support for debugging with gdb}
  62. *
  63. * TODO:
  64. *
  65. * 1. Redirect outputs
  66. * 2. Catch errors
  67. * 3. Prevent print from causing segmentation fault when given broken pairs
  68. */
  69. #define GDB_TYPE SCM
  70. #include "libguile/gdb_interface.h"
  71. /* Be carefull when this macro is true.
  72. scm_gc_heap_lock is set during gc.
  73. */
  74. #define SCM_GC_P (scm_gc_heap_lock)
  75. /* Macros that encapsulate blocks of code which can be called by the
  76. * debugger.
  77. */
  78. #define SCM_BEGIN_FOREIGN_BLOCK \
  79. do { \
  80. old_ints = scm_ints_disabled; scm_ints_disabled = 1; \
  81. old_gc = scm_block_gc; scm_block_gc = 1; \
  82. scm_print_carefully_p = 1; \
  83. } while (0)
  84. #define SCM_END_FOREIGN_BLOCK \
  85. do { \
  86. scm_print_carefully_p = 0; \
  87. scm_block_gc = old_gc; \
  88. scm_ints_disabled = old_ints; \
  89. } while (0)
  90. #define MSG_GUILE_NOT_INITIALIZED "*** Guile not initialized ***"
  91. #define RESET_STRING { gdb_output_length = 0; }
  92. #define SEND_STRING(str) \
  93. do { \
  94. gdb_output = (char *) (str); \
  95. gdb_output_length = strlen ((const char *) (str)); \
  96. } while (0)
  97. /* {Gdb interface}
  98. */
  99. unsigned short gdb_options = GDB_HAVE_BINDINGS;
  100. char *gdb_language = "lisp/c";
  101. SCM gdb_result;
  102. char *gdb_output;
  103. int gdb_output_length;
  104. int scm_print_carefully_p;
  105. static SCM gdb_input_port;
  106. static int port_mark_p, stream_mark_p, string_mark_p;
  107. static SCM tok_buf;
  108. static int tok_buf_mark_p;
  109. static SCM gdb_output_port;
  110. static int old_ints, old_gc;
  111. static void
  112. unmark_port (SCM port)
  113. {
  114. SCM stream, string;
  115. port_mark_p = SCM_GC8MARKP (port);
  116. SCM_CLRGC8MARK (port);
  117. stream = SCM_PACK (SCM_STREAM (port));
  118. stream_mark_p = SCM_GCMARKP (stream);
  119. SCM_CLRGCMARK (stream);
  120. string = SCM_CDR (stream);
  121. string_mark_p = SCM_GC8MARKP (string);
  122. SCM_CLRGC8MARK (string);
  123. }
  124. static void
  125. remark_port (SCM port)
  126. {
  127. SCM stream = SCM_PACK (SCM_STREAM (port));
  128. SCM string = SCM_CDR (stream);
  129. if (string_mark_p) SCM_SETGC8MARK (string);
  130. if (stream_mark_p) SCM_SETGCMARK (stream);
  131. if (port_mark_p) SCM_SETGC8MARK (port);
  132. }
  133. int
  134. gdb_maybe_valid_type_p (SCM value)
  135. {
  136. return SCM_IMP (value) || scm_cellp (value);
  137. }
  138. int
  139. gdb_read (char *str)
  140. {
  141. SCM ans;
  142. int status = 0;
  143. RESET_STRING;
  144. /* Need to be restrictive about what to read? */
  145. if (SCM_GC_P)
  146. {
  147. char *p;
  148. for (p = str; *p != '\0'; ++p)
  149. switch (*p)
  150. {
  151. case '(':
  152. case '\'':
  153. case '"':
  154. SEND_STRING ("Can't read this kind of expressions during gc");
  155. return -1;
  156. case '#':
  157. if (*++p == '\0')
  158. goto premature;
  159. if (*p == '\\')
  160. {
  161. if (*++p != '\0')
  162. continue;
  163. premature:
  164. SEND_STRING ("Premature end of lisp expression");
  165. return -1;
  166. }
  167. default:
  168. continue;
  169. }
  170. }
  171. SCM_BEGIN_FOREIGN_BLOCK;
  172. unmark_port (gdb_input_port);
  173. scm_seek (gdb_input_port, SCM_INUM0, SCM_MAKINUM (SEEK_SET));
  174. scm_puts (str, gdb_input_port);
  175. scm_truncate_file (gdb_input_port, SCM_UNDEFINED);
  176. scm_seek (gdb_input_port, SCM_INUM0, SCM_MAKINUM (SEEK_SET));
  177. /* Read one object */
  178. tok_buf_mark_p = SCM_GC8MARKP (tok_buf);
  179. SCM_CLRGC8MARK (tok_buf);
  180. ans = scm_lreadr (&tok_buf, gdb_input_port, &ans);
  181. if (SCM_GC_P)
  182. {
  183. if (SCM_NIMP (ans))
  184. {
  185. SEND_STRING ("Non-immediate created during gc. Memory may be trashed.");
  186. status = -1;
  187. goto exit;
  188. }
  189. }
  190. gdb_result = ans;
  191. /* Protect answer from future GC */
  192. if (SCM_NIMP (ans))
  193. scm_permanent_object (ans);
  194. exit:
  195. if (tok_buf_mark_p)
  196. SCM_SETGC8MARK (tok_buf);
  197. remark_port (gdb_input_port);
  198. SCM_END_FOREIGN_BLOCK;
  199. return status;
  200. }
  201. int
  202. gdb_eval (SCM exp)
  203. {
  204. RESET_STRING;
  205. if (SCM_IMP (exp))
  206. {
  207. gdb_result = exp;
  208. return 0;
  209. }
  210. if (SCM_GC_P)
  211. {
  212. SEND_STRING ("Can't evaluate lisp expressions during gc");
  213. return -1;
  214. }
  215. SCM_BEGIN_FOREIGN_BLOCK;
  216. {
  217. SCM env = scm_top_level_env (SCM_CDR (scm_top_level_lookup_closure_var));
  218. gdb_result = scm_permanent_object (scm_ceval (exp, env));
  219. }
  220. SCM_END_FOREIGN_BLOCK;
  221. return 0;
  222. }
  223. int
  224. gdb_print (SCM obj)
  225. {
  226. if (!scm_initialized_p)
  227. SEND_STRING ("*** Guile not initialized ***");
  228. else
  229. {
  230. RESET_STRING;
  231. SCM_BEGIN_FOREIGN_BLOCK;
  232. /* Reset stream */
  233. scm_seek (gdb_output_port, SCM_INUM0, SCM_MAKINUM (SEEK_SET));
  234. scm_write (obj, gdb_output_port);
  235. scm_truncate_file (gdb_output_port, SCM_UNDEFINED);
  236. {
  237. scm_port *pt = SCM_PTAB_ENTRY (gdb_output_port);
  238. scm_flush (gdb_output_port);
  239. *(pt->write_buf + pt->read_buf_size) = 0;
  240. SEND_STRING (pt->read_buf);
  241. }
  242. SCM_END_FOREIGN_BLOCK;
  243. }
  244. return 0;
  245. }
  246. int
  247. gdb_binding (SCM name, SCM value)
  248. {
  249. RESET_STRING;
  250. if (SCM_GC_P)
  251. {
  252. SEND_STRING ("Can't create new bindings during gc");
  253. return -1;
  254. }
  255. SCM_BEGIN_FOREIGN_BLOCK;
  256. {
  257. SCM vcell = scm_sym2vcell (name,
  258. SCM_CDR (scm_top_level_lookup_closure_var),
  259. SCM_BOOL_T);
  260. SCM_SETCDR (vcell, value);
  261. }
  262. SCM_END_FOREIGN_BLOCK;
  263. return 0;
  264. }
  265. void
  266. scm_init_gdbint ()
  267. {
  268. static char *s = "scm_init_gdb_interface";
  269. SCM port;
  270. scm_print_carefully_p = 0;
  271. port = scm_mkstrport (SCM_INUM0,
  272. scm_make_string (SCM_MAKINUM (0), SCM_UNDEFINED),
  273. SCM_OPN | SCM_WRTNG,
  274. s);
  275. gdb_output_port = scm_permanent_object (port);
  276. port = scm_mkstrport (SCM_INUM0,
  277. scm_make_string (SCM_MAKINUM (0), SCM_UNDEFINED),
  278. SCM_OPN | SCM_RDNG | SCM_WRTNG,
  279. s);
  280. gdb_input_port = scm_permanent_object (port);
  281. tok_buf = scm_permanent_object (scm_makstr (30L, 0));
  282. }
  283. /*
  284. Local Variables:
  285. c-file-style: "gnu"
  286. End:
  287. */