Skip to content
Open
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
5 changes: 3 additions & 2 deletions lldb/include/lldb/Target/StackFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ class StackFrame : public ExecutionContextScope,
/// \param [in] frame_marker
/// Optional string that will be prepended to the frame output description.
void DumpUsingSettingsFormat(Stream *strm, bool show_unique = false,
const char *frame_marker = nullptr);
const std::string &frame_marker = "");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StringRef?


/// Print a description for this frame using a default format.
///
Expand Down Expand Up @@ -390,7 +390,8 @@ class StackFrame : public ExecutionContextScope,
/// \return
/// Returns true if successful.
bool GetStatus(Stream &strm, bool show_frame_info, bool show_source,
bool show_unique = false, const char *frame_marker = nullptr);
bool show_unique = false,
const std::string &frame_marker = "");

/// Query whether this frame is a concrete frame on the call stack, or if it
/// is an inlined frame derived from the debug information and presented by
Expand Down
11 changes: 10 additions & 1 deletion lldb/include/lldb/Target/StackFrameList.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ class StackFrameList {
/// Resets the selected frame index of this object.
void ClearSelectedFrameIndex();

/// Return \code true if the next frame is hidden.
bool IsNextFrameHidden(lldb_private::StackFrame &frame);

/// Return \code true if the previous frame is hidden.
bool IsPreviousFrameHidden(lldb_private::StackFrame &frame);

std::wstring FrameMarker(lldb::StackFrameSP frame_sp,
lldb::StackFrameSP selected_frame_sp);

/// Get the currently selected frame index.
/// We should only call SelectMostRelevantFrame if (a) the user hasn't already
/// selected a frame, and (b) if this really is a user facing
Expand Down Expand Up @@ -96,7 +105,7 @@ class StackFrameList {
size_t GetStatus(Stream &strm, uint32_t first_frame, uint32_t num_frames,
bool show_frame_info, uint32_t num_frames_with_source,
bool show_unique = false, bool show_hidden = false,
const char *frame_marker = nullptr);
bool show_selected_frame = false);

/// Returns whether we have currently fetched all the frames of a stack.
bool WereAllFramesFetched() const;
Expand Down
11 changes: 11 additions & 0 deletions lldb/include/lldb/Utility/DiagnosticsRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ void RenderDiagnosticDetails(Stream &stream,
bool show_inline,
llvm::ArrayRef<DiagnosticDetail> details);

/// Returns whether or not the current terminal supports Unicode rendering.
///
/// The value is cached after the first computation.
///
/// On POSIX systems, we check if the LANG environment variable contains the
/// substring "UTF-8";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's so much better than checking for color!

///
/// On Windows, we check that we are running from the Windows Terminal
/// application.
bool TerminalSupportsUnicode();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this into Host/Terminal.h?


class DiagnosticError
: public llvm::ErrorInfo<DiagnosticError, CloneableECError> {
public:
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Target/StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,7 @@ bool StackFrame::DumpUsingFormat(Stream &strm,
}

void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
const char *frame_marker) {
const std::string &frame_marker) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're passing this into a function that takes a StringRef — why not make it a StringRef, too?

if (strm == nullptr)
return;

Expand All @@ -1953,6 +1953,7 @@ void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
frame_format = &format_entry;
}
}

