71 RUBY_FMODE_NOREVLOOKUP = 0x00000100,
74 RUBY_FMODE_PREP = 0x00010000,
76 RUBY_FMODE_UNIX = 0x00200000,
77 RUBY_FMODE_INET = 0x00400000,
78 RUBY_FMODE_INET6 = 0x00800000,
99 if (level < debug_level) {
100 fprintf(stderr,
"%*s", indent_level,
"");
111 va_start(ap, format);
112 vfprintf(stderr, format, ap);
121 if (level < debug_level) {
125 fprintf(stderr,
"DBG> %s: %s\n", header, buff);
140 if (level < debug_level) {
141 fprintf(stderr,
"DBG> %s: %s\n", header,
rb_id2name(
id));
150 if (level < debug_level) {
151 fprintf(stderr,
"DBG> %s: %s (%u)\n", header,
164# if RUBY_MSVCRT_VERSION >= 80
165extern int ruby_w32_rtc_error;
168#if defined _WIN32 || defined __CYGWIN__
170UINT ruby_w32_codepage[2];
181#define SET_WHEN(name, var, val) do { \
182 if (len == sizeof(name) - 1 && \
183 strncmp(str, (name), len) == 0) { \
188#define NAME_MATCH_VALUE(name) \
189 ((size_t)len >= sizeof(name)-1 && \
190 strncmp(str, (name), sizeof(name)-1) == 0 && \
191 ((len == sizeof(name)-1 && !(len = 0)) || \
192 (str[sizeof(name)-1] == '=' && \
193 (str += sizeof(name), len -= sizeof(name), 1))))
194#define SET_UINT(val) do { \
195 n = ruby_scan_digits(str, len, 10, &retlen, &ov); \
196 if (!ov && retlen) { \
197 val = (unsigned int)n; \
202#define SET_UINT_LIST(name, vals, num) do { \
204 for (i = 0; i < (num); ++i) { \
205 SET_UINT((vals)[i]); \
206 if (!len || *str != ':') break; \
211 fprintf(stderr, "ignored "name" option: `%.*s'\n", len, str); \
214#define SET_WHEN_UINT(name, vals, num, req) \
215 if (NAME_MATCH_VALUE(name)) SET_UINT_LIST(name, vals, num);
226# if RUBY_MSVCRT_VERSION >= 80
227 SET_WHEN(
"rtc_error", ruby_w32_rtc_error, 1);
230#if defined _WIN32 || defined __CYGWIN__
232 if (!
len) fprintf(stderr,
"missing codepage argument");
241set_debug_option(
const char *
str,
int len,
void *arg)
244 fprintf(stderr,
"unexpected debug option: %.*s\n",
len,
str);
248#ifdef USE_RUBY_DEBUG_LOG
249STATIC_ASSERT(USE_RUBY_DEBUG_LOG, USE_RUBY_DEBUG_LOG ? RUBY_DEVEL : 1);
255#define setup_debug_log()
270#define MAX_DEBUG_LOG 0x1000
271#define MAX_DEBUG_LOG_MESSAGE_LEN 0x0200
272#define MAX_DEBUG_LOG_FILTER 0x0010
279 char filters[MAX_DEBUG_LOG_FILTER][MAX_DEBUG_LOG_FILTER];
280 unsigned int filters_num;
281 rb_nativethread_lock_t lock;
286RUBY_DEBUG_LOG_MEM_ENTRY(
unsigned int index)
288 return &debug_log.mem[MAX_DEBUG_LOG_MESSAGE_LEN * index];
295 const char *log_config =
getenv(
"RUBY_DEBUG_LOG");
297 fprintf(stderr,
"RUBY_DEBUG_LOG=%s\n", log_config);
299 if (strcmp(log_config,
"mem") == 0) {
300 debug_log.mem = (
char *)
malloc(MAX_DEBUG_LOG * MAX_DEBUG_LOG_MESSAGE_LEN);
301 if (debug_log.mem ==
NULL) {
302 fprintf(stderr,
"setup_debug_log failed (can't allocate memory)\n");
307 else if (strcmp(log_config,
"stderr") == 0) {
312 if ((debug_log.output = fopen(log_config,
"w")) ==
NULL) {
313 fprintf(stderr,
"can not open %s for RUBY_DEBUG_LOG\n", log_config);
316 setvbuf(debug_log.output,
NULL, _IONBF, 0);
323 const char *filter_config =
getenv(
"RUBY_DEBUG_LOG_FILTER");
324 if (filter_config &&
strlen(filter_config) > 0) {
326 for (i=0; i<MAX_DEBUG_LOG_FILTER; i++) {
328 if ((p =
strchr(filter_config,
',')) ==
NULL) {
329 if (
strlen(filter_config) >= MAX_DEBUG_LOG_FILTER) {
330 fprintf(stderr,
"too long: %s (max:%d)\n", filter_config, MAX_DEBUG_LOG_FILTER);
333 strncpy(debug_log.filters[i], filter_config, MAX_DEBUG_LOG_FILTER - 1);
338 size_t n = p - filter_config;
339 if (n >= MAX_DEBUG_LOG_FILTER) {
340 fprintf(stderr,
"too long: %s (max:%d)\n", filter_config, MAX_DEBUG_LOG_FILTER);
343 strncpy(debug_log.filters[i], filter_config, n);
347 debug_log.filters_num = i;
348 for (i=0; i<debug_log.filters_num; i++) {
349 fprintf(stderr,
"RUBY_DEBUG_LOG_FILTER[%d]=%s\n", i, debug_log.filters[i]);
357 if (debug_log.filters_num > 0) {
358 for (
unsigned int i = 0; i<debug_log.filters_num; i++) {
359 if (
strstr(func_name, debug_log.filters[i]) !=
NULL) {
371pretty_filename(
const char *path)
382ruby_debug_log(
const char *
file,
int line,
const char *func_name,
const char *fmt, ...)
384 char buff[MAX_DEBUG_LOG_MESSAGE_LEN] = {0};
389 if (func_name &&
len < MAX_DEBUG_LOG_MESSAGE_LEN) {
390 r =
snprintf(buff +
len, MAX_DEBUG_LOG_MESSAGE_LEN,
"%s\t", func_name);
391 if (r < 0)
rb_bug(
"ruby_debug_log returns %d\n", r);
396 if (fmt &&
len < MAX_DEBUG_LOG_MESSAGE_LEN) {
401 if (r < 0)
rb_bug(
"ruby_debug_log vsnprintf() returns %d", r);
408 if (
file &&
len < MAX_DEBUG_LOG_MESSAGE_LEN) {
409 r =
snprintf(buff +
len, MAX_DEBUG_LOG_MESSAGE_LEN,
"\t%s:%d", pretty_filename(
file), line);
410 if (r < 0)
rb_bug(
"ruby_debug_log returns %d\n", r);
417 if (
len < MAX_DEBUG_LOG_MESSAGE_LEN) {
419 r =
snprintf(buff +
len, MAX_DEBUG_LOG_MESSAGE_LEN -
len,
"\t%s:%d", pretty_filename(ruby_file), ruby_line);
424 if (r < 0)
rb_bug(
"ruby_debug_log returns %d\n", r);
431 if (r &&
len < MAX_DEBUG_LOG_MESSAGE_LEN) {
432 r =
snprintf(buff +
len, MAX_DEBUG_LOG_MESSAGE_LEN -
len,
"\tr:#%u/%u",
433 (
unsigned int)rb_ractor_id(cr), GET_VM()->ractor.cnt);
434 if (r < 0)
rb_bug(
"ruby_debug_log returns %d\n", r);
442 if (r &&
len < MAX_DEBUG_LOG_MESSAGE_LEN) {
443 r =
snprintf(buff +
len, MAX_DEBUG_LOG_MESSAGE_LEN -
len,
"\tth:%p", (
void *)th);
444 if (r < 0)
rb_bug(
"ruby_debug_log returns %d\n", r);
451 unsigned int cnt = debug_log.cnt++;
454 unsigned int index =
cnt % MAX_DEBUG_LOG;
455 char *dst = RUBY_DEBUG_LOG_MEM_ENTRY(index);
456 strncpy(dst, buff, MAX_DEBUG_LOG_MESSAGE_LEN);
459 fprintf(stderr,
"%4u: %s\n",
cnt, buff);
462 fprintf(debug_log.output,
"%u\t%s\n",
cnt, buff);
470debug_log_dump(
FILE *
out,
unsigned int n)
473 unsigned int size = debug_log.cnt > MAX_DEBUG_LOG ? MAX_DEBUG_LOG : debug_log.cnt;
474 unsigned int current_index = debug_log.cnt % MAX_DEBUG_LOG;
475 if (n == 0) n =
size;
478 for (
unsigned int i=0; i<n; i++) {
479 int index = current_index -
size + i;
480 if (index < 0) index += MAX_DEBUG_LOG;
482 const char *mesg = RUBY_DEBUG_LOG_MEM_ENTRY(index);;
483 fprintf(
out,
"%4u: %s\n", debug_log.cnt -
size + i, mesg);
487 fprintf(stderr,
"RUBY_DEBUG_LOG=mem is not specified.");
496 debug_log_dump(stderr, n);
500ruby_debug_log_dump(
const char *fname,
unsigned int n)
502 FILE *fp = fopen(fname,
"w");
504 fprintf(stderr,
"can't open %s. give up.\n", fname);
507 debug_log_dump(fp, n);
int ruby_env_debug_option(const char *str, int len, void *arg)
enum ruby_rstring_flags rstring_flags
enum vm_call_flag_bits vm_call_flags
void ruby_debug_breakpoint(void)
int ruby_debug_print_indent(int level, int debug_level, int indent_level)
#define SET_WHEN(name, var, val)
enum ruby_value_type value_type
#define NAME_MATCH_VALUE(name)
enum ruby_econv_flag_type econv_flag_types
enum ruby_rarray_consts rarray_consts
void ruby_set_debug_option(const char *str)
enum ruby_robject_consts robject_consts
const union @11 ruby_dummy_gdb_enums
enum ruby_special_consts special_consts
enum ruby_robject_flags robject_flags
void ruby_debug_print_v(VALUE v)
enum ruby_rstring_consts rstring_consts
void ruby_debug_printf(const char *format,...)
rb_econv_result_t econv_result
enum ruby_method_ids method_ids
ID ruby_debug_print_id(int level, int debug_level, const char *header, ID id)
enum ruby_tag_type tag_type
enum ruby_coderange_type enc_coderange_types
enum ruby_rarray_flags rarray_flags
VALUE ruby_debug_print_value(int level, int debug_level, const char *header, VALUE obj)
enum ruby_id_types id_types
enum ruby_fl_type fl_types
enum ruby_fl_ushift fl_ushift
#define setup_debug_log()
enum ruby_encoding_consts encoding_consts
const SIGNED_VALUE RUBY_NODE_LMASK
enum ruby_rmodule_flags rmodule_flags
struct RSymbol * symbol_ptr
#define SET_UINT_LIST(name, vals, num)
NODE * ruby_debug_print_node(int level, int debug_level, const char *header, const NODE *node)
char * strchr(char *, char)
char str[HTML_ESCAPE_MAX_LEN+1]
VALUE * ruby_initial_gc_stress_ptr
const char * rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
void rb_bug(const char *fmt,...)
Thin wrapper to ruby/config.h.
int rb_thread_alone(void)
const char * rb_id2name(ID)
#define FMODE_SETENC_BY_BOM
char * strstr(const char *, const char *)
void ruby_each_words(const char *, void(*)(const char *, int, void *), void *)
Internal header for SignalException.
Internal header corresponding util.c.
const char * rb_source_location_cstr(int *pline)
const char * ruby_node_name(int node)
rb_atomic_t cnt[RUBY_NSIG]
ruby_special_consts
special constants - i.e.
size_t strlen(const char *)
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock)
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock)
void rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock)
ruby_value_type
C-level type of an object.
rb_ractor_t * ruby_single_main_ractor
bool ruby_debug_log_filter(const char *func_name)
void ruby_debug_log(const char *file, int line, const char *func_name, const char *fmt,...)
void ruby_debug_log_print(unsigned int n)