-
-
Save MasterDuke17/eb9c88f8c2967139ff2d6b8dd36aa041 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git src/core/exceptions.c src/core/exceptions.c | |
index f5429fbc1..763557886 100644 | |
--- src/core/exceptions.c | |
+++ src/core/exceptions.c | |
@@ -873,7 +873,7 @@ MVM_NO_RETURN void MVM_oops(MVMThreadContext *tc, const char *messageFormat, ... | |
} | |
/* Throws an ad-hoc (untyped) exception. */ | |
-MVM_NO_RETURN void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *messageFormat, ...) { | |
+void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *messageFormat, ...) { | |
va_list args; | |
va_start(args, messageFormat); | |
MVM_exception_throw_adhoc_free_va(tc, NULL, messageFormat, args); | |
@@ -881,13 +881,13 @@ MVM_NO_RETURN void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *m | |
} | |
/* Throws an ad-hoc (untyped) exception. */ | |
-MVM_NO_RETURN void MVM_exception_throw_adhoc_va(MVMThreadContext *tc, const char *messageFormat, va_list args) { | |
+void MVM_exception_throw_adhoc_va(MVMThreadContext *tc, const char *messageFormat, va_list args) { | |
MVM_exception_throw_adhoc_free_va(tc, NULL, messageFormat, args); | |
} | |
/* Throws an ad-hoc (untyped) exception, taking a NULL-terminated array of | |
* char pointers to deallocate after message construction. */ | |
-MVM_NO_RETURN void MVM_exception_throw_adhoc_free(MVMThreadContext *tc, char **waste, const char *messageFormat, ...) { | |
+void MVM_exception_throw_adhoc_free(MVMThreadContext *tc, char **waste, const char *messageFormat, ...) { | |
va_list args; | |
va_start(args, messageFormat); | |
MVM_exception_throw_adhoc_free_va(tc, waste, messageFormat, args); | |
@@ -896,7 +896,7 @@ MVM_NO_RETURN void MVM_exception_throw_adhoc_free(MVMThreadContext *tc, char **w | |
/* Throws an ad-hoc (untyped) exception, taking a NULL-terminated array of | |
* char pointers to deallocate after message construction. */ | |
-MVM_NO_RETURN void MVM_exception_throw_adhoc_free_va(MVMThreadContext *tc, char **waste, const char *messageFormat, va_list args) { | |
+void MVM_exception_throw_adhoc_free_va(MVMThreadContext *tc, char **waste, const char *messageFormat, va_list args) { | |
LocatedHandler lh; | |
MVMException *ex; | |
/* The current frame will be assigned as the thrower of the exception, so | |
@@ -944,11 +944,13 @@ MVM_NO_RETURN void MVM_exception_throw_adhoc_free_va(MVMThreadContext *tc, char | |
vfprintf(stderr, messageFormat, args); | |
fwrite("\n", 1, 1, stderr); | |
MVM_dump_backtrace(tc); | |
- abort(); | |
+ //abort(); | |
+ fprintf(stderr, "exception, would have abort()ed\n"); | |
} | |
else { | |
/* No, just the usual panic. */ | |
- panic_unhandled_ex(tc, ex); | |
+ //panic_unhandled_ex(tc, ex); | |
+ fprintf(stderr, "exception, but chose not to crash\n"); | |
} | |
} | |
@@ -962,7 +964,8 @@ MVM_NO_RETURN void MVM_exception_throw_adhoc_free_va(MVMThreadContext *tc, char | |
MVM_tc_release_ex_release_mutex(tc); | |
/* Jump back into the interpreter. */ | |
- longjmp(tc->interp_jump, 1); | |
+ //longjmp(tc->interp_jump, 1); | |
+ fprintf(stderr, "would have longjmped\n"); | |
} | |
void MVM_crash_on_error(void) { | |
diff --git src/core/exceptions.h src/core/exceptions.h | |
index 210075965..033ec35bd 100644 | |
--- src/core/exceptions.h | |
+++ src/core/exceptions.h | |
@@ -90,10 +90,10 @@ void MVM_exception_resume(MVMThreadContext *tc, MVMObject *exObj); | |
MVM_PUBLIC MVM_NO_RETURN void MVM_panic_allocation_failed(size_t len) MVM_NO_RETURN_ATTRIBUTE; | |
MVM_PUBLIC MVM_NO_RETURN void MVM_panic(MVMint32 exitCode, const char *messageFormat, ...) MVM_NO_RETURN_ATTRIBUTE MVM_FORMAT(printf, 2, 3); | |
MVM_PUBLIC MVM_NO_RETURN void MVM_oops(MVMThreadContext *tc, const char *messageFormat, ...) MVM_NO_RETURN_ATTRIBUTE MVM_FORMAT(printf, 2, 3); | |
-MVM_PUBLIC MVM_NO_RETURN void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *messageFormat, ...) MVM_NO_RETURN_ATTRIBUTE MVM_FORMAT(printf, 2, 3); | |
-MVM_NO_RETURN void MVM_exception_throw_adhoc_va(MVMThreadContext *tc, const char *messageFormat, va_list args) MVM_NO_RETURN_ATTRIBUTE; | |
-MVM_PUBLIC MVM_NO_RETURN void MVM_exception_throw_adhoc_free(MVMThreadContext *tc, char **waste, const char *messageFormat, ...) MVM_NO_RETURN_ATTRIBUTE MVM_FORMAT(printf, 3, 4); | |
-MVM_NO_RETURN void MVM_exception_throw_adhoc_free_va(MVMThreadContext *tc, char **waste, const char *messageFormat, va_list args) MVM_NO_RETURN_ATTRIBUTE; | |
+MVM_PUBLIC void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *messageFormat, ...) MVM_NO_RETURN_ATTRIBUTE MVM_FORMAT(printf, 2, 3); | |
+void MVM_exception_throw_adhoc_va(MVMThreadContext *tc, const char *messageFormat, va_list args) MVM_NO_RETURN_ATTRIBUTE; | |
+MVM_PUBLIC void MVM_exception_throw_adhoc_free(MVMThreadContext *tc, char **waste, const char *messageFormat, ...) MVM_NO_RETURN_ATTRIBUTE MVM_FORMAT(printf, 3, 4); | |
+void MVM_exception_throw_adhoc_free_va(MVMThreadContext *tc, char **waste, const char *messageFormat, va_list args) MVM_NO_RETURN_ATTRIBUTE; | |
MVM_PUBLIC void MVM_crash_on_error(void); | |
char * MVM_exception_backtrace_line(MVMThreadContext *tc, MVMFrame *cur_frame, MVMuint16 not_top, MVMuint8 *throw_address); | |
MVMint32 MVM_get_exception_category(MVMThreadContext *tc, MVMObject *ex); | |
diff --git src/strings/ops.c src/strings/ops.c | |
index 0fa1f8f71..78392e152 100644 | |
--- src/strings/ops.c | |
+++ src/strings/ops.c | |
@@ -206,6 +206,12 @@ static void turn_32bit_into_8bit_unchecked(MVMThreadContext *tc, MVMString *str) | |
dest_buf[i] = old_buf[i]; | |
} | |
+ if (num_graphs > 10) { | |
+ MVM_string_say(tc, str); | |
+ MVM_dump_backtrace(tc); | |
+ MVM_exception_throw_adhoc(tc, "old_buf %d", old_buf[0]); | |
+ } | |
+ | |
MVM_free(old_buf); | |
} | |
/* Checks if the next num_graphs graphemes in the iterator can fit into 8 bits. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import gcc | |
from gccutils import get_src_for_loc, pformat, cfg_to_dot, invoke_dot | |
# We'll implement this as a custom pass, to be called directly after the | |
# builtin "cfg" pass, which generates the CFG: | |
def collect_control_flows(bb, path, seen): | |
if bb.index in seen: | |
seen[bb.index] = 2 | |
else: | |
seen[bb.index] = 1 | |
paths = [] | |
new_path = [bb] | |
new_path.extend(path) | |
if not bb.preds: | |
paths.append(new_path) | |
for edge in bb.preds: | |
pred = edge.src | |
if pred.index in seen and seen[pred.index] > 1: | |
continue | |
paths.extend(collect_control_flows(pred, new_path, seen)) | |
return paths | |
alloc_funcs = {'MVM_malloc', 'MVM_calloc', 'MVM_fixed_size_allocate', 'MVM_fixed_size_allocate_zeroed'} | |
free_funcs = {'MVM_free', 'MVM_fixed_size_free', 'MVM_fixed_size_free_at_safepoint'} | |
def check_code_for_throw_without_free(fun): | |
for bb in fun.cfg.basic_blocks: | |
for ins in bb.gimple: | |
if isinstance(ins, gcc.GimpleReturn): | |
cfs = collect_control_flows(bb, [], {}) | |
for cf in cfs: | |
allocs = set() | |
for bb in cf: | |
for ins in bb.gimple: | |
if isinstance(ins, gcc.GimpleCall): | |
#if isinstance(ins.fn, gcc.AddrExpr): # plain function call is AddrExpr, other things could be function pointers | |
try: | |
print(ins.str_no_uid) | |
if ins.fn.operand.name in alloc_funcs: | |
print("M " + str(ins.lhs)) | |
allocs.add(ins.lhs) | |
if ins.fn.operand.name in free_funcs: | |
print("F " + str(ins.args[0])) | |
if ins.args[0] in allocs: | |
allocs.remove(ins.args[0]) | |
if ins.fn.operand.name == 'MVM_exception_throw_adhoc': | |
print("Exception:!") | |
if allocs: | |
print("Missing free in " + str(fun.decl.name) + " at " + str(cf[-2].gimple[-1].loc) + " " + str(allocs)) | |
except Exception: | |
pass | |
class CheckThrowWithoutFree(gcc.GimplePass): | |
def execute(self, fun): | |
# (the CFG should be set up by this point, and the GIMPLE is not yet | |
# in SSA form) | |
if fun and fun.cfg: | |
#print(fun.decl.name + ':') | |
check_code_for_throw_without_free(fun) | |
ps = CheckThrowWithoutFree(name='check-throw-without-free') | |
ps.register_after('cfg') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment