1 /**********************************************************************
6 created at: 04/08/25 02:31:54 JST
8 Copyright (C) 2004-2007 Koichi Sasada
10 **********************************************************************/
12 #include "ruby/internal/config.h"
16 #include "eval_intern.h"
19 #include "internal/signal.h"
20 #include "ruby/encoding.h"
22 #include "ruby/ruby.h"
23 #include "ruby/util.h"
27 #include "vm_callinfo.h"
28 #include "ruby/thread_native.h"
29 #include "ractor_core.h"
31 /* This is the only place struct RIMemo is actually used */
42 enum ruby_special_consts special_consts
;
43 enum ruby_value_type value_type
;
44 enum ruby_tag_type tag_type
;
45 enum node_type node_type
;
46 enum ruby_method_ids method_ids
;
47 enum ruby_id_types id_types
;
48 enum ruby_fl_type fl_types
;
49 enum ruby_fl_ushift fl_ushift
;
50 enum ruby_encoding_consts encoding_consts
;
51 enum ruby_coderange_type enc_coderange_types
;
52 enum ruby_econv_flag_type econv_flag_types
;
53 rb_econv_result_t econv_result
;
54 enum ruby_preserved_encindex encoding_index
;
55 enum ruby_robject_flags robject_flags
;
56 enum ruby_robject_consts robject_consts
;
57 enum ruby_rmodule_flags rmodule_flags
;
58 enum ruby_rstring_flags rstring_flags
;
60 enum ruby_rstring_consts rstring_consts
;
62 enum ruby_rarray_flags rarray_flags
;
63 enum ruby_rarray_consts rarray_consts
;
65 RUBY_FMODE_READABLE
= FMODE_READABLE
,
66 RUBY_FMODE_WRITABLE
= FMODE_WRITABLE
,
67 RUBY_FMODE_READWRITE
= FMODE_READWRITE
,
68 RUBY_FMODE_BINMODE
= FMODE_BINMODE
,
69 RUBY_FMODE_SYNC
= FMODE_SYNC
,
70 RUBY_FMODE_TTY
= FMODE_TTY
,
71 RUBY_FMODE_DUPLEX
= FMODE_DUPLEX
,
72 RUBY_FMODE_APPEND
= FMODE_APPEND
,
73 RUBY_FMODE_CREATE
= FMODE_CREATE
,
74 RUBY_FMODE_NOREVLOOKUP
= 0x00000100,
75 RUBY_FMODE_TRUNC
= FMODE_TRUNC
,
76 RUBY_FMODE_TEXTMODE
= FMODE_TEXTMODE
,
77 RUBY_FMODE_PREP
= 0x00010000,
78 RUBY_FMODE_SETENC_BY_BOM
= FMODE_SETENC_BY_BOM
,
79 RUBY_FMODE_UNIX
= 0x00200000,
80 RUBY_FMODE_INET
= 0x00400000,
81 RUBY_FMODE_INET6
= 0x00800000,
83 RUBY_NODE_TYPESHIFT
= NODE_TYPESHIFT
,
84 RUBY_NODE_TYPEMASK
= NODE_TYPEMASK
,
85 RUBY_NODE_LSHIFT
= NODE_LSHIFT
,
86 RUBY_NODE_FL_NEWLINE
= NODE_FL_NEWLINE
89 enum imemo_type types
;
90 enum {RUBY_IMEMO_MASK
= IMEMO_MASK
} mask
;
93 struct RSymbol
*symbol_ptr
;
94 enum vm_call_flag_bits vm_call_flags
;
95 } ruby_dummy_gdb_enums
;
97 const SIGNED_VALUE RUBY_NODE_LMASK
= NODE_LMASK
;
100 ruby_debug_print_indent(int level
, int debug_level
, int indent_level
)
102 if (level
< debug_level
) {
103 fprintf(stderr
, "%*s", indent_level
, "");
111 ruby_debug_printf(const char *format
, ...)
114 va_start(ap
, format
);
115 vfprintf(stderr
, format
, ap
);
122 ruby_debug_print_value(int level
, int debug_level
, const char *header
, VALUE obj
)
124 if (level
< debug_level
) {
126 rb_raw_obj_info(buff
, 0x100, obj
);
128 fprintf(stderr
, "DBG> %s: %s\n", header
, buff
);
135 ruby_debug_print_v(VALUE v
)
137 ruby_debug_print_value(0, 1, "", v
);
141 ruby_debug_print_id(int level
, int debug_level
, const char *header
, ID id
)
143 if (level
< debug_level
) {
144 fprintf(stderr
, "DBG> %s: %s\n", header
, rb_id2name(id
));
151 ruby_debug_print_node(int level
, int debug_level
, const char *header
, const NODE
*node
)
153 if (level
< debug_level
) {
154 fprintf(stderr
, "DBG> %s: %s (%u)\n", header
,
155 ruby_node_name(nd_type(node
)), nd_line(node
));
161 ruby_debug_breakpoint(void)
167 # if RUBY_MSVCRT_VERSION >= 80
168 extern int ruby_w32_rtc_error
;
171 #if defined _WIN32 || defined __CYGWIN__
173 UINT ruby_w32_codepage
[2];
175 extern int ruby_rgengc_debug
;
176 extern int ruby_on_ci
;
179 ruby_env_debug_option(const char *str
, int len
, void *arg
)
184 #define SET_WHEN(name, var, val) do { \
185 if (len == sizeof(name) - 1 && \
186 strncmp(str, (name), len) == 0) { \
191 #define NAME_MATCH_VALUE(name) \
192 ((size_t)len >= sizeof(name)-1 && \
193 strncmp(str, (name), sizeof(name)-1) == 0 && \
194 ((len == sizeof(name)-1 && !(len = 0)) || \
195 (str[sizeof(name)-1] == '=' && \
196 (str += sizeof(name), len -= sizeof(name), 1))))
197 #define SET_UINT(val) do { \
198 n = ruby_scan_digits(str, len, 10, &retlen, &ov); \
199 if (!ov && retlen) { \
200 val = (unsigned int)n; \
205 #define SET_UINT_LIST(name, vals, num) do { \
207 for (i = 0; i < (num); ++i) { \
208 SET_UINT((vals)[i]); \
209 if (!len || *str != ':') break; \
214 fprintf(stderr, "ignored "name" option: `%.*s'\n", len, str); \
217 #define SET_WHEN_UINT(name, vals, num, req) \
218 if (NAME_MATCH_VALUE(name)) SET_UINT_LIST(name, vals, num);
220 SET_WHEN("gc_stress", *ruby_initial_gc_stress_ptr
, Qtrue
);
221 SET_WHEN("core", ruby_enable_coredump
, 1);
222 SET_WHEN("ci", ruby_on_ci
, 1);
223 if (NAME_MATCH_VALUE("rgengc")) {
224 if (!len
) ruby_rgengc_debug
= 1;
225 else SET_UINT_LIST("rgengc", &ruby_rgengc_debug
, 1);
229 # if RUBY_MSVCRT_VERSION >= 80
230 SET_WHEN("rtc_error", ruby_w32_rtc_error
, 1);
233 #if defined _WIN32 || defined __CYGWIN__
234 if (NAME_MATCH_VALUE("codepage")) {
235 if (!len
) fprintf(stderr
, "missing codepage argument");
236 else SET_UINT_LIST("codepage", ruby_w32_codepage
, numberof(ruby_w32_codepage
));
244 set_debug_option(const char *str
, int len
, void *arg
)
246 if (!ruby_env_debug_option(str
, len
, arg
)) {
247 fprintf(stderr
, "unexpected debug option: %.*s\n", len
, str
);
251 #ifdef USE_RUBY_DEBUG_LOG
252 STATIC_ASSERT(USE_RUBY_DEBUG_LOG
, USE_RUBY_DEBUG_LOG
? RUBY_DEVEL
: 1);
256 static void setup_debug_log(void);
258 #define setup_debug_log()
262 ruby_set_debug_option(const char *str
)
264 ruby_each_words(str
, set_debug_option
, 0);
270 // RUBY_DEBUG_LOG features
271 // See vm_debug.h comments for details.
273 #define MAX_DEBUG_LOG 0x1000
274 #define MAX_DEBUG_LOG_MESSAGE_LEN 0x0200
275 #define MAX_DEBUG_LOG_FILTER 0x0010
277 enum ruby_debug_log_mode ruby_debug_log_mode
;
282 char filters
[MAX_DEBUG_LOG_FILTER
][MAX_DEBUG_LOG_FILTER
];
283 unsigned int filters_num
;
284 rb_nativethread_lock_t lock
;
289 RUBY_DEBUG_LOG_MEM_ENTRY(unsigned int index
)
291 return &debug_log
.mem
[MAX_DEBUG_LOG_MESSAGE_LEN
* index
];
295 setup_debug_log(void)
297 // check RUBY_DEBUG_LOG
298 const char *log_config
= getenv("RUBY_DEBUG_LOG");
300 fprintf(stderr
, "RUBY_DEBUG_LOG=%s\n", log_config
);
302 if (strcmp(log_config
, "mem") == 0) {
303 debug_log
.mem
= (char *)malloc(MAX_DEBUG_LOG
* MAX_DEBUG_LOG_MESSAGE_LEN
);
304 if (debug_log
.mem
== NULL
) {
305 fprintf(stderr
, "setup_debug_log failed (can't allocate memory)\n");
308 ruby_debug_log_mode
|= ruby_debug_log_memory
;
310 else if (strcmp(log_config
, "stderr") == 0) {
311 ruby_debug_log_mode
|= ruby_debug_log_stderr
;
314 ruby_debug_log_mode
|= ruby_debug_log_file
;
315 if ((debug_log
.output
= fopen(log_config
, "w")) == NULL
) {
316 fprintf(stderr
, "can not open %s for RUBY_DEBUG_LOG\n", log_config
);
319 setvbuf(debug_log
.output
, NULL
, _IONBF
, 0);
322 rb_nativethread_lock_initialize(&debug_log
.lock
);
325 // check RUBY_DEBUG_LOG_FILTER
326 const char *filter_config
= getenv("RUBY_DEBUG_LOG_FILTER");
327 if (filter_config
&& strlen(filter_config
) > 0) {
329 for (i
=0; i
<MAX_DEBUG_LOG_FILTER
; i
++) {
331 if ((p
= strchr(filter_config
, ',')) == NULL
) {
332 if (strlen(filter_config
) >= MAX_DEBUG_LOG_FILTER
) {
333 fprintf(stderr
, "too long: %s (max:%d)\n", filter_config
, MAX_DEBUG_LOG_FILTER
);
336 strncpy(debug_log
.filters
[i
], filter_config
, MAX_DEBUG_LOG_FILTER
- 1);
341 size_t n
= p
- filter_config
;
342 if (n
>= MAX_DEBUG_LOG_FILTER
) {
343 fprintf(stderr
, "too long: %s (max:%d)\n", filter_config
, MAX_DEBUG_LOG_FILTER
);
346 strncpy(debug_log
.filters
[i
], filter_config
, n
);
350 debug_log
.filters_num
= i
;
351 for (i
=0; i
<debug_log
.filters_num
; i
++) {
352 fprintf(stderr
, "RUBY_DEBUG_LOG_FILTER[%d]=%s\n", i
, debug_log
.filters
[i
]);
358 ruby_debug_log_filter(const char *func_name
)
360 if (debug_log
.filters_num
> 0) {
361 for (unsigned int i
= 0; i
<debug_log
.filters_num
; i
++) {
362 if (strstr(func_name
, debug_log
.filters
[i
]) != NULL
) {
374 pretty_filename(const char *path
)
376 // basename is one idea.
378 while ((s
= strchr(path
, '/')) != NULL
) {
385 ruby_debug_log(const char *file
, int line
, const char *func_name
, const char *fmt
, ...)
387 char buff
[MAX_DEBUG_LOG_MESSAGE_LEN
] = {0};
392 if (func_name
&& len
< MAX_DEBUG_LOG_MESSAGE_LEN
) {
393 r
= snprintf(buff
+ len
, MAX_DEBUG_LOG_MESSAGE_LEN
, "%s\t", func_name
);
394 if (r
< 0) rb_bug("ruby_debug_log returns %d\n", r
);
399 if (fmt
&& len
< MAX_DEBUG_LOG_MESSAGE_LEN
) {
402 r
= vsnprintf(buff
+ len
, MAX_DEBUG_LOG_MESSAGE_LEN
- len
, fmt
, args
);
404 if (r
< 0) rb_bug("ruby_debug_log vsnprintf() returns %d", r
);
408 // optional information
411 if (file
&& len
< MAX_DEBUG_LOG_MESSAGE_LEN
) {
412 r
= snprintf(buff
+ len
, MAX_DEBUG_LOG_MESSAGE_LEN
, "\t%s:%d", pretty_filename(file
), line
);
413 if (r
< 0) rb_bug("ruby_debug_log returns %d\n", r
);
419 const char *ruby_file
= rb_source_location_cstr(&ruby_line
);
420 if (len
< MAX_DEBUG_LOG_MESSAGE_LEN
) {
422 r
= snprintf(buff
+ len
, MAX_DEBUG_LOG_MESSAGE_LEN
- len
, "\t%s:%d", pretty_filename(ruby_file
), ruby_line
);
425 r
= snprintf(buff
+ len
, MAX_DEBUG_LOG_MESSAGE_LEN
- len
, "\t");
427 if (r
< 0) rb_bug("ruby_debug_log returns %d\n", r
);
431 // ractor information
432 if (ruby_single_main_ractor
== NULL
) {
433 rb_ractor_t
*cr
= GET_RACTOR();
434 if (r
&& len
< MAX_DEBUG_LOG_MESSAGE_LEN
) {
435 r
= snprintf(buff
+ len
, MAX_DEBUG_LOG_MESSAGE_LEN
- len
, "\tr:#%u/%u",
436 (unsigned int)rb_ractor_id(cr
), GET_VM()->ractor
.cnt
);
437 if (r
< 0) rb_bug("ruby_debug_log returns %d\n", r
);
442 // thread information
443 if (!rb_thread_alone()) {
444 const rb_thread_t
*th
= GET_THREAD();
445 if (r
&& len
< MAX_DEBUG_LOG_MESSAGE_LEN
) {
446 r
= snprintf(buff
+ len
, MAX_DEBUG_LOG_MESSAGE_LEN
- len
, "\tth:%p", (void *)th
);
447 if (r
< 0) rb_bug("ruby_debug_log returns %d\n", r
);
452 rb_nativethread_lock_lock(&debug_log
.lock
);
454 unsigned int cnt
= debug_log
.cnt
++;
456 if (ruby_debug_log_mode
& ruby_debug_log_memory
) {
457 unsigned int index
= cnt
% MAX_DEBUG_LOG
;
458 char *dst
= RUBY_DEBUG_LOG_MEM_ENTRY(index
);
459 strncpy(dst
, buff
, MAX_DEBUG_LOG_MESSAGE_LEN
);
461 if (ruby_debug_log_mode
& ruby_debug_log_stderr
) {
462 fprintf(stderr
, "%4u: %s\n", cnt
, buff
);
464 if (ruby_debug_log_mode
& ruby_debug_log_file
) {
465 fprintf(debug_log
.output
, "%u\t%s\n", cnt
, buff
);
468 rb_nativethread_lock_unlock(&debug_log
.lock
);
473 debug_log_dump(FILE *out
, unsigned int n
)
475 if (ruby_debug_log_mode
& ruby_debug_log_memory
) {
476 unsigned int size
= debug_log
.cnt
> MAX_DEBUG_LOG
? MAX_DEBUG_LOG
: debug_log
.cnt
;
477 unsigned int current_index
= debug_log
.cnt
% MAX_DEBUG_LOG
;
478 if (n
== 0) n
= size
;
479 if (n
> size
) n
= size
;
481 for (unsigned int i
=0; i
<n
; i
++) {
482 int index
= current_index
- size
+ i
;
483 if (index
< 0) index
+= MAX_DEBUG_LOG
;
484 VM_ASSERT(index
<= MAX_DEBUG_LOG
);
485 const char *mesg
= RUBY_DEBUG_LOG_MEM_ENTRY(index
);;
486 fprintf(out
, "%4u: %s\n", debug_log
.cnt
- size
+ i
, mesg
);
490 fprintf(stderr
, "RUBY_DEBUG_LOG=mem is not specified.");
497 ruby_debug_log_print(unsigned int n
)
499 debug_log_dump(stderr
, n
);
503 ruby_debug_log_dump(const char *fname
, unsigned int n
)
505 FILE *fp
= fopen(fname
, "w");
507 fprintf(stderr
, "can't open %s. give up.\n", fname
);
510 debug_log_dump(fp
, n
);
514 #endif // #if RUBY_DEVEL