Skip to content

Commit 220c17f

Browse files
committed
Print a warning when stopped in a frame LLDB has no plugin for.
This patchs adds an optional warning that is printed when stopped at a frame that was compiled in a source language that LLDB has no plugin for. The motivational use-case is debugging Swift code on Linux. When the user accidentally invokes the system LLDB that was built without the Swift plugin, it is very much non-obvious why debugging doesnt work. This warning makes it easy to figure out what went wrong. <rdar://problem/56986569>
1 parent 0231227 commit 220c17f

File tree

7 files changed

+62
-7
lines changed

7 files changed

+62
-7
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class ProcessProperties : public Properties {
8686
bool GetDetachKeepsStopped() const;
8787
void SetDetachKeepsStopped(bool keep_stopped);
8888
bool GetWarningsOptimization() const;
89+
bool GetWarningsUnsupportedLanguage() const;
8990
bool GetStopOnExec() const;
9091
std::chrono::seconds GetUtilityExpressionTimeout() const;
9192
bool GetOSPluginReportsAllThreads() const;
@@ -390,7 +391,7 @@ class Process : public std::enable_shared_from_this<Process>,
390391
};
391392

392393
/// Process warning types.
393-
enum Warnings { eWarningsOptimization = 1 };
394+
enum Warnings { eWarningsOptimization = 1, eWarningsUnsupportedLanguage = 2 };
394395

395396
typedef Range<lldb::addr_t, lldb::addr_t> LoadRange;
396397
// We use a read/write lock to allow on or more clients to access the process
@@ -1319,6 +1320,12 @@ class Process : public std::enable_shared_from_this<Process>,
13191320
/// pre-computed.
13201321
void PrintWarningOptimization(const SymbolContext &sc);
13211322

1323+
/// Print a user-visible warning about a function written in a
1324+
/// language that this version of LLDB doesn't support.
1325+
///
1326+
/// \see PrintWarningOptimization
1327+
void PrintWarningUnsupportedLanguage(const SymbolContext &sc);
1328+
13221329
virtual bool GetProcessInfo(ProcessInstanceInfo &info);
13231330

13241331
public:

lldb/source/Target/Process.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ bool ProcessProperties::GetWarningsOptimization() const {
258258
nullptr, idx, g_process_properties[idx].default_uint_value != 0);
259259
}
260260

261+
bool ProcessProperties::GetWarningsUnsupportedLanguage() const {
262+
const uint32_t idx = ePropertyWarningUnsupportedLanguage;
263+
return m_collection_sp->GetPropertyAtIndexAsBoolean(
264+
nullptr, idx, g_process_properties[idx].default_uint_value != 0);
265+
}
266+
261267
bool ProcessProperties::GetStopOnExec() const {
262268
const uint32_t idx = ePropertyStopOnExec;
263269
return m_collection_sp->GetPropertyAtIndexAsBoolean(
@@ -5779,9 +5785,6 @@ void Process::PrintWarning(uint64_t warning_type, const void *repeat_key,
57795785
StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
57805786
if (!stream_sp)
57815787
return;
5782-
if (warning_type == eWarningsOptimization && !GetWarningsOptimization()) {
5783-
return;
5784-
}
57855788

57865789
if (repeat_key != nullptr) {
57875790
WarningsCollection::iterator it = m_warnings_issued.find(warning_type);
@@ -5806,8 +5809,11 @@ void Process::PrintWarning(uint64_t warning_type, const void *repeat_key,
58065809
}
58075810

58085811
void Process::PrintWarningOptimization(const SymbolContext &sc) {
5809-
if (GetWarningsOptimization() && sc.module_sp &&
5810-
!sc.module_sp->GetFileSpec().GetFilename().IsEmpty() && sc.function &&
5812+
if (!GetWarningsOptimization())
5813+
return;
5814+
if (!sc.module_sp)
5815+
return;
5816+
if (!sc.module_sp->GetFileSpec().GetFilename().IsEmpty() && sc.function &&
58115817
sc.function->GetIsOptimized()) {
58125818
PrintWarning(Process::Warnings::eWarningsOptimization, sc.module_sp.get(),
58135819
"%s was compiled with optimization - stepping may behave "
@@ -5816,6 +5822,25 @@ void Process::PrintWarningOptimization(const SymbolContext &sc) {
58165822
}
58175823
}
58185824

5825+
void Process::PrintWarningUnsupportedLanguage(const SymbolContext &sc) {
5826+
if (!GetWarningsUnsupportedLanguage())
5827+
return;
5828+
if (!sc.module_sp)
5829+
return;
5830+
LanguageType language = sc.GetLanguage();
5831+
if (language == eLanguageTypeUnknown)
5832+
return;
5833+
auto type_system_or_err = sc.module_sp->GetTypeSystemForLanguage(language);
5834+
if (auto err = type_system_or_err.takeError()) {
5835+
llvm::consumeError(std::move(err));
5836+
PrintWarning(Process::Warnings::eWarningsUnsupportedLanguage,
5837+
sc.module_sp.get(),
5838+
"This version of LLDB has no plugin for the %s language. "
5839+
"Inspection of frame variables will be limited.\n",
5840+
Language::GetNameForLanguageType(language));
5841+
}
5842+
}
5843+
58195844
bool Process::GetProcessInfo(ProcessInstanceInfo &info) {
58205845
info.Clear();
58215846

lldb/source/Target/TargetProperties.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ let Definition = "process" in {
204204
def WarningOptimization: Property<"optimization-warnings", "Boolean">,
205205
DefaultTrue,
206206
Desc<"If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected.">;
207+
def WarningUnsupportedLanguage: Property<"unsupported-language-warnings", "Boolean">,
208+
DefaultTrue,
209+
Desc<"If true, warn when stopped in code that is written in a source language that LLDB does not support.">;
207210
def StopOnExec: Property<"stop-on-exec", "Boolean">,
208211
Global,
209212
DefaultTrue,

lldb/source/Target/Thread.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,13 @@ void Thread::FrameSelectedCallback(StackFrame *frame) {
326326
if (!frame)
327327
return;
328328

329-
if (frame->HasDebugInformation() && GetProcess()->GetWarningsOptimization()) {
329+
if (frame->HasDebugInformation() &&
330+
(GetProcess()->GetWarningsOptimization() ||
331+
GetProcess()->GetWarningsUnsupportedLanguage())) {
330332
SymbolContext sc =
331333
frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextModule);
332334
GetProcess()->PrintWarningOptimization(sc);
335+
GetProcess()->PrintWarningUnsupportedLanguage(sc);
333336
}
334337
}
335338

lldb/test/Shell/Process/Inputs/true.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int main(int argc, char **argv) {
2+
return 0;
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Test warnings.
2+
REQUIRES: shell
3+
RUN: %clang_host -O3 %S/Inputs/true.c -std=c99 -g -o %t.exe
4+
RUN: %lldb -o "b main" -o r -o q -b %t.exe | FileCheck %s
5+
6+
CHECK: compiled with optimization
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Test warnings.
2+
REQUIRES: shell
3+
RUN: %clang_host %S/Inputs/true.c -std=c99 -g -c -S -emit-llvm -o - \
4+
RUN: | sed -e 's/DW_LANG_C99/DW_LANG_PLI/g' >%t.ll
5+
RUN: %clang_host %t.ll -g -o %t.exe
6+
RUN: %lldb -o "b main" -o r -o q -b %t.exe | FileCheck %s
7+
8+
CHECK: This version of LLDB has no plugin for the pli language

0 commit comments

Comments
 (0)