namespace lldb_vscode {
+void EmplaceSafeString(llvm::json::Object &obj, llvm::StringRef key,
+ llvm::StringRef str) {
+ if (LLVM_LIKELY(llvm::json::isUTF8(str)))
+ obj.try_emplace(key, str.str());
+ else
+ obj.try_emplace(key, llvm::json::fixUTF8(str));
+}
+
llvm::StringRef GetAsString(const llvm::json::Value &value) {
if (auto s = value.getAsString())
return *s;
void SetValueForKey(lldb::SBValue &v, llvm::json::Object &object,
llvm::StringRef key) {
-
+
llvm::StringRef value = v.GetValue();
llvm::StringRef summary = v.GetSummary();
llvm::StringRef type_name = v.GetType().GetDisplayTypeName();
-
+
std::string result;
llvm::raw_string_ostream strm(result);
if (!value.empty()) {
strm << " @ " << llvm::format_hex(address, 0);
}
strm.flush();
- object.try_emplace(key, result);
+ EmplaceSafeString(object, key, result);
}
void FillResponse(const llvm::json::Object &request,
// to true by default.
response.try_emplace("type", "response");
response.try_emplace("seq", (int64_t)0);
- response.try_emplace("command", GetString(request, "command"));
+ EmplaceSafeString(response, "command", GetString(request, "command"));
const int64_t seq = GetSigned(request, "seq", 0);
response.try_emplace("request_seq", seq);
response.try_emplace("success", true);
int64_t variablesReference,
int64_t namedVariables, bool expensive) {
llvm::json::Object object;
- object.try_emplace("name", name.str());
+ EmplaceSafeString(object, "name", name.str());
object.try_emplace("variablesReference", variablesReference);
object.try_emplace("expensive", expensive);
object.try_emplace("namedVariables", namedVariables);
llvm::json::Object event;
event.try_emplace("seq", 0);
event.try_emplace("type", "event");
- event.try_emplace("event", event_name);
+ EmplaceSafeString(event, "event", event_name);
return event;
}
llvm::json::Value
CreateExceptionBreakpointFilter(const ExceptionBreakpoint &bp) {
llvm::json::Object object;
- object.try_emplace("filter", bp.filter);
- object.try_emplace("label", bp.label);
+ EmplaceSafeString(object, "filter", bp.filter);
+ EmplaceSafeString(object, "label", bp.label);
object.try_emplace("default", bp.default_value);
return llvm::json::Value(std::move(object));
}
if (file.IsValid()) {
const char *name = file.GetFilename();
if (name)
- object.try_emplace("name", name);
+ EmplaceSafeString(object, "name", name);
char path[PATH_MAX] = "";
file.GetPath(path, sizeof(path));
if (path[0]) {
- object.try_emplace("path", std::string(path));
+ EmplaceSafeString(object, "path", std::string(path));
}
}
return llvm::json::Value(std::move(object));
}
const auto num_insts = insts.GetSize();
if (low_pc != LLDB_INVALID_ADDRESS && num_insts > 0) {
- object.try_emplace("name", frame.GetFunctionName());
+ EmplaceSafeString(object, "name", frame.GetFunctionName());
SourceReference source;
llvm::raw_string_ostream src_strm(source.content);
std::string line;
line.clear();
llvm::raw_string_ostream line_strm(line);
line_strm << llvm::formatv("{0:X+}: <{1}> {2} {3,12} {4}", inst_addr,
- inst_offset, llvm::fmt_repeat(' ', spaces),
- m, o);
+ inst_offset, llvm::fmt_repeat(' ', spaces), m,
+ o);
// If there is a comment append it starting at column 60 or after one
// space past the last char
llvm::json::Object object;
int64_t frame_id = MakeVSCodeFrameID(frame);
object.try_emplace("id", frame_id);
- object.try_emplace("name", frame.GetFunctionName());
+ EmplaceSafeString(object, "name", frame.GetFunctionName());
int64_t disasm_line = 0;
object.try_emplace("source", CreateSource(frame, disasm_line));
std::string thread_with_name(thread_str);
thread_with_name += ' ';
thread_with_name += name;
- object.try_emplace("name", thread_with_name);
+ EmplaceSafeString(object, "name", thread_with_name);
} else {
- object.try_emplace("name", std::string(thread_str));
+ EmplaceSafeString(object, "name", std::string(thread_str));
}
return llvm::json::Value(std::move(object));
}
ExceptionBreakpoint *exc_bp = g_vsc.GetExceptionBPFromStopReason(thread);
if (exc_bp) {
body.try_emplace("reason", "exception");
- body.try_emplace("description", exc_bp->label);
+ EmplaceSafeString(body, "description", exc_bp->label);
} else {
body.try_emplace("reason", "breakpoint");
}
if (ObjectContainsKey(body, "description")) {
char description[1024];
if (thread.GetStopDescription(description, sizeof(description))) {
- body.try_emplace("description", std::string(description));
+ EmplaceSafeString(body, "description", std::string(description));
}
}
if (tid == g_vsc.focus_tid) {
int64_t varID, bool format_hex) {
llvm::json::Object object;
auto name = v.GetName();
- object.try_emplace("name", name ? name : "<null>");
+ EmplaceSafeString(object, "name", name ? name : "<null>");
if (format_hex)
v.SetFormat(lldb::eFormatHex);
SetValueForKey(v, object, "value");
auto type_cstr = v.GetType().GetDisplayTypeName();
- object.try_emplace("type", type_cstr ? type_cstr : NO_TYPENAME);
+ EmplaceSafeString(object, "type", type_cstr ? type_cstr : NO_TYPENAME);
if (varID != INT64_MAX)
object.try_emplace("id", varID);
if (v.MightHaveChildren())
v.GetExpressionPath(evaluateStream);
const char *evaluateName = evaluateStream.GetData();
if (evaluateName && evaluateName[0])
- object.try_emplace("evaluateName", std::string(evaluateName));
+ EmplaceSafeString(object, "evaluateName", std::string(evaluateName));
return llvm::json::Value(std::move(object));
}
exe_fspec.GetPath(exe_path, sizeof(exe_path));
llvm::json::Object event(CreateEventObject("process"));
llvm::json::Object body;
- body.try_emplace("name", std::string(exe_path));
+ EmplaceSafeString(body, "name", std::string(exe_path));
const auto pid = g_vsc.target.GetProcess().GetProcessID();
body.try_emplace("systemProcessId", (int64_t)pid);
body.try_emplace("isLocalProcess", true);
g_vsc.target.AddModule(program.data(), target_triple, uuid_cstr, symfile);
if (error.Fail()) {
response.try_emplace("success", false);
- response.try_emplace("message", std::string(error.GetCString()));
+ EmplaceSafeString(response, "message", std::string(error.GetCString()));
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
return;
}
if (error.Fail()) {
response.try_emplace("success", false);
- response.try_emplace("message", std::string(error.GetCString()));
+ EmplaceSafeString(response, "message", std::string(error.GetCString()));
}
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
if (error.Success()) {
else if (stopReason == lldb::eStopReasonBreakpoint) {
ExceptionBreakpoint *exc_bp = g_vsc.GetExceptionBPFromStopReason(thread);
if (exc_bp) {
- body.try_emplace("exceptionId", exc_bp->filter);
- body.try_emplace("description", exc_bp->label);
+ EmplaceSafeString(body, "exceptionId", exc_bp->filter);
+ EmplaceSafeString(body, "description", exc_bp->label);
} else {
body.try_emplace("exceptionId", "exception");
}
if (!ObjectContainsKey(body, "description")) {
char description[1024];
if (thread.GetStopDescription(description, sizeof(description))) {
- body.try_emplace("description", std::string(description));
+ EmplaceSafeString(body, "description", std::string(description));
}
}
body.try_emplace("breakMode", "always");
const auto expression = GetString(arguments, "expression");
if (!expression.empty() && expression[0] == '`') {
- body.try_emplace("result",
- RunLLDBCommands(llvm::StringRef(),
- {expression.substr(1)}));
+ auto result = RunLLDBCommands(llvm::StringRef(),
+ {expression.substr(1)});
+ EmplaceSafeString(body, "result", result);
body.try_emplace("variablesReference", (int64_t)0);
} else {
// Always try to get the answer from the local variables if possible. If
response.try_emplace("success", false);
const char *error_cstr = value.GetError().GetCString();
if (error_cstr && error_cstr[0])
- response.try_emplace("message", std::string(error_cstr));
+ EmplaceSafeString(response, "message", std::string(error_cstr));
else
- response.try_emplace("message", "evaluate failed");
+ EmplaceSafeString(response, "message", "evaluate failed");
} else {
SetValueForKey(value, body, "result");
auto value_typename = value.GetType().GetDisplayTypeName();
- body.try_emplace("type", value_typename ? value_typename : NO_TYPENAME);
+ EmplaceSafeString(body, "type", value_typename ? value_typename : NO_TYPENAME);
if (value.MightHaveChildren()) {
auto variablesReference = VARIDX_TO_VARREF(g_vsc.variables.GetSize());
g_vsc.variables.Append(value);
g_vsc.target.AddModule(program.data(), target_triple, uuid_cstr, symfile);
if (error.Fail()) {
response.try_emplace("success", false);
- response.try_emplace("message", std::string(error.GetCString()));
+ EmplaceSafeString(response, "message", std::string(error.GetCString()));
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
}
}
g_vsc.target.Launch(g_vsc.launch_info, error);
if (error.Fail()) {
response.try_emplace("success", false);
- response.try_emplace("message", std::string(error.GetCString()));
+ EmplaceSafeString(response, "message", std::string(error.GetCString()));
}
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
auto sourceReference = GetSigned(source, "sourceReference", -1);
auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
if (pos != g_vsc.source_map.end()) {
- body.try_emplace("content", pos->second.content);
+ EmplaceSafeString(body, "content", pos->second.content);
} else {
response.try_emplace("success", false);
}
bool success = variable.SetValueFromCString(value.data(), error);
if (success) {
SetValueForKey(variable, body, "value");
- body.try_emplace("type", variable.GetType().GetDisplayTypeName());
+ EmplaceSafeString(body, "type", variable.GetType().GetDisplayTypeName());
body.try_emplace("variablesReference", newVariablesReference);
} else {
- body.try_emplace("message", std::string(error.GetCString()));
+ EmplaceSafeString(body, "message", std::string(error.GetCString()));
}
response.try_emplace("success", success);
}