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: add commands to inspect the workqueue #122

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ The following subcommands are supported:
* -n, --name name - all properties with the specified name
* -s, --string string - all properties that refer to the specified JavaScript string value

getactivehandles -- Print all pending handles in the queue. Equivalent to running process._getActiveHandles() on
the living process.

getactiverequests -- Print all pending handles in the queue. Equivalent to running process._getActiveHandles() on
the living process.

inspect -- Print detailed description and contents of the JavaScript value.

Possible flags (all optional):
Expand Down
5 changes: 5 additions & 0 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"<(lldb_include_dir)",
],


"cflags" : [ "-std=c++11" ],

"conditions": [
Expand Down Expand Up @@ -58,10 +59,14 @@
"target_name": "plugin",
"type": "shared_library",
"sources": [
"src/constants.cc",
"src/error.cc",
"src/llnode.cc",
"src/llv8.cc",
"src/llv8-constants.cc",
"src/llscan.cc",
"src/node.cc",
"src/node-constants.cc",
]
}],
}
121 changes: 121 additions & 0 deletions src/constants.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include <cinttypes>

#include <lldb/API/SBExpressionOptions.h>

#include "src/constants.h"

using lldb::SBAddress;
using lldb::SBError;
using lldb::SBSymbol;
using lldb::SBSymbolContext;
using lldb::SBSymbolContextList;

namespace llnode {

template <typename T>
T ReadSymbolFromTarget(SBTarget& target, SBAddress& start, const char* name,
Error& err) {
SBError sberr;
T res = 0;
target.ReadMemory(start, &res, sizeof(T), sberr);
if (!sberr.Fail()) {
err = Error::Ok();
} else {
err = Error::Failure("Failed to read symbol %s", name);
}
return res;
}

int64_t Constants::LookupConstant(SBTarget target, const char* name,
int64_t def, Error& err) {
int64_t res = 0;
res = def;

SBSymbolContextList context_list = target.FindSymbols(name);

if (!context_list.IsValid() || context_list.GetSize() == 0) {
err = Error::Failure("Failed to find symbol %s", name);
return res;
}

SBSymbolContext context = context_list.GetContextAtIndex(0);
SBSymbol symbol = context.GetSymbol();
if (!symbol.IsValid()) {
err = Error::Failure("Failed to fetch symbol %s from context", name);
return res;
}

SBAddress start = symbol.GetStartAddress();
SBAddress end = symbol.GetEndAddress();
uint32_t size = end.GetOffset() - start.GetOffset();

// NOTE: size could be bigger for at the end symbols
if (size >= 8) {
res = ReadSymbolFromTarget<int64_t>(target, start, name, err);
} else if (size == 4) {
int32_t tmp = ReadSymbolFromTarget<int32_t>(target, start, name, err);
res = static_cast<int64_t>(tmp);
} else if (size == 2) {
int16_t tmp = ReadSymbolFromTarget<int16_t>(target, start, name, err);
res = static_cast<int64_t>(tmp);
} else if (size == 1) {
int8_t tmp = ReadSymbolFromTarget<int8_t>(target, start, name, err);
res = static_cast<int64_t>(tmp);
} else {
err = Error::Failure("Unexpected symbol size %" PRIu32 " of symbol %s",
size, name);
}

return res;
}

void Constants::Assign(SBTarget target) {
loaded_ = false;
target_ = target;
}


int64_t Constants::LoadRawConstant(const char* name, int64_t def) {
Error err;
int64_t v = Constants::LookupConstant(target_, name, def, err);
if (err.Fail()) {
Error::PrintInDebugMode(
"Failed to load raw constant %s, default to %" PRId64, name, def);
}

return v;
}

int64_t Constants::LoadConstant(const char* name, Error& err, int64_t def) {
int64_t v = Constants::LookupConstant(
target_, (constant_prefix() + name).c_str(), def, err);
return v;
}

int64_t Constants::LoadConstant(const char* name, int64_t def) {
Error err;
int64_t v = LoadConstant(name, err, def);
if (err.Fail()) {
Error::PrintInDebugMode("Failed to load constant %s, default to %" PRId64,
name, def);
}

return v;
}

int64_t Constants::LoadConstant(const char* name, const char* fallback,
int64_t def) {
Error err;
int64_t v = LoadConstant(name, err, def);
if (err.Fail()) v = LoadConstant(fallback, err, def);
if (err.Fail()) {
Error::PrintInDebugMode(
"Failed to load constant %s, fallback %s, default to %" PRId64, name,
fallback, def);
}

return v;
}


} // namespace llnode
47 changes: 47 additions & 0 deletions src/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef SRC_CONSTANTS_H_
#define SRC_CONSTANTS_H_

