mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Add ability to take heap snapshots with python debugger
Signed-off-by: Ádám László Kulcsár <adam.kulcsar@szteszoftver.hu>
This commit is contained in:
parent
ad3844437e
commit
769e86e32a
6 changed files with 39 additions and 14 deletions
|
|
@ -1002,7 +1002,23 @@ bool DebuggerEscargot::processEvents(ExecutionState* state, Optional<ByteCodeBlo
|
|||
}
|
||||
case ESCARGOT_DEBUGGER_TAKE_HEAP_SNAPSHOT: {
|
||||
HeapSnapshot snapshot;
|
||||
snapshot.takeHeapSnapshot(state);
|
||||
std::string fileName = snapshot.takeHeapSnapshot(state);
|
||||
|
||||
if (fileName.empty()) {
|
||||
ESCARGOT_LOG_ERROR("Error happened during heap snapshot creation. Aborting now.\n");
|
||||
abort();
|
||||
} else if (enabled()) {
|
||||
String* data = String::fromUTF8(fileName.c_str(), fileName.length());
|
||||
|
||||
if (data == nullptr) {
|
||||
ESCARGOT_LOG_ERROR("Error happened during heap snapshot creation. Aborting now.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
send(ESCARGOT_DEBUGGER_SNAPSHOT_FINISHED,
|
||||
data->characters8(),
|
||||
data->length());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ public:
|
|||
ESCARGOT_MESSAGE_EXCEPTION_BACKTRACE = 46,
|
||||
ESCARGOT_DEBUGGER_WAIT_FOR_SOURCE = 47,
|
||||
ESCARGOT_DEBUGGER_WAITING_AFTER_PENDING = 48,
|
||||
ESCARGOT_DEBUGGER_WAIT_FOR_WAIT_EXIT = 49
|
||||
ESCARGOT_DEBUGGER_WAIT_FOR_WAIT_EXIT = 49,
|
||||
ESCARGOT_DEBUGGER_SNAPSHOT_FINISHED = 50
|
||||
};
|
||||
|
||||
// Messages sent by the debugger client to Escargot
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ void HeapSnapshot::addNotIndexedDeclarativeEnvironmentRecord(ExecutionState* sta
|
|||
}
|
||||
}
|
||||
|
||||
bool HeapSnapshot::prepareHeapSnapshotFile()
|
||||
std::string HeapSnapshot::prepareHeapSnapshotFile()
|
||||
{
|
||||
auto addFields = [](rapidjson::Value& array, Vector<std::string, GCUtil::gc_malloc_allocator<std::string>>& strings, rapidjson::Document::AllocatorType& allocator) {
|
||||
for (const std::string& elem : strings) {
|
||||
|
|
@ -431,7 +431,7 @@ bool HeapSnapshot::prepareHeapSnapshotFile()
|
|||
|
||||
if (output.get() == nullptr) {
|
||||
ESCARGOT_LOG_ERROR("Could not create heap snapshot file.\n");
|
||||
return false;
|
||||
return "";
|
||||
}
|
||||
|
||||
char buffer[65536];
|
||||
|
|
@ -439,11 +439,10 @@ bool HeapSnapshot::prepareHeapSnapshotFile()
|
|||
rapidjson::Writer<rapidjson::FileWriteStream> writer(os);
|
||||
jsonDoc.Accept(writer);
|
||||
|
||||
return true;
|
||||
return outputName;
|
||||
}
|
||||
|
||||
|
||||
void HeapSnapshot::takeHeapSnapshot(ExecutionState* state)
|
||||
std::string HeapSnapshot::takeHeapSnapshot(ExecutionState* state)
|
||||
{
|
||||
uint64_t id = 0;
|
||||
uint64_t stateIdx = 0;
|
||||
|
|
@ -524,10 +523,7 @@ void HeapSnapshot::takeHeapSnapshot(ExecutionState* state)
|
|||
}
|
||||
|
||||
ESCARGOT_LOG_INFO("nodes: %ld | edges: %ld | strings: %ld", m_nodeCount, m_edgeCount, m_strings.size());
|
||||
if (prepareHeapSnapshotFile() != true) {
|
||||
ESCARGOT_LOG_ERROR("Error happened during heap snapshot creation. Aborting now.\n");
|
||||
abort();
|
||||
}
|
||||
return prepareHeapSnapshotFile();
|
||||
}
|
||||
} // namespace Escargot
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@ public:
|
|||
void addIndexedDeclarativeEnvironmentRecord(ExecutionState* state, DeclarativeEnvironmentRecordIndexed* env, uint64_t& id, uint64_t& LexicalEnvIdx);
|
||||
void addNotIndexedDeclarativeEnvironmentRecord(ExecutionState* state, DeclarativeEnvironmentRecordNotIndexed* env, uint64_t& id, uint64_t& LexicalEnvIdx);
|
||||
|
||||
bool prepareHeapSnapshotFile();
|
||||
void takeHeapSnapshot(ExecutionState* state);
|
||||
std::string prepareHeapSnapshotFile();
|
||||
std::string takeHeapSnapshot(ExecutionState* state);
|
||||
|
||||
private:
|
||||
uint64_t m_nodeCount;
|
||||
|
|
|
|||
|
|
@ -197,6 +197,12 @@ class DebuggerPrompt(Cmd):
|
|||
self.stop = True
|
||||
do_bt = do_backtrace
|
||||
|
||||
def do_take_snapshot(self, args):
|
||||
""" Save heap snapshot to a .snapshot file in the escargot binary's folder """
|
||||
file_name = self.debugger._send_take_snapshot()
|
||||
print("Took heap snapshot as \'" + file_name.decode('utf-8')[1:] + "\'!")
|
||||
self.stop = True
|
||||
|
||||
def do_scope(self, args):
|
||||
""" Get lexical environment chain """
|
||||
self.debugger.scope_chain(args)
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ ESCARGOT_DEBUGGER_THERE_WAS_NO_SOURCE = 26
|
|||
ESCARGOT_DEBUGGER_PENDING_CONFIG = 27
|
||||
ESCARGOT_DEBUGGER_PENDING_RESUME = 28
|
||||
ESCARGOT_DEBUGGER_WAIT_BEFORE_EXIT = 29
|
||||
ESCARGOT_DEBUGGER_STOP = 30
|
||||
ESCARGOT_DEBUGGER_TAKE_HEAP_SNAPSHOT = 30
|
||||
ESCARGOT_DEBUGGER_STOP = 31
|
||||
|
||||
|
||||
# Environment record types
|
||||
|
|
@ -626,6 +627,11 @@ class Debugger(object):
|
|||
1 if self.wait_exit else 0)
|
||||
self.channel.send_message(self.byte_order, message)
|
||||
|
||||
def _send_take_snapshot(self):
|
||||
message = struct.pack(self.byte_order + "BB", 1, ESCARGOT_DEBUGGER_TAKE_HEAP_SNAPSHOT)
|
||||
self.channel.send_message(self.byte_order, message)
|
||||
return self.channel.get_message(True)
|
||||
|
||||
def _exec_command(self, command_id):
|
||||
message = struct.pack(self.byte_order + "BB",
|
||||
1,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue