Commit 2c814183 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Filter out undefined variables from locals()

You can imagine what happens if the variable is undefined and we
try to return it.
parent e8746068
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "codegen/irgen/hooks.h" #include "codegen/irgen/hooks.h"
#include "codegen/stackmaps.h" #include "codegen/stackmaps.h"
#include "core/util.h"
#include "runtime/types.h" #include "runtime/types.h"
...@@ -526,10 +527,37 @@ BoxedDict* getLocals(bool only_user_visible) { ...@@ -526,10 +527,37 @@ BoxedDict* getLocals(bool only_user_visible) {
unsigned offset = ip - cf->code_start; unsigned offset = ip - cf->code_start;
assert(cf->location_map); assert(cf->location_map);
// We have to detect + ignore any entries for variables that
// could have been defined (so they have entries) but aren't (so the
// entries point to uninitialized memory).
std::unordered_set<std::string> is_undefined;
for (const auto& p : cf->location_map->names) {
if (!startswith(p.first, "!is_defined_"))
continue;
for (const LocationMap::LocationTable::LocationEntry& e : p.second.locations) {
if (e.offset < offset && offset <= e.offset + e.length) {
const auto& locs = e.locations;
assert(locs.size() == 1);
uint64_t v = frame_info.readLocation(locs[0]);
if ((v & 1) == 0)
is_undefined.insert(p.first.substr(12));
break;
}
}
}
for (const auto& p : cf->location_map->names) { for (const auto& p : cf->location_map->names) {
if (only_user_visible && (p.first[0] == '#' || p.first[0] == '!')) if (only_user_visible && (p.first[0] == '#' || p.first[0] == '!'))
continue; continue;
if (is_undefined.count(p.first))
continue;
for (const LocationMap::LocationTable::LocationEntry& e : p.second.locations) { for (const LocationMap::LocationTable::LocationEntry& e : p.second.locations) {
if (e.offset < offset && offset <= e.offset + e.length) { if (e.offset < offset && offset <= e.offset + e.length) {
const auto& locs = e.locations; const auto& locs = e.locations;
...@@ -552,9 +580,8 @@ BoxedDict* getLocals(bool only_user_visible) { ...@@ -552,9 +580,8 @@ BoxedDict* getLocals(bool only_user_visible) {
return d; return d;
} else if (frame_info.getId().type == PythonFrameId::INTERPRETED) { } else if (frame_info.getId().type == PythonFrameId::INTERPRETED) {
return localsForInterpretedFrame((void*)frame_info.getId().bp, only_user_visible); return localsForInterpretedFrame((void*)frame_info.getId().bp, only_user_visible);
} else {
abort();
} }
abort();
} }
RELEASE_ASSERT(0, "Internal error: unable to find any python frames"); RELEASE_ASSERT(0, "Internal error: unable to find any python frames");
} }
......
...@@ -31,11 +31,12 @@ def f3(): ...@@ -31,11 +31,12 @@ def f3():
print sorted(locals().items()) print sorted(locals().items())
f3() f3()
def f4(): def f4(t):
"""testing synthetic 'is_defined' variables""" """testing synthetic 'is_defined' variables"""
if 0: if t:
x = 1 x = 1
else: else:
y = 2 y = 2
print sorted(locals().items()) print sorted(locals().items())
# f4() f4(0)
f4(1)
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