[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