Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: print builtins and unnamed stack frames #104

Merged
merged 4 commits into from
Jun 29, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 42 additions & 22 deletions src/llnode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,20 @@

namespace llnode {

using namespace lldb;
using lldb::SBCommandInterpreter;
using lldb::SBCommandReturnObject;
using lldb::SBDebugger;
using lldb::SBError;
using lldb::SBExpressionOptions;
using lldb::SBFrame;
using lldb::SBMemoryRegionInfo;

This comment was marked as off-topic.

This comment was marked as off-topic.

using lldb::SBStream;
using lldb::SBSymbol;
using lldb::SBTarget;
using lldb::SBThread;
using lldb::SBValue;
using lldb::eReturnStatusFailed;
using lldb::eReturnStatusSuccessFinishResult;

v8::LLV8 llv8;

Expand Down Expand Up @@ -97,30 +110,37 @@ bool BacktraceCmd::DoExecute(SBDebugger d, char** cmd,
if (number != -1) num_frames = number;
for (uint32_t i = 0; i < num_frames; i++) {
SBFrame frame = thread.GetFrameAtIndex(i);
SBSymbol symbol = frame.GetSymbol();

// C++ symbol
if (symbol.IsValid()) {
SBStream desc;
if (!frame.GetDescription(desc)) continue;
result.Printf(frame == selected_frame ? " * %s" : " %s",
desc.GetData());
continue;
const char star = (frame == selected_frame ? '*' : ' ');
const uint64_t pc = frame.GetPC();

if (!frame.GetSymbol().IsValid()) {
v8::Error err;
v8::JSFrame v8_frame(&llv8, static_cast<int64_t>(frame.GetFP()));
std::string res = v8_frame.Inspect(true, err);
if (err.Success()) {
result.Printf(" %c frame #%u: 0x%016llx %s\n", star, i, pc,
res.c_str());
continue;
}
}

// V8 frame
v8::Error err;
v8::JSFrame v8_frame(&llv8, static_cast<int64_t>(frame.GetFP()));
std::string res = v8_frame.Inspect(true, err);

// Skip invalid frames
if (err.Fail()) continue;
#ifdef LLDB_SBMemoryRegionInfoList_h_
// Heuristic: a PC in WX memory is almost certainly a V8 builtin.

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

// TODO(bnoordhuis) Find a way to map the PC to the builtin's name.
{
SBMemoryRegionInfo info;
if (target.GetProcess().GetMemoryRegionInfo(pc, info).Success() &&
info.IsExecutable() && info.IsWritable()) {
result.Printf(" %c frame #%u: 0x%016llx <builtin>\n", star, i, pc);
continue;
}
}
#endif // LLDB_SBMemoryRegionInfoList_h_

// V8 symbol
result.Printf(frame == selected_frame ? " * frame #%u: 0x%016llx %s\n"
: " frame #%u: 0x%016llx %s\n",
i, static_cast<unsigned long long int>(frame.GetPC()),
res.c_str());
// C++ stack frame.
SBStream desc;
if (frame.GetDescription(desc))
result.Printf(" %c %s", star, desc.GetData());
}

result.SetStatus(eReturnStatusSuccessFinishResult);
Expand Down
14 changes: 12 additions & 2 deletions src/llscan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,23 @@

namespace llnode {

using lldb::SBCommandReturnObject;
using lldb::SBDebugger;
using lldb::SBError;
using lldb::SBExpressionOptions;
using lldb::SBMemoryRegionInfo;
using lldb::SBMemoryRegionInfoList;
using lldb::SBStream;
using lldb::SBTarget;
using lldb::SBValue;
using lldb::eReturnStatusFailed;
using lldb::eReturnStatusSuccessFinishResult;

// Defined in llnode.cc
extern v8::LLV8 llv8;

LLScan llscan;

using namespace lldb;


bool FindObjectsCmd::DoExecute(SBDebugger d, char** cmd,
SBCommandReturnObject& result) {
Expand Down
9 changes: 8 additions & 1 deletion src/llv8-constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ namespace llnode {
namespace v8 {
namespace constants {

using namespace lldb;
using lldb::SBAddress;
using lldb::SBError;
using lldb::SBProcess;
using lldb::SBSymbol;
using lldb::SBSymbolContext;
using lldb::SBSymbolContextList;
using lldb::SBTarget;
using lldb::addr_t;

static std::string kConstantPrefix = "v8dbg_";

Expand Down
4 changes: 3 additions & 1 deletion src/llv8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
namespace llnode {
namespace v8 {

using namespace lldb;
using lldb::SBError;
using lldb::SBTarget;
using lldb::addr_t;

static std::string kConstantPrefix = "v8dbg_";

Expand Down
4 changes: 4 additions & 0 deletions test/frame-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ tape('v8 stack', (t) => {
sess.linesUntil(/eyecatcher/, (lines) => {
lines.reverse();
t.ok(lines.length > 4, 'frame count');
// FIXME(bnoordhuis) This can fail with versions of lldb that don't
// support the GetMemoryRegions() API; llnode won't be able to identify
// V8 builtins stack frames, it just prints them as anonymous frames.
lines = lines.filter((s) => !/<builtin>/.test(s));
const eyecatcher = lines[0];
const adapter = lines[1];
const crasher = lines[2];
Expand Down
10 changes: 5 additions & 5 deletions test/scan-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ tape('v8 findrefs and friends', (t) => {

sess.linesUntil(/lldb\-/, (lines) => {
// `class Deflate extends Zlib` makes instances show up as
// Transform objects (which Zlib inherits from) in node.js >= 8.
// Note that the version check will have to be redone for node.js >= 10
// but that is still a year out and by then llnode probably needs more
// fixups anyway.
// Transform objects (which Zlib inherits from) in node.js 8.0.0.
// That change was reverted in https://github.com/nodejs/node/pull/13374
// and released in 8.1.0.
const re =
(process.version >= 'v8.' ? /Transform\._handle/ : /Deflate\._handle/);
(process.version === 'v8.0.0' ?
/Transform\._handle/ : /Deflate\._handle/);
t.ok(re.test(lines.join('\n')), 'Should find reference');
t.ok(/Object\.holder/.test(lines.join('\n')), 'Should find reference #2');
t.ok(/\(Array\)\[1\]/.test(lines.join('\n')), 'Should find reference #3');
Expand Down