Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

Location:
EcnlProtoTool/trunk/mruby-1.3.0
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-1.3.0/src/backtrace.c

    r321 r331  
    55*/
    66
    7 #include "mruby.h"
    8 #include "mruby/variable.h"
    9 #include "mruby/proc.h"
    10 #include "mruby/array.h"
    11 #include "mruby/string.h"
    12 #include "mruby/class.h"
    13 #include "mruby/debug.h"
    14 #include "mruby/error.h"
    15 #include "mruby/numeric.h"
     7#include <mruby.h>
     8#include <mruby/variable.h>
     9#include <mruby/proc.h>
     10#include <mruby/array.h>
     11#include <mruby/string.h>
     12#include <mruby/class.h>
     13#include <mruby/debug.h>
     14#include <mruby/error.h>
     15#include <mruby/numeric.h>
     16#include <mruby/data.h>
    1617
    1718struct backtrace_location {
    18   int i;
    1919  int lineno;
    2020  const char *filename;
    21   const char *method;
    22   const char *sep;
    23   const char *class_name;
     21  mrb_sym method_id;
    2422};
    2523
    26 typedef void (*output_stream_func)(mrb_state*, struct backtrace_location*, void*);
    27 
    28 #ifndef MRB_DISABLE_STDIO
    29 
    30 struct print_backtrace_args {
    31   FILE *stream;
    32   int tracehead;
    33 };
    34 
    35 static void
    36 print_backtrace_i(mrb_state *mrb, struct backtrace_location *loc, void *data)
    37 {
    38   struct print_backtrace_args *args;
    39 
    40   args = (struct print_backtrace_args*)data;
    41 
    42   if (args->tracehead) {
    43     fprintf(args->stream, "trace:\n");
    44     args->tracehead = FALSE;
    45   }
    46 
    47   fprintf(args->stream, "\t[%d] %s:%d", loc->i, loc->filename, loc->lineno);
    48 
    49   if (loc->method) {
    50     if (loc->class_name) {
    51       fprintf(args->stream, ":in %s%s%s", loc->class_name, loc->sep, loc->method);
    52     }
    53     else {
    54       fprintf(args->stream, ":in %s", loc->method);
    55     }
    56   }
    57 
    58   fprintf(args->stream, "\n");
    59 }
    60 
    61 #endif
    62 
    63 static void
    64 get_backtrace_i(mrb_state *mrb, struct backtrace_location *loc, void *data)
    65 {
    66   mrb_value ary, str;
    67   int ai;
    68 
    69   ai = mrb_gc_arena_save(mrb);
    70   ary = mrb_obj_value((struct RArray*)data);
    71 
    72   str = mrb_str_new_cstr(mrb, loc->filename);
    73   mrb_str_cat_lit(mrb, str, ":");
    74   mrb_str_concat(mrb, str, mrb_fixnum_to_str(mrb, mrb_fixnum_value(loc->lineno), 10));
    75 
    76   if (loc->method) {
    77     mrb_str_cat_lit(mrb, str, ":in ");
    78 
    79     if (loc->class_name) {
    80       mrb_str_cat_cstr(mrb, str, loc->class_name);
    81       mrb_str_cat_cstr(mrb, str, loc->sep);
    82     }
    83 
    84     mrb_str_cat_cstr(mrb, str, loc->method);
    85   }
    86 
    87   mrb_ary_push(mrb, ary, str);
    88   mrb_gc_arena_restore(mrb, ai);
    89 }
    90 
    91 static void
    92 output_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, output_stream_func func, void *data)
    93 {
    94   int i;
     24typedef void (*each_backtrace_func)(mrb_state*, int i, struct backtrace_location*, void*);
     25
     26static const mrb_data_type bt_type = { "Backtrace", mrb_free };
     27
     28static void
     29each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func func, void *data)
     30{
     31  int i, j;
    9532
    9633  if (ciidx >= mrb->c->ciend - mrb->c->cibase)
    9734    ciidx = 10; /* ciidx is broken... */
    9835
    99   for (i = ciidx; i >= 0; i--) {
     36  for (i=ciidx, j=0; i >= 0; i--,j++) {
    10037    struct backtrace_location loc;
    10138    mrb_callinfo *ci;
     
    10946
    11047    irep = ci->proc->body.irep;
     48    if (!irep) continue;
    11149
    11250    if (mrb->c->cibase[i].err) {
     
    12462    if (loc.lineno == -1) continue;
    12563
    126     if (ci->target_class == ci->proc->target_class) {
    127       loc.sep = ".";
    128     }
    129     else {
    130       loc.sep = "#";
    131     }
    132 
    13364    if (!loc.filename) {
    13465      loc.filename = "(unknown)";
    13566    }
    13667
    137     loc.method = mrb_sym2name(mrb, ci->mid);
    138     loc.class_name = mrb_class_name(mrb, ci->proc->target_class);
    139     loc.i = i;
    140     func(mrb, &loc, data);
    141   }
    142 }
    143 
    144 static void
    145 exc_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream)
    146 {
    147   mrb_value lastpc;
    148   mrb_code *code;
    149 
    150   lastpc = mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "lastpc"));
    151   if (mrb_nil_p(lastpc)) {
    152     code = NULL;
    153   } else {
    154     code = (mrb_code*)mrb_cptr(lastpc);
    155   }
    156 
    157   output_backtrace(mrb, mrb_fixnum(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "ciidx"))),
    158                    code, func, stream);
    159 }
    160 
    161 /* mrb_print_backtrace/mrb_get_backtrace:
    162 
    163    function to retrieve backtrace information from the exception.
    164    note that if you call method after the exception, call stack will be
    165    overwritten.  So invoke these functions just after detecting exceptions.
     68    loc.method_id = ci->mid;
     69    func(mrb, j, &loc, data);
     70  }
     71}
     72
     73#ifndef MRB_DISABLE_STDIO
     74
     75static void
     76print_backtrace(mrb_state *mrb, mrb_value backtrace)
     77{
     78  int i, n;
     79  FILE *stream = stderr;
     80
     81  if (!mrb_array_p(backtrace)) return;
     82  fprintf(stream, "trace:\n");
     83
     84  n = RARRAY_LEN(backtrace);
     85  for (i=0; n--; i++) {
     86    mrb_value entry = RARRAY_PTR(backtrace)[n];
     87
     88    if (mrb_string_p(entry)) {
     89      fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry));
     90    }
     91  }
     92}
     93
     94static void
     95print_packed_backtrace(mrb_state *mrb, mrb_value packed)
     96{
     97  FILE *stream = stderr;
     98  struct backtrace_location *bt;
     99  int n, i;
     100
     101  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type);
     102  if (bt == NULL) {
     103    mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
     104  }
     105  n = (mrb_int)RDATA(packed)->flags;
     106
     107  fprintf(stream, "trace:\n");
     108  for (i = 0; n--; i++) {
     109    int ai = mrb_gc_arena_save(mrb);
     110    struct backtrace_location *entry = &bt[n];
     111    if (entry->filename == NULL) continue;
     112    fprintf(stream, "\t[%d] %s:%d", (int)i, entry->filename, entry->lineno);
     113    if (entry->method_id != 0) {
     114      const char *method_name;
     115
     116      method_name = mrb_sym2name(mrb, entry->method_id);
     117      fprintf(stream, ":in %s", method_name);
     118      mrb_gc_arena_restore(mrb, ai);
     119    }
     120    fprintf(stream, "\n");
     121  }
     122}
     123
     124/* mrb_print_backtrace
     125
     126   function to retrieve backtrace information from the last exception.
    166127*/
    167 
    168 #ifndef MRB_DISABLE_STDIO
    169128
    170129MRB_API void
    171130mrb_print_backtrace(mrb_state *mrb)
    172131{
    173   struct print_backtrace_args args;
    174 
    175   if (!mrb->exc || mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), E_SYSSTACK_ERROR)) {
     132  mrb_value backtrace;
     133
     134  if (!mrb->exc) {
    176135    return;
    177136  }
    178137
    179   args.stream = stderr;
    180   args.tracehead = TRUE;
    181   exc_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)&args);
    182 }
    183 
     138  backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
     139  if (mrb_nil_p(backtrace)) return;
     140  if (mrb_array_p(backtrace)) {
     141    print_backtrace(mrb, backtrace);
     142  }
     143  else {
     144    print_packed_backtrace(mrb, backtrace);
     145  }
     146}
    184147#else
    185148
     
    191154#endif
    192155
     156static void
     157pack_backtrace_i(mrb_state *mrb,
     158                 int i,
     159                 struct backtrace_location *loc,
     160                 void *data)
     161{
     162  struct backtrace_location *entry = (struct backtrace_location*)data;
     163
     164  entry[i] = *loc;
     165}
     166
     167static mrb_value
     168packed_backtrace(mrb_state *mrb)
     169{
     170  struct RData *backtrace;
     171  ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase;
     172  mrb_int len = (ciidx+1)*sizeof(struct backtrace_location);
     173  void *ptr;
     174
     175  ptr = mrb_malloc(mrb, len);
     176  memset(ptr, 0, len);
     177  backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
     178  backtrace->flags = (unsigned int)ciidx+1;
     179  each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, ptr);
     180  return mrb_obj_value(backtrace);
     181}
     182
     183void
     184mrb_keep_backtrace(mrb_state *mrb, mrb_value exc)
     185{
     186  mrb_value backtrace;
     187  int ai = mrb_gc_arena_save(mrb);
     188
     189  backtrace = packed_backtrace(mrb);
     190  mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);
     191  mrb_gc_arena_restore(mrb, ai);
     192}
     193
     194mrb_value
     195mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
     196{
     197  struct backtrace_location *bt;
     198  mrb_int n, i;
     199
     200  if (mrb_nil_p(backtrace)) return mrb_ary_new_capa(mrb, 0);
     201  if (mrb_array_p(backtrace)) return backtrace;
     202  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type);
     203  if (bt == NULL) {
     204    mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
     205  }
     206  n = (mrb_int)RDATA(backtrace)->flags;
     207  backtrace = mrb_ary_new_capa(mrb, n);
     208  for (i = 0; i < n; i++) {
     209    int ai = mrb_gc_arena_save(mrb);
     210    struct backtrace_location *entry = &bt[i];
     211    mrb_value btline;
     212
     213    if (entry->filename == NULL) continue;
     214    btline = mrb_format(mrb, "%S:%S",
     215                              mrb_str_new_cstr(mrb, entry->filename),
     216                              mrb_fixnum_value(entry->lineno));
     217    if (entry->method_id != 0) {
     218      mrb_str_cat_lit(mrb, btline, ":in ");
     219      mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id));
     220    }
     221    mrb_ary_push(mrb, backtrace, btline);
     222    mrb_gc_arena_restore(mrb, ai);
     223  }
     224
     225  return backtrace;
     226}
     227
    193228MRB_API mrb_value
    194 mrb_exc_backtrace(mrb_state *mrb, mrb_value self)
    195 {
    196   mrb_value ary;
    197 
    198   ary = mrb_ary_new(mrb);
    199   exc_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary));
    200 
    201   return ary;
     229mrb_exc_backtrace(mrb_state *mrb, mrb_value exc)
     230{
     231  mrb_sym attr_name;
     232  mrb_value backtrace;
     233
     234  attr_name = mrb_intern_lit(mrb, "backtrace");
     235  backtrace = mrb_iv_get(mrb, exc, attr_name);
     236  if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) {
     237    return backtrace;
     238  }
     239  backtrace = mrb_unpack_backtrace(mrb, backtrace);
     240  mrb_iv_set(mrb, exc, attr_name, backtrace);
     241  return backtrace;
    202242}
    203243
     
    205245mrb_get_backtrace(mrb_state *mrb)
    206246{
    207   mrb_value ary;
    208   mrb_callinfo *ci = mrb->c->ci;
    209   mrb_code *pc = ci->pc;
    210   mrb_int ciidx = (mrb_int)(ci - mrb->c->cibase - 1);
    211 
    212   if (ciidx < 0) ciidx = 0;
    213   ary = mrb_ary_new(mrb);
    214   output_backtrace(mrb, ciidx, pc, get_backtrace_i, (void*)mrb_ary_ptr(ary));
    215 
    216   return ary;
    217 }
     247  return mrb_unpack_backtrace(mrb, packed_backtrace(mrb));
     248}
Note: See TracChangeset for help on using the changeset viewer.