Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Last active May 20, 2020 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasterDuke17/eb9c88f8c2967139ff2d6b8dd36aa041 to your computer and use it in GitHub Desktop.
Save MasterDuke17/eb9c88f8c2967139ff2d6b8dd36aa041 to your computer and use it in GitHub Desktop.
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.
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')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment