Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into workqueue_cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
Matheus Marchini committed Aug 29, 2017
2 parents 71c965d + f85f8fc commit 2084b2b
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 34 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ v8 bt command. See the [Commands](#commands) section below for more commands.
### Commands

```
(lldb) v8 help
(llnode) v8 help
Node.js helpers
Syntax: v8
Expand All @@ -226,7 +226,7 @@ The following subcommands are supported:
Syntax: v8 bt [number]
findjsinstances -- List all objects which share the specified map.
Accepts the same options as `v8 inspect`
findjsobjects -- List all object types and instance counts grouped by map and sorted by instance count.
findjsobjects -- List all object types and instance counts grouped by typename and sorted by instance count.
Requires `LLNODE_RANGESFILE` environment variable to be set to a file containing memory ranges for the
core file being debugged.
There are scripts for generating this file on Linux and Mac in the scripts directory of the llnode
Expand All @@ -238,25 +238,25 @@ The following subcommands are supported:
* -v, --value expr - all properties that refer to the specified JavaScript object (default)
* -n, --name name - all properties with the specified name
* -s, --string string - all properties that refer to the specified JavaScript string value
* --array-length num - print maximum of `num` elements in array
getactivehandles -- *EXPERIMENTAL* Equivalent to running process._getActiveHandles. This command is still being developed and for now it only works building node from source.
getactiverequests -- *EXPERIMENTAL* Equivalent to running process._getActiveRequests. This command is still being developed and for now it only works building node from source.
inspect -- Print detailed description and contents of the JavaScript value.
Possible flags (all optional):
* -F, --full-string - print whole string without adding ellipsis
* -m, --print-map - print object's map address
* -s, --print-source - print source code for function objects
* --string-length num - print maximum of `num` characters in string
* -l num, --length num - print maximum of `num` elements from string/array
Syntax: v8 inspect [flags] expr
nodeinfo -- Print information about Node.js
print -- Print short description of the JavaScript value.
Syntax: v8 print expr
source -- Source code information
getactivehandles -- *EXPERIMENTAL* Equivalent to running process._getActiveHandles. This command is still being developed and for now it only works building node from source.
getactiverequests -- *EXPERIMENTAL* Equivalent to running process._getActiveRequests. This command is still being developed and for now it only works building node from source.
For more help on any particular subcommand, type 'help <command> <subcommand>'.
```
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "llnode",
"version": "1.6.0",
"version": "1.6.1",
"description": "Node.js plugin for LLDB",
"main": "no-entry-sorry.js",
"directories": {
Expand Down
24 changes: 11 additions & 13 deletions src/llnode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ char** CommandBase::ParseInspectOptions(char** cmd,
v8::Value::InspectOptions* options) {
static struct option opts[] = {
{"full-string", no_argument, nullptr, 'F'},
{"string-length", required_argument, nullptr, 0x1001},
{"array-length", required_argument, nullptr, 0x1002},
{"string-length", required_argument, nullptr, 'l'},
{"array-length", required_argument, nullptr, 'l'},
{"length", required_argument, nullptr, 'l'},
{"print-map", no_argument, nullptr, 'm'},
{"print-source", no_argument, nullptr, 's'},
{nullptr, 0, nullptr, 0}};
Expand All @@ -67,21 +68,18 @@ char** CommandBase::ParseInspectOptions(char** cmd,
optind = 0;
opterr = 1;
do {
int arg = getopt_long(argc, args, "Fms", opts, nullptr);
int arg = getopt_long(argc, args, "Fmsl:", opts, nullptr);
if (arg == -1) break;

switch (arg) {
case 'F':
options->string_length = 0;
options->length = 0;
break;
case 'm':
options->print_map = true;
break;
case 0x1001:
options->string_length = strtol(optarg, nullptr, 10);
break;
case 0x1002:
options->array_length = strtol(optarg, nullptr, 10);
case 'l':
options->length = strtol(optarg, nullptr, 10);
break;
case 's':
options->print_source = true;
Expand Down Expand Up @@ -431,8 +429,8 @@ bool PluginInitialize(SBDebugger d) {
" * -F, --full-string - print whole string without adding ellipsis\n"
" * -m, --print-map - print object's map address\n"
" * -s, --print-source - print source code for function objects\n"
" * --string-length num - print maximum of `num` characters in string\n"
" * --array-length num - print maximum of `num` elements in array\n"
" * -l num, --length num - print maximum of `num` elements from "
"string/array\n"
"\n"
"Syntax: v8 inspect [flags] expr\n");
interpreter.AddCommand("jsprint", new llnode::PrintCmd(true),
Expand All @@ -447,8 +445,8 @@ bool PluginInitialize(SBDebugger d) {
"Alias for `v8 source list`");

v8.AddCommand("findjsobjects", new llnode::FindObjectsCmd(),
"List all object types and instance counts grouped by map and "
"sorted by instance count.\n"
"List all object types and instance counts grouped by type"
"name and sorted by instance count.\n"
#ifndef LLDB_SBMemoryRegionInfoList_h_
"Requires `LLNODE_RANGESFILE` environment variable to be set "
"to a file containing memory ranges for the core file being "
Expand Down
16 changes: 16 additions & 0 deletions src/llscan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,14 @@ void FindReferencesCmd::ReferenceScanner::PrintRefs(
result.Printf("0x%" PRIx64 ": %s.%s=0x%" PRIx64 "\n", str.raw(),
type_name.c_str(), "<Second>", search_value_.raw());
}
} else if (repr == v8->string()->kThinStringTag) {
v8::ThinString thin_str(str);
v8::String actual = thin_str.Actual(err);
if (err.Success() && actual.raw() == search_value_.raw()) {
std::string type_name = thin_str.GetTypeName(err);
result.Printf("0x%" PRIx64 ": %s.%s=0x%" PRIx64 "\n", str.raw(),
type_name.c_str(), "<Actual>", search_value_.raw());
}
}
// Nothing to do for other kinds of string.
}
Expand Down Expand Up @@ -694,6 +702,14 @@ void FindReferencesCmd::ReferenceScanner::ScanRefs(v8::String& str,
references = llscan.GetReferencesByValue(second.raw());
references->push_back(str.raw());
}
} else if (repr == v8->string()->kThinStringTag) {
v8::ThinString thin_str(str);
v8::String actual = thin_str.Actual(err);

if (err.Success()) {
references = llscan.GetReferencesByValue(actual.raw());
references->push_back(str.raw());
}
}
// Nothing to do for other kinds of string.
}
Expand Down
5 changes: 5 additions & 0 deletions src/llv8-constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ void String::Load() {
kConsStringTag = LoadConstant("ConsStringTag");
kSlicedStringTag = LoadConstant("SlicedStringTag");
kExternalStringTag = LoadConstant("ExternalStringTag");
kThinStringTag = LoadConstant("ThinStringTag");

kLengthOffset = LoadConstant("class_String__length__SMI");
}
Expand Down Expand Up @@ -365,6 +366,9 @@ void SlicedString::Load() {
kOffsetOffset = LoadConstant("class_SlicedString__offset__SMI");
}

void ThinString::Load() {
kActualOffset = LoadConstant("class_ThinString__actual__String");
}

void FixedArrayBase::Load() {
kLengthOffset = LoadConstant("class_FixedArrayBase__length__SMI");
Expand Down Expand Up @@ -521,6 +525,7 @@ void Frame::Load() {
kConstructFrame = LoadConstant("frametype_ConstructFrame");
kJSFrame = LoadConstant("frametype_JavaScriptFrame");
kOptimizedFrame = LoadConstant("frametype_OptimizedFrame");
kStubFrame = LoadConstant("frametype_StubFrame");
}


Expand Down
12 changes: 12 additions & 0 deletions src/llv8-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ class String : public Module {
int64_t kConsStringTag;
int64_t kSlicedStringTag;
int64_t kExternalStringTag;
int64_t kThinStringTag;

int64_t kLengthOffset;

Expand Down Expand Up @@ -305,6 +306,16 @@ class SlicedString : public Module {
void Load();
};

class ThinString : public Module {
public:
MODULE_DEFAULT_METHODS(ThinString);

int64_t kActualOffset;

protected:
void Load();
};

class FixedArrayBase : public Module {
public:
MODULE_DEFAULT_METHODS(FixedArrayBase);
Expand Down Expand Up @@ -449,6 +460,7 @@ class Frame : public Module {
int64_t kConstructFrame;
int64_t kJSFrame;
int64_t kOptimizedFrame;
int64_t kStubFrame;

protected:
void Load();
Expand Down
12 changes: 12 additions & 0 deletions src/llv8-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ ACCESSOR(ConsString, Second, cons_string()->kSecondOffset, String);
ACCESSOR(SlicedString, Parent, sliced_string()->kParentOffset, String);
ACCESSOR(SlicedString, Offset, sliced_string()->kOffsetOffset, Smi);

ACCESSOR(ThinString, Actual, thin_string()->kActualOffset, String);

ACCESSOR(FixedArrayBase, Length, fixed_array_base()->kLengthOffset, Smi);

inline std::string OneByteString::ToString(Error& err) {
Expand Down Expand Up @@ -319,6 +321,16 @@ inline std::string SlicedString::ToString(Error& err) {
return tmp.substr(offset.GetValue(), length.GetValue());
}

inline std::string ThinString::ToString(Error& err) {
String actual = Actual(err);
if (err.Fail()) return std::string();

std::string tmp = actual.ToString(err);
if (err.Fail()) return std::string();

return tmp;
}

inline int64_t FixedArray::LeaData() const {
return LeaField(v8()->fixed_array()->kDataOffset);
}
Expand Down
22 changes: 15 additions & 7 deletions src/llv8.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include <assert.h>

#include <algorithm>
#include <algorithm>
#include <cinttypes>

Expand Down Expand Up @@ -43,6 +42,7 @@ void LLV8::Load(SBTarget target) {
two_byte_string.Assign(target, &common);
cons_string.Assign(target, &common);
sliced_string.Assign(target, &common);
thin_string.Assign(target, &common);
fixed_array_base.Assign(target, &common);
fixed_array.Assign(target, &common);
oddball.Assign(target, &common);
Expand Down Expand Up @@ -269,6 +269,8 @@ std::string JSFrame::Inspect(bool with_args, Error& err) {
return "<internal>";
} else if (value == v8()->frame()->kConstructFrame) {
return "<constructor>";
} else if (value == v8()->frame()->kStubFrame) {
return "<stub>";
} else if (value != v8()->frame()->kJSFrame &&
value != v8()->frame()->kOptimizedFrame) {
err = Error::Failure("Unknown frame marker");
Expand Down Expand Up @@ -958,6 +960,11 @@ std::string String::ToString(Error& err) {
return std::string("(external)");
}

if (repr == v8()->string()->kThinStringTag) {
ThinString thin(this);
return thin.ToString(err);
}

err = Error::Failure("Unsupported string representation");
return std::string();
}
Expand All @@ -967,7 +974,7 @@ std::string String::Inspect(InspectOptions* options, Error& err) {
std::string val = ToString(err);
if (err.Fail()) return std::string();

unsigned int len = options->string_length;
unsigned int len = options->length;

if (len != 0 && val.length() > len) val = val.substr(0, len) + "...";

Expand Down Expand Up @@ -1120,7 +1127,7 @@ std::string JSArrayBuffer::Inspect(InspectOptions* options, Error& err) {
if (options->detailed) {
res += ": [\n ";

int display_length = std::min<int>(byte_length, options->array_length);
int display_length = std::min<int>(byte_length, options->length);
res += v8()->LoadBytes(display_length, data, err);

if (display_length < byte_length) {
Expand Down Expand Up @@ -1156,16 +1163,17 @@ std::string JSArrayBufferView::Inspect(InspectOptions* options, Error& err) {
int byte_length = static_cast<int>(length.GetValue());
int byte_offset = static_cast<int>(off.GetValue());
char tmp[128];
snprintf(tmp, sizeof(tmp), "<ArrayBufferView: backingStore=0x%016" PRIx64
", byteOffset=%d, byteLength=%d",
snprintf(tmp, sizeof(tmp),
"<ArrayBufferView: backingStore=0x%016" PRIx64
", byteOffset=%d, byteLength=%d",
data, byte_offset, byte_length);

std::string res;
res += tmp;
if (options->detailed) {
res += ": [\n ";

int display_length = std::min<int>(byte_length, options->array_length);
int display_length = std::min<int>(byte_length, options->length);
res += v8()->LoadBytes(display_length, data + byte_offset, err);

if (display_length < byte_length) {
Expand Down Expand Up @@ -1915,7 +1923,7 @@ std::string JSArray::Inspect(InspectOptions* options, Error& err) {

std::string res = "<Array: length=" + std::to_string(length);
if (options->detailed) {
int64_t display_length = std::min<int64_t>(length, options->array_length);
int64_t display_length = std::min<int64_t>(length, options->length);
std::string elems = InspectElements(display_length, err);
if (err.Fail()) return std::string();

Expand Down
20 changes: 14 additions & 6 deletions src/llv8.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,14 @@ class Value {
: detailed(false),
print_map(false),
print_source(false),
string_length(kStringLength),
array_length(kArrayLength) {}
length(kLength) {}

static const unsigned int kStringLength = 16;
static const unsigned int kArrayLength = 16;
static const unsigned int kLength = 16;

bool detailed;
bool print_map;
bool print_source;
unsigned int string_length;
unsigned int array_length;
unsigned int length;
};

Value(const Value& v) = default;
Expand Down Expand Up @@ -222,6 +219,15 @@ class SlicedString : public String {
inline std::string ToString(Error& err);
};

class ThinString : public String {
public:
V8_VALUE_DEFAULT_METHODS(ThinString, String)

inline String Actual(Error& err);

inline std::string ToString(Error& err);
};

class HeapNumber : public HeapObject {
public:
V8_VALUE_DEFAULT_METHODS(HeapNumber, HeapObject)
Expand Down Expand Up @@ -481,6 +487,7 @@ class LLV8 {
constants::TwoByteString two_byte_string;
constants::ConsString cons_string;
constants::SlicedString sliced_string;
constants::ThinString thin_string;
constants::FixedArrayBase fixed_array_base;
constants::FixedArray fixed_array;
constants::Oddball oddball;
Expand All @@ -507,6 +514,7 @@ class LLV8 {
friend class TwoByteString;
friend class ConsString;
friend class SlicedString;
friend class ThinString;
friend class HeapNumber;
friend class JSObject;
friend class JSArray;
Expand Down
10 changes: 10 additions & 0 deletions test/fixtures/inspect-scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ let outerVar = 'outer variable';

exports.holder = {};

function makeThin(a, b) {
var str = a + b;
var obj = {};
obj[str]; // Turn the cons string into a thin string.
return str;
}

function closure() {

function Class() {
Expand All @@ -28,6 +35,9 @@ function closure() {
c.hashmap['cons-string'] =
'this could be a bit smaller, but v8 wants big str.';
c.hashmap['cons-string'] += c.hashmap['cons-string'];
c.hashmap['internalized-string'] = 'foobar';
// This thin string points to the previous 'foobar'.
c.hashmap['thin-string'] = makeThin('foo', 'bar');
c.hashmap['array'] = [true, 1, undefined, null, 'test', Class];
c.hashmap['long-array'] = new Array(20).fill(5);
c.hashmap['array-buffer'] = new Uint8Array(
Expand Down
Loading

0 comments on commit 2084b2b

Please sign in to comment.