if (!DumpUsingFormat(*strm, frame_format, frame_marker)) {
Dump(strm, true, false);
strm->EOL();
Expand Down Expand Up @@ -2034,7 +2035,7 @@ bool StackFrame::HasCachedData() const {
}

bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
bool show_unique, const char *frame_marker) {
bool show_unique, const std::string &frame_marker) {
if (show_frame_info) {
strm.Indent();
DumpUsingSettingsFormat(&strm, show_unique, frame_marker);
Expand Down
59 changes: 43 additions & 16 deletions lldb/source/Target/StackFrameList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/DiagnosticsRendering.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ConvertUTF.h"

#include <memory>

Expand Down Expand Up @@ -879,11 +881,43 @@ StackFrameList::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) {
return ret_sp;
}

bool StackFrameList::IsNextFrameHidden(lldb_private::StackFrame &frame) {
uint32_t frame_idx = frame.GetFrameIndex();
StackFrameSP frame_sp = GetFrameAtIndex(frame_idx + 1);
if (!frame_sp)
return false;
return frame_sp->IsHidden();
}

bool StackFrameList::IsPreviousFrameHidden(lldb_private::StackFrame &frame) {
uint32_t frame_idx = frame.GetFrameIndex();
if (frame_idx == 0)
return false;
StackFrameSP frame_sp = GetFrameAtIndex(frame_idx - 1);
if (!frame_sp)
return false;
return frame_sp->IsHidden();
}

std::wstring StackFrameList::FrameMarker(lldb::StackFrameSP frame_sp,
lldb::StackFrameSP selected_frame_sp) {
if (frame_sp == selected_frame_sp) {
return TerminalSupportsUnicode() ? L" * " : L"* ";
} else if (!TerminalSupportsUnicode()) {
return L" ";
} else if (IsPreviousFrameHidden(*frame_sp)) {
return L" ﹉";
} else if (IsNextFrameHidden(*frame_sp)) {
return L" ﹍";
}
Comment on lines +904 to +912
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No braces

return L"  ";
}

size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame,
uint32_t num_frames, bool show_frame_info,
uint32_t num_frames_with_source,
bool show_unique, bool show_hidden,
const char *selected_frame_marker) {
bool show_selected_frame) {
size_t num_frames_displayed = 0;

if (num_frames == 0)
Expand All @@ -901,25 +935,17 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame,

StackFrameSP selected_frame_sp =
m_thread.GetSelectedFrame(DoNoSelectMostRelevantFrame);
const char *unselected_marker = nullptr;
std::string buffer;
if (selected_frame_marker) {
size_t len = strlen(selected_frame_marker);
buffer.insert(buffer.begin(), len, ' ');
unselected_marker = buffer.c_str();
}
const char *marker = nullptr;
std::wstring marker;
for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx) {
frame_sp = GetFrameAtIndex(frame_idx);
if (!frame_sp)
break;

if (selected_frame_marker != nullptr) {
if (frame_sp == selected_frame_sp)
marker = selected_frame_marker;
else
marker = unselected_marker;
}
if (show_selected_frame)
marker = FrameMarker(frame_sp, selected_frame_sp);
else
marker = FrameMarker(frame_sp, nullptr);

// Hide uninteresting frames unless it's the selected frame.
if (!show_hidden && frame_sp != selected_frame_sp && frame_sp->IsHidden())
Expand All @@ -933,10 +959,11 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame,
m_thread.GetID(), num_frames_displayed))
break;


std::string marker_utf8;
llvm::convertWideToUTF8(marker, marker_utf8);
if (!frame_sp->GetStatus(strm, show_frame_info,
num_frames_with_source > (first_frame - frame_idx),
show_unique, marker))
show_unique, marker_utf8))
break;
++num_frames_displayed;
}
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Target/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1817,16 +1817,16 @@ size_t Thread::GetStatus(Stream &strm, uint32_t start_frame,

const bool show_frame_info = true;
const bool show_frame_unique = only_stacks;
const char *selected_frame_marker = nullptr;
bool show_selected_frame = false;
if (num_frames == 1 || only_stacks ||
(GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID()))
strm.IndentMore();
else
selected_frame_marker = "* ";
show_selected_frame = true;

num_frames_shown = GetStackFrameList()->GetStatus(
strm, start_frame, num_frames, show_frame_info, num_frames_with_source,
show_frame_unique, show_hidden, selected_frame_marker);
show_frame_unique, show_hidden, show_selected_frame);
if (num_frames == 1)
strm.IndentLess();
strm.IndentLess();
Expand Down
17 changes: 16 additions & 1 deletion lldb/source/Utility/DiagnosticsRendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void RenderDiagnosticDetails(Stream &stream,
// characters. In the future it might make sense to move this into
// Host so it can be customized for a specific platform.
llvm::StringRef cursor, underline, vbar, joint, hbar, spacer;
if (stream.AsRawOstream().colors_enabled()) {
if (TerminalSupportsUnicode()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is long overdue!

cursor = "˄";
underline = "˜";
vbar = "│";
Expand Down Expand Up @@ -232,4 +232,19 @@ void RenderDiagnosticDetails(Stream &stream,
}
}

bool TerminalSupportsUnicode() {
static std::optional<bool> result;
if (result)
return result.value();
#ifndef _WIN32
if (const char *lang_var = std::getenv("LANG"))
result = std::string(lang_var).find("UTF-8");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result = std::string(lang_var).find("UTF-8");
result = llvm::StringRef(lang_var).find("UTF-8");

else
result = false;
#else
result = std::getenv("WT_SESSION") != nullptr;
#endif
return result.value();
}
Comment on lines +235 to +248
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this be correct for Xcode and DAP?


} // namespace lldb_private
Loading