#include <lldb/API/LLDB.h>
#include <string>

#include "src/error.h"

using lldb::SBTarget;

namespace llnode {

#define CONSTANTS_DEFAULT_METHODS(NAME) \
inline NAME* operator()() { \
if (loaded_) return this; \
loaded_ = true; \
Load(); \
return this; \
}

class Constants {
public:
Constants() : loaded_(false) {}

inline bool is_loaded() const { return loaded_; }

void Assign(lldb::SBTarget target);

inline virtual std::string constant_prefix() { return ""; };

static int64_t LookupConstant(SBTarget target, const char* name, int64_t def,
Error& err);

protected:
int64_t LoadRawConstant(const char* name, int64_t def = -1);
int64_t LoadConstant(const char* name, Error& err, int64_t def = -1);
int64_t LoadConstant(const char* name, int64_t def = -1);
int64_t LoadConstant(const char* name, const char* fallback,
int64_t def = -1);

lldb::SBTarget target_;
bool loaded_;
};

} // namespace llnode

#endif
46 changes: 46 additions & 0 deletions src/error.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <cstdarg>

#include "error.h"

namespace llnode {
bool Error::is_debug_mode = false;

Error::Error(bool failed, const char* format, ...) {
failed_ = failed;
char tmp[kMaxMessageLength];
va_list arglist;
va_start(arglist, format);
vsnprintf(tmp, sizeof(tmp), format, arglist);
va_end(arglist);
msg_ = tmp;
}


void Error::PrintInDebugMode(const char* format, ...) {
if (!is_debug_mode) {
return;
}
char fmt[kMaxMessageLength];
snprintf(fmt, sizeof(fmt), "[llv8] %s\n", format);
va_list arglist;
va_start(arglist, format);
vfprintf(stderr, fmt, arglist);
va_end(arglist);
}


Error Error::Failure(std::string msg) {
PrintInDebugMode("%s", msg.c_str());
return Error(true, msg);
}


Error Error::Failure(const char* format, ...) {
char tmp[kMaxMessageLength];
va_list arglist;
va_start(arglist, format);
vsnprintf(tmp, sizeof(tmp), format, arglist);
va_end(arglist);
return Error::Failure(std::string(tmp));
}
} // namespace llnode
37 changes: 37 additions & 0 deletions src/error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef SRC_ERROR_H_
#define SRC_ERROR_H_

#include <string>

namespace llnode {

class Error {
public:
Error() : failed_(false), msg_("") {}
Error(bool failed, std::string msg) : failed_(failed), msg_(msg) {}
Error(bool failed, const char* format, ...)
__attribute__((format(printf, 3, 4)));

static inline Error Ok() { return Error(false, "ok"); }
static Error Failure(std::string msg);
static Error Failure(const char* format, ...)
__attribute__((format(printf, 1, 2)));
static void PrintInDebugMode(const char* format, ...)
__attribute__((format(printf, 1, 2)));

inline bool Success() const { return !Fail(); }
inline bool Fail() const { return failed_; }

inline const char* GetMessage() { return msg_.c_str(); }

static void SetDebugMode(bool mode) { is_debug_mode = mode; }

private:
bool failed_;
std::string msg_;
static const size_t kMaxMessageLength = 128;
static bool is_debug_mode;
};
} // namespace llnode

#endif
Loading