[macruby-changes] [4546] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Sep 27 22:47:48 PDT 2010
Revision: 4546
http://trac.macosforge.org/projects/ruby/changeset/4546
Author: lsansonetti at apple.com
Date: 2010-09-27 22:47:47 -0700 (Mon, 27 Sep 2010)
Log Message:
-----------
add backtracing support for interpreted dispatch calls + cleanup useless code
Modified Paths:
--------------
MacRuby/trunk/dispatcher.cpp
MacRuby/trunk/interpreter.cpp
MacRuby/trunk/interpreter.h
MacRuby/trunk/objc.h
MacRuby/trunk/objc.m
MacRuby/trunk/vm.cpp
MacRuby/trunk/vm.h
Modified: MacRuby/trunk/dispatcher.cpp
===================================================================
--- MacRuby/trunk/dispatcher.cpp 2010-09-27 23:05:30 UTC (rev 4545)
+++ MacRuby/trunk/dispatcher.cpp 2010-09-28 05:47:47 UTC (rev 4546)
@@ -821,8 +821,8 @@
char *method_name = (char *)sel_getName(sel);
char file[PATH_MAX];
unsigned long line = 0;
- GET_CORE()->symbolize_backtrace_entry(1, NULL, file, sizeof file,
- &line, NULL, 0);
+ GET_CORE()->symbolize_backtrace_entry(1, file, sizeof file, &line,
+ NULL, 0);
MACRUBY_METHOD_ENTRY(class_name, method_name, file, line);
}
@@ -835,8 +835,8 @@
char *method_name = (char *)sel_getName(sel);
char file[PATH_MAX];
unsigned long line = 0;
- GET_CORE()->symbolize_backtrace_entry(1, NULL, file, sizeof file,
- &line, NULL, 0);
+ GET_CORE()->symbolize_backtrace_entry(1, file, sizeof file, &line,
+ NULL, 0);
MACRUBY_METHOD_RETURN(class_name, method_name, file, line);
}
Modified: MacRuby/trunk/interpreter.cpp
===================================================================
--- MacRuby/trunk/interpreter.cpp 2010-09-27 23:05:30 UTC (rev 4545)
+++ MacRuby/trunk/interpreter.cpp 2010-09-28 05:47:47 UTC (rev 4546)
@@ -82,6 +82,35 @@
int argc = value_as(call_arg(call, 5), int);
VALUE *argv = value_as(call_arg(call, 6), VALUE *);
+ MDNode *node = call->getMetadata(RoxorCompiler::shared->dbg_mdkind);
+ if (node != NULL) {
+ DILocation loc(node);
+ std::string path;
+ path.append(loc.getDirectory());
+ path.append("/");
+ path.append(loc.getFilename());
+
+ Frame frame;
+ frame.name = (const char *)sel;
+ frame.path = path;
+ frame.line = loc.getLineNumber();
+ frames.push_back(frame);
+ }
+
+ struct Finally {
+ RoxorInterpreter *ir;
+ bool pop;
+ Finally(RoxorInterpreter *_ir, bool _pop) {
+ ir = _ir;
+ pop = _pop;
+ }
+ ~Finally() {
+ if (pop) {
+ ir->frames.pop_back();
+ }
+ }
+ } finalizer(this, node != NULL);
+
return vm_dispatch(top, self, sel, block, opt, argc, argv);
}
else if (called == RoxorCompiler::shared->singletonClassFunc) {
@@ -93,6 +122,27 @@
oops("unrecognized call instruction:", call);
}
+bool
+RoxorInterpreter::frame_at_index(unsigned int idx, void *addr,
+ std::string *name, std::string *path, unsigned int *line)
+{
+ if ((uintptr_t)addr < (uintptr_t)(void *)&vm_dispatch
+ || (uintptr_t)addr > (uintptr_t)(void *)&vm_dispatch + 5000) {
+ // Likely not an interpreted dispatch call.
+ return false;
+ }
+ if (idx >= frames.size()) {
+ // Not enough frames!
+ return false;
+ }
+
+ Frame &frame = frames[idx];
+ *name = frame.name;
+ *path = frame.path;
+ *line = frame.line;
+ return true;
+}
+
#define return_if_cached(__insn) \
std::map<Instruction *, VALUE>::iterator __i = insns.find(__insn); \
if (__i != insns.end()) { \
Modified: MacRuby/trunk/interpreter.h
===================================================================
--- MacRuby/trunk/interpreter.h 2010-09-27 23:05:30 UTC (rev 4545)
+++ MacRuby/trunk/interpreter.h 2010-09-28 05:47:47 UTC (rev 4546)
@@ -22,6 +22,9 @@
VALUE interpret(Function *func, VALUE self, SEL sel);
+ bool frame_at_index(unsigned int idx, void *addr, std::string *name,
+ std::string *path, unsigned int *line);
+
private:
VALUE self_arg;
SEL sel_arg;
@@ -29,6 +32,13 @@
unsigned int stack_p;
#define INTERPRETER_STACK_SIZE 1000
std::map<Instruction *, VALUE> insns;
+ class Frame {
+ public:
+ std::string name;
+ std::string path;
+ unsigned int line;
+ };
+ std::vector<Frame> frames;
VALUE interpret_basicblock(BasicBlock *bb);
VALUE interpret_instruction(Instruction *insn);
Modified: MacRuby/trunk/objc.h
===================================================================
--- MacRuby/trunk/objc.h 2010-09-27 23:05:30 UTC (rev 4545)
+++ MacRuby/trunk/objc.h 2010-09-28 05:47:47 UTC (rev 4546)
@@ -73,9 +73,6 @@
return false;
}
-bool rb_objc_symbolize_address(void *addr, void **start, char *name,
- size_t name_len);
-
id rb_rb2oc_exception(VALUE exc);
VALUE rb_oc2rb_exception(id exc, bool *created);
Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m 2010-09-27 23:05:30 UTC (rev 4545)
+++ MacRuby/trunk/objc.m 2010-09-28 05:47:47 UTC (rev 4546)
@@ -109,26 +109,6 @@
return false;
}
-bool
-rb_objc_symbolize_address(void *addr, void **start, char *name,
- size_t name_len)
-{
- Dl_info info;
- if (dladdr(addr, &info) != 0) {
- if (info.dli_saddr != NULL) {
- if (start != NULL) {
- *start = info.dli_saddr;
- }
- if (name != NULL) {
- strncpy(name, info.dli_sname, name_len);
- }
- return true;
- }
- }
-
- return false;
-}
-
VALUE
rb_home_dir(VALUE user_name)
{
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2010-09-27 23:05:30 UTC (rev 4545)
+++ MacRuby/trunk/vm.cpp 2010-09-28 05:47:47 UTC (rev 4546)
@@ -651,14 +651,13 @@
void
rb_symbolicate(void *addr)
{
- void *start = NULL;
char path[1000];
char name[100];
unsigned long ln = 0;
- if (GET_CORE()->symbolize_call_address(addr, &start, path, sizeof path,
- &ln, name, sizeof name)) {
- printf("addr %p start %p selector %s location %s:%ld\n",
- addr, start, name, path, ln);
+ if (GET_CORE()->symbolize_call_address(addr, path, sizeof path,
+ &ln, name, sizeof name, NULL)) {
+ printf("addr %p selector %s location %s:%ld\n",
+ addr, name, path, ln);
}
else {
printf("addr %p unknown\n", addr);
@@ -666,8 +665,9 @@
}
bool
-RoxorCore::symbolize_call_address(void *addr, void **startp, char *path,
- size_t path_len, unsigned long *ln, char *name, size_t name_len)
+RoxorCore::symbolize_call_address(void *addr, char *path, size_t path_len,
+ unsigned long *ln, char *name, size_t name_len,
+ unsigned int *interpreter_frame_idx)
{
#if MACRUBY_STATIC
return false;
@@ -676,25 +676,34 @@
return false;
}
- void *start = NULL;
RoxorFunction *f = jmm->find_function((unsigned char *)addr);
if (f != NULL) {
if (f->imp == NULL) {
f->imp = ee->getPointerToFunctionOrStub(f->f);
}
- start = f->imp;
}
else {
- if (!rb_objc_symbolize_address(addr, &start, NULL, 0)) {
+ std::string fr_name;
+ std::string fr_path;
+ unsigned int fr_line = 0;
+ if (interpreter_frame_idx == NULL
+ || !RoxorInterpreter::shared->frame_at_index(*interpreter_frame_idx,
+ addr, &fr_name, &fr_path, &fr_line)) {
return false;
}
+ (*interpreter_frame_idx)++;
+ if (name != NULL) {
+ strlcpy(name, fr_name.c_str(), name_len);
+ }
+ if (path != NULL) {
+ strlcpy(path, fr_path.c_str(), path_len);
+ }
+ if (ln != NULL) {
+ *ln = fr_line;
+ }
+ return true;
}
- assert(start != NULL);
- if (startp != NULL) {
- *startp = start;
- }
-
if (f != NULL) {
if (ln != NULL) {
*ln = 0;
@@ -711,7 +720,7 @@
}
if (name != NULL) {
std::map<IMP, rb_vm_method_node_t *>::iterator iter =
- ruby_imps.find((IMP)start);
+ ruby_imps.find((IMP)f->imp);
if (iter == ruby_imps.end()) {
strncpy(name, "block", name_len);
}
@@ -737,8 +746,8 @@
}
void
-RoxorCore::symbolize_backtrace_entry(int index, void **startp, char *path,
- size_t path_len, unsigned long *ln, char *name, size_t name_len)
+RoxorCore::symbolize_backtrace_entry(int index, char *path, size_t path_len,
+ unsigned long *ln, char *name, size_t name_len)
{
void *callstack[10];
const int callstack_n = backtrace(callstack, 10);
@@ -746,8 +755,8 @@
index++; // count us!
if (callstack_n < index
- || !GET_CORE()->symbolize_call_address(callstack[index], startp,
- path, path_len, ln, name, name_len)) {
+ || !GET_CORE()->symbolize_call_address(callstack[index], path,
+ path_len, ln, name, name_len, NULL)) {
if (path != NULL) {
strncpy(path, "core", path_len);
}
@@ -3330,8 +3339,8 @@
char *classname = (char *)rb_class2name(CLASS_OF(rb_exc));
char file[PATH_MAX];
unsigned long line = 0;
- GET_CORE()->symbolize_backtrace_entry(2, NULL, file, sizeof file,
- &line, NULL, 0);
+ GET_CORE()->symbolize_backtrace_entry(2, file, sizeof file, &line,
+ NULL, 0);
MACRUBY_RAISE(classname, file, line);
}
#if __LP64__
@@ -3583,6 +3592,8 @@
VALUE ary = rb_ary_new();
+ unsigned int interpreter_frame_idx = 0;
+
for (int i = 0; i < callstack_n; i++) {
char path[PATH_MAX];
char name[100];
@@ -3590,8 +3601,8 @@
path[0] = name[0] = '\0';
- if (GET_CORE()->symbolize_call_address(callstack[i], NULL,
- path, sizeof path, &ln, name, sizeof name)
+ if (GET_CORE()->symbolize_call_address(callstack[i], path, sizeof path,
+ &ln, name, sizeof name, &interpreter_frame_idx)
&& name[0] != '\0' && path[0] != '\0') {
char entry[PATH_MAX];
if (ln == 0) {
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2010-09-27 23:05:30 UTC (rev 4545)
+++ MacRuby/trunk/vm.h 2010-09-28 05:47:47 UTC (rev 4546)
@@ -848,13 +848,12 @@
}
#endif
- bool symbolize_call_address(void *addr, void **startp,
- char *path, size_t path_len, unsigned long *ln,
- char *name, size_t name_len);
+ bool symbolize_call_address(void *addr, char *path, size_t path_len,
+ unsigned long *ln, char *name, size_t name_len,
+ unsigned int *interpreter_frame_idx);
- void symbolize_backtrace_entry(int index, void **startp,
- char *path, size_t path_len, unsigned long *ln,
- char *name, size_t name_len);
+ void symbolize_backtrace_entry(int index, char *path, size_t path_len,
+ unsigned long *ln, char *name, size_t name_len);
void invalidate_method_cache(SEL sel);
rb_vm_method_node_t *method_node_get(IMP imp, bool create=false);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100927/0b0c22c0/attachment-0001.html>
More information about the macruby-changes
mailing list