Commit 06ffe979 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add a bunch of misc debugging helpers

parent d4df5d7e
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
# This module should be kept compatible with Python 2.2, see PEP 291. # This module should be kept compatible with Python 2.2, see PEP 291.
from __future__ import generators from __future__ import generators
# Pyston change:
import sys
del sys.modules['modulefinder']
raise ImportError("This isn't really supported in Pyston yet")
import dis import dis
import imp import imp
import marshal import marshal
......
...@@ -64,7 +64,7 @@ union Value { ...@@ -64,7 +64,7 @@ union Value {
Value(double d) : d(d) {} Value(double d) : d(d) {}
Value(Box* o) : o(o) { Value(Box* o) : o(o) {
if (DEBUG >= 2) if (DEBUG >= 2)
assert(gc::isValidGCObject(o)); ASSERT(gc::isValidGCObject(o), "%p", o);
} }
}; };
...@@ -532,8 +532,15 @@ Value ASTInterpreter::visit_jump(AST_Jump* node) { ...@@ -532,8 +532,15 @@ Value ASTInterpreter::visit_jump(AST_Jump* node) {
CompiledFunction* partial_func = compilePartialFuncInternal(&exit); CompiledFunction* partial_func = compilePartialFuncInternal(&exit);
auto arg_tuple = getTupleFromArgsArray(&arg_array[0], arg_array.size()); auto arg_tuple = getTupleFromArgsArray(&arg_array[0], arg_array.size());
return partial_func->call(std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple), Box* r = partial_func->call(std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple),
std::get<3>(arg_tuple)); std::get<3>(arg_tuple));
// This is one of the few times that we are allowed to have an invalid value in a Box* Value.
// Check for it, and return as an int so that we don't trigger a potential assert when
// creating the Value.
if (compiled_func->getReturnType() != VOID)
assert(r);
return (intptr_t)r;
} }
} }
......
...@@ -985,7 +985,9 @@ AST_Module* parse_file(const char* fn) { ...@@ -985,7 +985,9 @@ AST_Module* parse_file(const char* fn) {
Timer _t("parsing"); Timer _t("parsing");
if (ENABLE_PYPA_PARSER) { if (ENABLE_PYPA_PARSER) {
return pypa_parse(fn); AST_Module* rtn = pypa_parse(fn);
assert(rtn);
return rtn;
} }
FILE* fp = popen(getParserCommandLine(fn).c_str(), "r"); FILE* fp = popen(getParserCommandLine(fn).c_str(), "r");
......
...@@ -699,7 +699,7 @@ FrameStackState getFrameStackState() { ...@@ -699,7 +699,7 @@ FrameStackState getFrameStackState() {
Box* v = e.type->deserializeFromFrame(vals); Box* v = e.type->deserializeFromFrame(vals);
// printf("%s: (pp id %ld) %p\n", p.first.c_str(), e._debug_pp_id, v); // printf("%s: (pp id %ld) %p\n", p.first.c_str(), e._debug_pp_id, v);
assert(gc::isValidGCObject(v)); ASSERT(gc::isValidGCObject(v), "%p", v);
d->d[boxString(p.first)] = v; d->d[boxString(p.first)] = v;
} }
} }
......
...@@ -82,7 +82,10 @@ static int main(int argc, char** argv) { ...@@ -82,7 +82,10 @@ static int main(int argc, char** argv) {
bool stats = false; bool stats = false;
bool unbuffered = false; bool unbuffered = false;
const char* command = NULL; const char* command = NULL;
while ((code = getopt(argc, argv, "+OqdIibpjtrsSvnxc:FuP")) != -1) {
// Suppress getopt errors so we can throw them ourselves
opterr = 0;
while ((code = getopt(argc, argv, "+:OqdIibpjtrsSvnxc:FuP")) != -1) {
if (code == 'O') if (code == 'O')
FORCE_OPTIMIZE = true; FORCE_OPTIMIZE = true;
else if (code == 't') else if (code == 't')
...@@ -120,11 +123,24 @@ static int main(int argc, char** argv) { ...@@ -120,11 +123,24 @@ static int main(int argc, char** argv) {
} else if (code == 'F') { } else if (code == 'F') {
CONTINUE_AFTER_FATAL = true; CONTINUE_AFTER_FATAL = true;
} else if (code == 'c') { } else if (code == 'c') {
assert(optarg);
command = optarg; command = optarg;
// no more option parsing; the rest of our arguments go into sys.argv. // no more option parsing; the rest of our arguments go into sys.argv.
break; break;
} else } else {
if (code == ':') {
fprintf(stderr, "Argument expected for the -%c option\n", optopt);
return 2;
}
if (code == '?') {
fprintf(stderr, "Unknown option: -%c\n", optopt);
return 2;
}
fprintf(stderr, "Unknown getopt() error. '%c' '%c'\n", code, optopt);
abort(); abort();
}
} }
const char* fn = NULL; const char* fn = NULL;
......
...@@ -1579,7 +1579,6 @@ Box* getattrInternalGeneric(Box* obj, const std::string& attr, GetattrRewriteArg ...@@ -1579,7 +1579,6 @@ Box* getattrInternalGeneric(Box* obj, const std::string& attr, GetattrRewriteArg
return getattrInternalEx(static_cast<BoxedInstanceMethod*>(obj)->func, attr, NULL, cls_only, for_call, return getattrInternalEx(static_cast<BoxedInstanceMethod*>(obj)->func, attr, NULL, cls_only, for_call,
bind_obj_out, NULL); bind_obj_out, NULL);
} }
// Finally, check __getattr__
if (rewrite_args) { if (rewrite_args) {
rewrite_args->out_success = true; rewrite_args->out_success = true;
...@@ -2160,7 +2159,7 @@ extern "C" i64 unboxedLen(Box* obj) { ...@@ -2160,7 +2159,7 @@ extern "C" i64 unboxedLen(Box* obj) {
return rtn; return rtn;
} }
extern "C" void dump(void* p) { extern "C" void dumpEx(void* p, int levels) {
printf("\n"); printf("\n");
printf("Raw address: %p\n", p); printf("Raw address: %p\n", p);
...@@ -2233,7 +2232,32 @@ extern "C" void dump(void* p) { ...@@ -2233,7 +2232,32 @@ extern "C" void dump(void* p) {
} }
if (isSubclass(b->cls, tuple_cls)) { if (isSubclass(b->cls, tuple_cls)) {
printf("%ld elements\n", static_cast<BoxedTuple*>(b)->size()); BoxedTuple* t = static_cast<BoxedTuple*>(b);
printf("%ld elements\n", t->size());
if (levels > 0) {
int i = 0;
for (auto e : *t) {
printf("\nElement %d:", i);
i++;
dumpEx(e, levels - 1);
}
}
}
if (isSubclass(b->cls, dict_cls)) {
BoxedDict* d = static_cast<BoxedDict*>(b);
printf("%ld elements\n", d->d.size());
if (levels > 0) {
int i = 0;
for (auto t : d->d) {
printf("\nKey:");
dumpEx(t.first, levels - 1);
printf("Value:");
dumpEx(t.second, levels - 1);
}
}
} }
if (isSubclass(b->cls, int_cls)) { if (isSubclass(b->cls, int_cls)) {
...@@ -2269,6 +2293,10 @@ extern "C" void dump(void* p) { ...@@ -2269,6 +2293,10 @@ extern "C" void dump(void* p) {
RELEASE_ASSERT(0, "%d", (int)al->kind_id); RELEASE_ASSERT(0, "%d", (int)al->kind_id);
} }
extern "C" void dump(void* p) {
dumpEx(p, 0);
}
// For rewriting purposes, this function assumes that nargs will be constant. // For rewriting purposes, this function assumes that nargs will be constant.
// That's probably fine for some uses (ex binops), but otherwise it should be guarded on beforehand. // That's probably fine for some uses (ex binops), but otherwise it should be guarded on beforehand.
extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope scope, CallRewriteArgs* rewrite_args, extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope scope, CallRewriteArgs* rewrite_args,
...@@ -2441,7 +2469,7 @@ extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope ...@@ -2441,7 +2469,7 @@ extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope
extern "C" Box* callattr(Box* obj, const std::string* attr, CallattrFlags flags, ArgPassSpec argspec, Box* arg1, extern "C" Box* callattr(Box* obj, const std::string* attr, CallattrFlags flags, ArgPassSpec argspec, Box* arg1,
Box* arg2, Box* arg3, Box** args, const std::vector<const std::string*>* keyword_names) { Box* arg2, Box* arg3, Box** args, const std::vector<const std::string*>* keyword_names) {
assert(gc::isValidGCObject(obj)); ASSERT(gc::isValidGCObject(obj), "%p", obj);
int npassed_args = argspec.totalPassed(); int npassed_args = argspec.totalPassed();
......
...@@ -94,6 +94,7 @@ extern "C" Box* createBoxedIterWrapperIfNeeded(Box* o); ...@@ -94,6 +94,7 @@ extern "C" Box* createBoxedIterWrapperIfNeeded(Box* o);
extern "C" bool hasnext(Box* o); extern "C" bool hasnext(Box* o);
extern "C" void dump(void* p); extern "C" void dump(void* p);
extern "C" void dumpEx(void* p, int levels = 0);
struct SetattrRewriteArgs; struct SetattrRewriteArgs;
void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args); void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args);
......
...@@ -159,7 +159,8 @@ extern "C" void abort() { ...@@ -159,7 +159,8 @@ extern "C" void abort() {
// In case something calls abort down the line: // In case something calls abort down the line:
static bool recursive = false; static bool recursive = false;
if (!recursive) { // If object_cls is NULL, then we somehow died early on, and won't be able to display a traceback.
if (!recursive && object_cls) {
recursive = true; recursive = true;
fprintf(stderr, "Someone called abort!\n"); fprintf(stderr, "Someone called abort!\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment