[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-27 Thread Michael Christensen via lldb-commits

https://github.com/mdko created https://github.com/llvm/llvm-project/pull/73596

We'd like a way to select the current thread by its thread ID (rather than its 
internal LLDB thread index).

This PR adds a `-t` option (`--thread_id` long option) that tells the `thread 
select` command to interpret the `` argument as a thread ID.

Here's an example of it working:
```
michristensen@devbig356 llvm/llvm-project (thread-select-tid) » 
../Debug/bin/lldb ~/scratch/cpp/threading/a.out
(lldb) target create "/home/michristensen/scratch/cpp/threading/a.out"
Current executable set to '/home/michristensen/scratch/cpp/threading/a.out' 
(x86_64).
(lldb) b 18
Breakpoint 1: where = a.out`main + 80 at main.cpp:18:12, address = 
0x0850
(lldb) run
Process 215715 launched: '/home/michristensen/scratch/cpp/threading/a.out' 
(x86_64)
This is a thread, i=1
This is a thread, i=2
This is a thread, i=3
This is a thread, i=4
This is a thread, i=5
Process 215715 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;
(lldb) thread select 2
* thread #2, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread info
thread #2: tid = 216047, 0x768f9918 libc.so.6`__nanosleep + 72, name = 
'a.out'

(lldb) thread list
Process 215715 stopped
  thread #1: tid = 215715, 0x55400850 a.out`main at main.cpp:18:12, 
name = 'a.out', stop reason = breakpoint 1.1
* thread #2: tid = 216047, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #3: tid = 216048, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #4: tid = 216049, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #5: tid = 216050, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #6: tid = 216051, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
(lldb) thread select 215715
error: invalid thread #215715.
(lldb) thread select -t 215715
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;
(lldb) thread select -t 216051
* thread #6, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread select 3
* thread #3, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread select -t 216048
* thread #3, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread select --thread_id 216048
* thread #3, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) help thread select
Change the currently selected thread.

Syntax: thread select  

Command Options Usage:
  thread select [-t] 

   -t ( --thread_id )
Provide a thread ID instead of a thread index.

 This command takes options and free-form arguments.  If your arguments
 resemble option specifiers (i.e., they start with a - or --), you must use
 ' -- ' between the end of the command options and the beginning of the
 arguments.
(lldb) c
Process 215715 resuming
Process 215715 exited with status = 0 (0x)
```

>From 97a6e23c85457a14c91c5800fa03bb872e6f1fa6 Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Mon, 27 Nov 2023 12:49:24 -0800
Subject: [PATCH] Add option to pass thread ID to t

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-27 Thread Michael Christensen via lldb-commits

mdko wrote:

CC @jeffreytan81 @clayborg

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-28 Thread Michael Christensen via lldb-commits

mdko wrote:

@jimingham So it seems that when `-t ` is supplied, the user shouldn't be 
able to specify a thread index as well, e.g. the following is disallowed:
```
thread select -t 216051 1
```

Would it make sense then for `thread select` to take two possible mutually 
exclusive options (`-t `) and (`-i `), with the `-i` option being 
the default (i.e. doesn't need to be specified)? e.g.
```
thread select -t 216051
```

and
```
thread select -i 1
thread select 1
```
(where the `-i` doesn't need to be supplied by default)?


> It makes the completer much easier to hook up since the option value can 
> complete against the native thread ID's
Sounds good, I'll work on adding the complete for the native thread ID option 
with the above change.

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-28 Thread Michael Christensen via lldb-commits

https://github.com/mdko updated https://github.com/llvm/llvm-project/pull/73596

>From 97a6e23c85457a14c91c5800fa03bb872e6f1fa6 Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Mon, 27 Nov 2023 12:49:24 -0800
Subject: [PATCH 1/2] Add option to pass thread ID to thread select command

---
 lldb/source/Commands/CommandObjectThread.cpp  | 59 +--
 lldb/source/Commands/Options.td   |  5 ++
 .../thread/select/TestThreadSelect.py | 23 +++-
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index a9f5a4f8a4fbd71..9384df319cc221d 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1129,8 +1129,44 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
 
 // CommandObjectThreadSelect
 
+#define LLDB_OPTIONS_thread_select
+#include "CommandOptions.inc"
+
 class CommandObjectThreadSelect : public CommandObjectParsed {
 public:
+  class CommandOptions : public Options {
+  public:
+CommandOptions() { OptionParsingStarting(nullptr); }
+
+~CommandOptions() override = default;
+
+void OptionParsingStarting(ExecutionContext *execution_context) override {
+  m_thread_id = false;
+}
+
+Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+  ExecutionContext *execution_context) override {
+  const int short_option = m_getopt_table[option_idx].val;
+  switch (short_option) {
+  case 't': {
+m_thread_id = true;
+break;
+  }
+
+  default:
+llvm_unreachable("Unimplemented option");
+  }
+
+  return {};
+}
+
+llvm::ArrayRef GetDefinitions() override {
+  return llvm::ArrayRef(g_thread_select_options);
+}
+
+bool m_thread_id;
+  };
+
   CommandObjectThreadSelect(CommandInterpreter &interpreter)
   : CommandObjectParsed(interpreter, "thread select",
 "Change the currently selected thread.", nullptr,
@@ -1165,6 +1201,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 nullptr);
   }
 
+  Options *GetOptions() override { return &m_options; }
+
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
 Process *process = m_exe_ctx.GetProcessPtr();
@@ -1173,22 +1211,29 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
   return;
 } else if (command.GetArgumentCount() != 1) {
   result.AppendErrorWithFormat(
-  "'%s' takes exactly one thread index argument:\nUsage: %s\n",
-  m_cmd_name.c_str(), m_cmd_syntax.c_str());
+  "'%s' takes exactly one thread %s argument:\nUsage: %s\n",
+  m_cmd_name.c_str(), m_options.m_thread_id ? "ID" : "index",
+  m_cmd_syntax.c_str());
   return;
 }
 
 uint32_t index_id;
 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
-  result.AppendErrorWithFormat("Invalid thread index '%s'",
+  result.AppendErrorWithFormat("Invalid thread %s '%s'",
+   m_options.m_thread_id ? "ID" : "index",
command.GetArgumentAtIndex(0));
   return;
 }
 
-Thread *new_thread =
-process->GetThreadList().FindThreadByIndexID(index_id).get();
+Thread *new_thread = nullptr;
+if (m_options.m_thread_id) {
+new_thread = process->GetThreadList().FindThreadByID(index_id).get();
+} else {
+new_thread = 
process->GetThreadList().FindThreadByIndexID(index_id).get();
+}
 if (new_thread == nullptr) {
-  result.AppendErrorWithFormat("invalid thread #%s.\n",
+  result.AppendErrorWithFormat("invalid thread %s%s.\n",
+   m_options.m_thread_id ? "ID " : "#",
command.GetArgumentAtIndex(0));
   return;
 }
@@ -1196,6 +1241,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
 result.SetStatus(eReturnStatusSuccessFinishNoResult);
   }
+
+  CommandOptions m_options;
 };
 
 // CommandObjectThreadList
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 542c78be5a12dad..23886046df8f673 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
 Desc<"Display thread plans for unreported threads">;
 }
 
+let Command = "thread select" in {
+  def thread_thread_id : Option<"thread_id", "t">,
+Desc<"Provide a thread ID instead of a thread index.">;
+}
+
 let Command = "thread trace dump function calls" in {
   def thread_trace_dump_function_calls_file : Option<"file", "F">, Group<1>,
 Arg<"Filename">,
diff --git a/lldb/test/API/commands/thread/select/TestThreadSelect.py 
b/lldb/test/AP

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-28 Thread Michael Christensen via lldb-commits

https://github.com/mdko updated https://github.com/llvm/llvm-project/pull/73596

>From 97a6e23c85457a14c91c5800fa03bb872e6f1fa6 Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Mon, 27 Nov 2023 12:49:24 -0800
Subject: [PATCH 1/3] Add option to pass thread ID to thread select command

---
 lldb/source/Commands/CommandObjectThread.cpp  | 59 +--
 lldb/source/Commands/Options.td   |  5 ++
 .../thread/select/TestThreadSelect.py | 23 +++-
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index a9f5a4f8a4fbd71..9384df319cc221d 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1129,8 +1129,44 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
 
 // CommandObjectThreadSelect
 
+#define LLDB_OPTIONS_thread_select
+#include "CommandOptions.inc"
+
 class CommandObjectThreadSelect : public CommandObjectParsed {
 public:
+  class CommandOptions : public Options {
+  public:
+CommandOptions() { OptionParsingStarting(nullptr); }
+
+~CommandOptions() override = default;
+
+void OptionParsingStarting(ExecutionContext *execution_context) override {
+  m_thread_id = false;
+}
+
+Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+  ExecutionContext *execution_context) override {
+  const int short_option = m_getopt_table[option_idx].val;
+  switch (short_option) {
+  case 't': {
+m_thread_id = true;
+break;
+  }
+
+  default:
+llvm_unreachable("Unimplemented option");
+  }
+
+  return {};
+}
+
+llvm::ArrayRef GetDefinitions() override {
+  return llvm::ArrayRef(g_thread_select_options);
+}
+
+bool m_thread_id;
+  };
+
   CommandObjectThreadSelect(CommandInterpreter &interpreter)
   : CommandObjectParsed(interpreter, "thread select",
 "Change the currently selected thread.", nullptr,
@@ -1165,6 +1201,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 nullptr);
   }
 
+  Options *GetOptions() override { return &m_options; }
+
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
 Process *process = m_exe_ctx.GetProcessPtr();
@@ -1173,22 +1211,29 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
   return;
 } else if (command.GetArgumentCount() != 1) {
   result.AppendErrorWithFormat(
-  "'%s' takes exactly one thread index argument:\nUsage: %s\n",
-  m_cmd_name.c_str(), m_cmd_syntax.c_str());
+  "'%s' takes exactly one thread %s argument:\nUsage: %s\n",
+  m_cmd_name.c_str(), m_options.m_thread_id ? "ID" : "index",
+  m_cmd_syntax.c_str());
   return;
 }
 
 uint32_t index_id;
 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
-  result.AppendErrorWithFormat("Invalid thread index '%s'",
+  result.AppendErrorWithFormat("Invalid thread %s '%s'",
+   m_options.m_thread_id ? "ID" : "index",
command.GetArgumentAtIndex(0));
   return;
 }
 
-Thread *new_thread =
-process->GetThreadList().FindThreadByIndexID(index_id).get();
+Thread *new_thread = nullptr;
+if (m_options.m_thread_id) {
+new_thread = process->GetThreadList().FindThreadByID(index_id).get();
+} else {
+new_thread = 
process->GetThreadList().FindThreadByIndexID(index_id).get();
+}
 if (new_thread == nullptr) {
-  result.AppendErrorWithFormat("invalid thread #%s.\n",
+  result.AppendErrorWithFormat("invalid thread %s%s.\n",
+   m_options.m_thread_id ? "ID " : "#",
command.GetArgumentAtIndex(0));
   return;
 }
@@ -1196,6 +1241,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
 result.SetStatus(eReturnStatusSuccessFinishNoResult);
   }
+
+  CommandOptions m_options;
 };
 
 // CommandObjectThreadList
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 542c78be5a12dad..23886046df8f673 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
 Desc<"Display thread plans for unreported threads">;
 }
 
+let Command = "thread select" in {
+  def thread_thread_id : Option<"thread_id", "t">,
+Desc<"Provide a thread ID instead of a thread index.">;
+}
+
 let Command = "thread trace dump function calls" in {
   def thread_trace_dump_function_calls_file : Option<"file", "F">, Group<1>,
 Arg<"Filename">,
diff --git a/lldb/test/API/commands/thread/select/TestThreadSelect.py 
b/lldb/test/AP

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-28 Thread Michael Christensen via lldb-commits

mdko wrote:

[Latest 
changes](https://github.com/llvm/llvm-project/pull/73596/commits/34045b9b2e04e01fed142ad2d7f4503e69646c9f)
 implement reviewer suggestions:
* `thread_id` option is now `thread-id`
*  This option takes a value rather than causing original argument to be 
interpreted differently
* This option is now in a separate grouping, so we can show the two separate 
ways of calling this command: `thread select ` and ` thread 
select [-t ]`. This is similar to what shows up with `memory write 
...`

Example usage:
```
michristensen@devbig356 llvm/Debug » ./bin/lldb ~/scratch/cpp/virtual/a.out
error: module importing failed: This script interpreter does not support 
importing modules.
NAME PASS STOP NOTIFY
===  ===  ===  ===
SIGPIPE  true falsefalse
(lldb) target create "/home/michristensen/scratch/cpp/virtual/a.out"
Current executable set to '/home/michristensen/scratch/cpp/virtual/a.out' 
(x86_64).
(lldb) b 18
Breakpoint 1: where = a.out`main + 13 at t2.cpp:20:14, address = 
0x0c2d
(lldb) ^D
michristensen@devbig356 llvm/Debug »
michristensen@devbig356 llvm/Debug » ./bin/lldb ~/scratch/cpp/threading/a.out
error: module importing failed: This script interpreter does not support 
importing modules.
NAME PASS STOP NOTIFY
===  ===  ===  ===
SIGPIPE  true falsefalse
(lldb) target create "/home/michristensen/scratch/cpp/threading/a.out"
Current executable set to '/home/michristensen/scratch/cpp/threading/a.out' 
(x86_64).
(lldb) b 18
Breakpoint 1: where = a.out`main + 80 at main.cpp:18:12, address = 
0x0850
(lldb) run
Process 3517265 launched: '/home/michristensen/scratch/cpp/threading/a.out' 
(x86_64)
This is a thread, i=1
This is a thread, i=2
This is a thread, i=3
This is a thread, i=4
This is a thread, i=5
Process 3517265 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;
(lldb) thread select 2
* thread #2, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread info
thread #2: tid = 3517533, 0x768f9918 libc.so.6`__nanosleep + 72, name = 
'a.out'

(lldb) thread list
Process 3517265 stopped
  thread #1: tid = 3517265, 0x55400850 a.out`main at main.cpp:18:12, 
name = 'a.out', stop reason = breakpoint 1.1
* thread #2: tid = 3517533, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #3: tid = 3517534, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #4: tid = 3517535, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #5: tid = 3517536, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #6: tid = 3517537, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
(lldb) thread select 3517265
error: Invalid thread #3517265.
(lldb) thread select -t 3517265
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;
(lldb) thread select -t 3517534
* thread #3, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread select 6
* thread #6, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread info
thread #6: tid = 3517537, 0x768f9918 libc.so.6`__nanosleep + 72, name = 
'a.out'

(lldb) thread select -t 3517536
* thread #5, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)
(lldb) thread info
thread #5: tid = 3517536, 0x768f9918 libc.s

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-28 Thread Michael Christensen via lldb-commits


@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
 Desc<"Display thread plans for unreported threads">;
 }
 
+let Command = "thread select" in {
+  def thread_select_thread_id : Option<"thread-id", "t">, Group<2>,
+Arg<"ThreadID">, Desc<"Provide a thread ID instead of a thread index.">;

mdko wrote:

Yes it's a uint64_t:

https://github.com/llvm/llvm-project/blob/35db35b7cfb80139ab6f23c7f10c47df5d1d7462/lldb/include/lldb/lldb-types.h#L82

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-28 Thread Michael Christensen via lldb-commits

https://github.com/mdko edited https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-28 Thread Michael Christensen via lldb-commits


@@ -1165,37 +1208,59 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 nullptr);
   }
 
+  Options *GetOptions() override { return &m_option_group; }
+
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
 Process *process = m_exe_ctx.GetProcessPtr();
 if (process == nullptr) {
   result.AppendError("no process");
   return;
-} else if (command.GetArgumentCount() != 1) {
+} else if (m_options.m_thread_id == LLDB_INVALID_THREAD_ID &&
+   command.GetArgumentCount() != 1) {
   result.AppendErrorWithFormat(
-  "'%s' takes exactly one thread index argument:\nUsage: %s\n",
+  "'%s' takes exactly one thread index argument, or a thread ID "
+  "option:\nUsage: %s\n",
   m_cmd_name.c_str(), m_cmd_syntax.c_str());
   return;
-}
-
-uint32_t index_id;
-if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
-  result.AppendErrorWithFormat("Invalid thread index '%s'",
-   command.GetArgumentAtIndex(0));
+} else if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID &&
+   command.GetArgumentCount() != 0) {
+  result.AppendErrorWithFormat("'%s' cannot take both a thread ID option "
+   "and a thread index argument:\nUsage: %s\n",
+   m_cmd_name.c_str(), m_cmd_syntax.c_str());
   return;
 }
 
-Thread *new_thread =
-process->GetThreadList().FindThreadByIndexID(index_id).get();
-if (new_thread == nullptr) {
-  result.AppendErrorWithFormat("invalid thread #%s.\n",
-   command.GetArgumentAtIndex(0));
-  return;
+Thread *new_thread = nullptr;
+if (command.GetArgumentCount() == 1) {
+  uint32_t index_id;
+  if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
+result.AppendErrorWithFormat("Invalid thread index '%s'",
+ command.GetArgumentAtIndex(0));
+return;
+  }
+  new_thread = 
process->GetThreadList().FindThreadByIndexID(index_id).get();
+  if (new_thread == nullptr) {
+result.AppendErrorWithFormat("Invalid thread #%s.\n",
+ command.GetArgumentAtIndex(0));
+return;
+  }
+} else {
+  new_thread =
+  process->GetThreadList().FindThreadByID(m_options.m_thread_id).get();
+  if (new_thread == nullptr) {
+result.AppendErrorWithFormat("Invalid thread ID %lu.\n",

mdko wrote:

Thread IDs are shown as unsigned decimal, e.g.:
```
(lldb) thread list
Process 2291372 stopped
  thread #1: tid = 2291372, 0x55400850 a.out`main at main.cpp:18:12, 
name = 'a.out', stop reason = breakpoint 1.1
* thread #2: tid = 2291686, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #3: tid = 2291688, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #4: tid = 2291690, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #5: tid = 2291691, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #6: tid = 2291692, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
```

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-29 Thread Michael Christensen via lldb-commits

https://github.com/mdko updated https://github.com/llvm/llvm-project/pull/73596

>From 97a6e23c85457a14c91c5800fa03bb872e6f1fa6 Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Mon, 27 Nov 2023 12:49:24 -0800
Subject: [PATCH 1/4] Add option to pass thread ID to thread select command

---
 lldb/source/Commands/CommandObjectThread.cpp  | 59 +--
 lldb/source/Commands/Options.td   |  5 ++
 .../thread/select/TestThreadSelect.py | 23 +++-
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index a9f5a4f8a4fbd71..9384df319cc221d 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1129,8 +1129,44 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
 
 // CommandObjectThreadSelect
 
+#define LLDB_OPTIONS_thread_select
+#include "CommandOptions.inc"
+
 class CommandObjectThreadSelect : public CommandObjectParsed {
 public:
+  class CommandOptions : public Options {
+  public:
+CommandOptions() { OptionParsingStarting(nullptr); }
+
+~CommandOptions() override = default;
+
+void OptionParsingStarting(ExecutionContext *execution_context) override {
+  m_thread_id = false;
+}
+
+Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+  ExecutionContext *execution_context) override {
+  const int short_option = m_getopt_table[option_idx].val;
+  switch (short_option) {
+  case 't': {
+m_thread_id = true;
+break;
+  }
+
+  default:
+llvm_unreachable("Unimplemented option");
+  }
+
+  return {};
+}
+
+llvm::ArrayRef GetDefinitions() override {
+  return llvm::ArrayRef(g_thread_select_options);
+}
+
+bool m_thread_id;
+  };
+
   CommandObjectThreadSelect(CommandInterpreter &interpreter)
   : CommandObjectParsed(interpreter, "thread select",
 "Change the currently selected thread.", nullptr,
@@ -1165,6 +1201,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 nullptr);
   }
 
+  Options *GetOptions() override { return &m_options; }
+
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
 Process *process = m_exe_ctx.GetProcessPtr();
@@ -1173,22 +1211,29 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
   return;
 } else if (command.GetArgumentCount() != 1) {
   result.AppendErrorWithFormat(
-  "'%s' takes exactly one thread index argument:\nUsage: %s\n",
-  m_cmd_name.c_str(), m_cmd_syntax.c_str());
+  "'%s' takes exactly one thread %s argument:\nUsage: %s\n",
+  m_cmd_name.c_str(), m_options.m_thread_id ? "ID" : "index",
+  m_cmd_syntax.c_str());
   return;
 }
 
 uint32_t index_id;
 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
-  result.AppendErrorWithFormat("Invalid thread index '%s'",
+  result.AppendErrorWithFormat("Invalid thread %s '%s'",
+   m_options.m_thread_id ? "ID" : "index",
command.GetArgumentAtIndex(0));
   return;
 }
 
-Thread *new_thread =
-process->GetThreadList().FindThreadByIndexID(index_id).get();
+Thread *new_thread = nullptr;
+if (m_options.m_thread_id) {
+new_thread = process->GetThreadList().FindThreadByID(index_id).get();
+} else {
+new_thread = 
process->GetThreadList().FindThreadByIndexID(index_id).get();
+}
 if (new_thread == nullptr) {
-  result.AppendErrorWithFormat("invalid thread #%s.\n",
+  result.AppendErrorWithFormat("invalid thread %s%s.\n",
+   m_options.m_thread_id ? "ID " : "#",
command.GetArgumentAtIndex(0));
   return;
 }
@@ -1196,6 +1241,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
 result.SetStatus(eReturnStatusSuccessFinishNoResult);
   }
+
+  CommandOptions m_options;
 };
 
 // CommandObjectThreadList
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 542c78be5a12dad..23886046df8f673 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
 Desc<"Display thread plans for unreported threads">;
 }
 
+let Command = "thread select" in {
+  def thread_thread_id : Option<"thread_id", "t">,
+Desc<"Provide a thread ID instead of a thread index.">;
+}
+
 let Command = "thread trace dump function calls" in {
   def thread_trace_dump_function_calls_file : Option<"file", "F">, Group<1>,
 Arg<"Filename">,
diff --git a/lldb/test/API/commands/thread/select/TestThreadSelect.py 
b/lldb/test/AP

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-29 Thread Michael Christensen via lldb-commits

https://github.com/mdko updated https://github.com/llvm/llvm-project/pull/73596

>From 97a6e23c85457a14c91c5800fa03bb872e6f1fa6 Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Mon, 27 Nov 2023 12:49:24 -0800
Subject: [PATCH 1/5] Add option to pass thread ID to thread select command

---
 lldb/source/Commands/CommandObjectThread.cpp  | 59 +--
 lldb/source/Commands/Options.td   |  5 ++
 .../thread/select/TestThreadSelect.py | 23 +++-
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index a9f5a4f8a4fbd71..9384df319cc221d 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1129,8 +1129,44 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
 
 // CommandObjectThreadSelect
 
+#define LLDB_OPTIONS_thread_select
+#include "CommandOptions.inc"
+
 class CommandObjectThreadSelect : public CommandObjectParsed {
 public:
+  class CommandOptions : public Options {
+  public:
+CommandOptions() { OptionParsingStarting(nullptr); }
+
+~CommandOptions() override = default;
+
+void OptionParsingStarting(ExecutionContext *execution_context) override {
+  m_thread_id = false;
+}
+
+Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+  ExecutionContext *execution_context) override {
+  const int short_option = m_getopt_table[option_idx].val;
+  switch (short_option) {
+  case 't': {
+m_thread_id = true;
+break;
+  }
+
+  default:
+llvm_unreachable("Unimplemented option");
+  }
+
+  return {};
+}
+
+llvm::ArrayRef GetDefinitions() override {
+  return llvm::ArrayRef(g_thread_select_options);
+}
+
+bool m_thread_id;
+  };
+
   CommandObjectThreadSelect(CommandInterpreter &interpreter)
   : CommandObjectParsed(interpreter, "thread select",
 "Change the currently selected thread.", nullptr,
@@ -1165,6 +1201,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 nullptr);
   }
 
+  Options *GetOptions() override { return &m_options; }
+
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
 Process *process = m_exe_ctx.GetProcessPtr();
@@ -1173,22 +1211,29 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
   return;
 } else if (command.GetArgumentCount() != 1) {
   result.AppendErrorWithFormat(
-  "'%s' takes exactly one thread index argument:\nUsage: %s\n",
-  m_cmd_name.c_str(), m_cmd_syntax.c_str());
+  "'%s' takes exactly one thread %s argument:\nUsage: %s\n",
+  m_cmd_name.c_str(), m_options.m_thread_id ? "ID" : "index",
+  m_cmd_syntax.c_str());
   return;
 }
 
 uint32_t index_id;
 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
-  result.AppendErrorWithFormat("Invalid thread index '%s'",
+  result.AppendErrorWithFormat("Invalid thread %s '%s'",
+   m_options.m_thread_id ? "ID" : "index",
command.GetArgumentAtIndex(0));
   return;
 }
 
-Thread *new_thread =
-process->GetThreadList().FindThreadByIndexID(index_id).get();
+Thread *new_thread = nullptr;
+if (m_options.m_thread_id) {
+new_thread = process->GetThreadList().FindThreadByID(index_id).get();
+} else {
+new_thread = 
process->GetThreadList().FindThreadByIndexID(index_id).get();
+}
 if (new_thread == nullptr) {
-  result.AppendErrorWithFormat("invalid thread #%s.\n",
+  result.AppendErrorWithFormat("invalid thread %s%s.\n",
+   m_options.m_thread_id ? "ID " : "#",
command.GetArgumentAtIndex(0));
   return;
 }
@@ -1196,6 +1241,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
 result.SetStatus(eReturnStatusSuccessFinishNoResult);
   }
+
+  CommandOptions m_options;
 };
 
 // CommandObjectThreadList
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 542c78be5a12dad..23886046df8f673 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
 Desc<"Display thread plans for unreported threads">;
 }
 
+let Command = "thread select" in {
+  def thread_thread_id : Option<"thread_id", "t">,
+Desc<"Provide a thread ID instead of a thread index.">;
+}
+
 let Command = "thread trace dump function calls" in {
   def thread_trace_dump_function_calls_file : Option<"file", "F">, Group<1>,
 Arg<"Filename">,
diff --git a/lldb/test/API/commands/thread/select/TestThreadSelect.py 
b/lldb/test/AP

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-29 Thread Michael Christensen via lldb-commits

mdko wrote:

[Latest changes]() update help and usage text, format specifier, add a general 
thread ID completion mechanism, and use this thread ID completion in the 
`thread select -t` argument. (If the thread ID completer is satisfactory, I can 
add it to other ThreadID args in 
[Options.td](https://github.com/mdko/llvm-project/blob/main/lldb/source/Commands/Options.td)
 in a later PR.)

Example:
```
michristensen@devbig356 llvm/Debug » ./bin/lldb ~/scratch/cpp/threading/a.out
NAME PASS STOP NOTIFY
===  ===  ===  ===
SIGPIPE  true falsefalse
(lldb) target create "/home/michristensen/scratch/cpp/threading/a.out"
Current executable set to '/home/michristensen/scratch/cpp/threading/a.out' 
(x86_64).
(lldb) b 18
Breakpoint 1: where = a.out`main + 80 at main.cpp:18:12, address = 
0x0850
(lldb) run
Process 2749371 launched: '/home/michristensen/scratch/cpp/threading/a.out' 
(x86_64)
This is a thread, i=1
This is a thread, i=2
This is a thread, i=3
This is a thread, i=4
This is a thread, i=5
Process 2749371 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;
(lldb) thread list
Process 2749371 stopped
* thread #1: tid = 2749371, 0x55400850 a.out`main at main.cpp:18:12, 
name = 'a.out', stop reason = breakpoint 1.1
  thread #2: tid = 2749646, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #3: tid = 2749647, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #4: tid = 2749648, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #5: tid = 2749649, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
  thread #6: tid = 2749650, 0x768f9918 libc.so.6`__nanosleep + 72, name 
= 'a.out'
(lldb) thread select -t 2749
Available completions:
2749371 -- * thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;

2749646 --   thread #2, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)

2749647 --   thread #3, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)

2749648 --   thread #4, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)

2749649 --   thread #5, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)

2749650 --   thread #6, name = 'a.out'
frame #0: 0x768f9918 libc.so.6`__nanosleep + 72
libc.so.6`__nanosleep:
->  0x768f9918 <+72>: cmpq   $-0x1000, %rax ; imm = 0xF000
0x768f991e <+78>: ja 0x768f9952 ; <+130>
0x768f9920 <+80>: movl   %edx, %edi
0x768f9922 <+82>: movl   %eax, 0xc(%rsp)

(lldb) thread select -t 2749371
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;
(lldb) thread select
Available completions:
1 -- * thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x55400850 a.out`main at main.cpp:18:12
   15 for (int i = 0; i < 5; i++) {
   16   pthread_create(&thread_ids[i], NULL, foo, NULL);
   17 }
-> 18 for (int i = 0; i < 5; i++) {
   19   pthread_join(thread_ids[i], NULL);
   20 }
   21 return 0;

 

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-29 Thread Michael Christensen via lldb-commits


@@ -807,6 +808,23 @@ void 
CommandCompletions::TypeCategoryNames(CommandInterpreter &interpreter,
   });
 }
 
+void CommandCompletions::ThreadIDs(CommandInterpreter &interpreter,
+   CompletionRequest &request,
+   SearchFilter *searcher) {
+  const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+  if (!exe_ctx.HasProcessScope())
+return;
+
+  ThreadList &threads = exe_ctx.GetProcessPtr()->GetThreadList();
+  lldb::ThreadSP thread_sp;
+  for (uint32_t idx = 0; (thread_sp = threads.GetThreadAtIndex(idx)); ++idx) {

mdko wrote:

It's to avoid this warning:
```
/home/michristensen/llvm/llvm-project/lldb/source/Commands/CommandCompletions.cpp:820:36:
 warning: using the result of an assignment as a condition without parentheses 
[-Wparentheses]
  for (uint32_t idx = 0; thread_sp = threads.GetThreadAtIndex(idx); ++idx) {
 ~~^~~
/home/michristensen/llvm/llvm-project/lldb/source/Commands/CommandCompletions.cpp:820:36:
 note: place parentheses around the assignment to silence this warning
  for (uint32_t idx = 0; thread_sp = threads.GetThreadAtIndex(idx); ++idx) {
```

It's also consistent to how it was done in the ThreadIndex completer code:
https://github.com/llvm/llvm-project/blob/e109a2ea37b20141aad8c4db4d39ff56e8a6dc4e/lldb/source/Commands/CommandCompletions.cpp#L776

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-11-30 Thread Michael Christensen via lldb-commits


@@ -1296,10 +1296,11 @@ enum CompletionType {
   eRemoteDiskFileCompletion = (1u << 22),
   eRemoteDiskDirectoryCompletion = (1u << 23),
   eTypeCategoryNameCompletion = (1u << 24),
+  eThreadIDCompletion = (1u << 25),

mdko wrote:

@clayborg Is there anything special about `eCustomCompletion` being last? The 
comment in 1300-1302 seems to allude to this, but I don't see anything in the 
code base requiring this nor any other custom completions.

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-12-04 Thread Michael Christensen via lldb-commits


@@ -1296,10 +1296,11 @@ enum CompletionType {
   eRemoteDiskFileCompletion = (1u << 22),
   eRemoteDiskDirectoryCompletion = (1u << 23),
   eTypeCategoryNameCompletion = (1u << 24),
+  eThreadIDCompletion = (1u << 25),

mdko wrote:

@jimingham What are your thoughts on putting eThreadIDCompletion before 
eCustomCompletion? (See @clayborg 's comments above)

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-12-05 Thread Michael Christensen via lldb-commits

https://github.com/mdko updated https://github.com/llvm/llvm-project/pull/73596

>From 97a6e23c85457a14c91c5800fa03bb872e6f1fa6 Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Mon, 27 Nov 2023 12:49:24 -0800
Subject: [PATCH 1/6] Add option to pass thread ID to thread select command

---
 lldb/source/Commands/CommandObjectThread.cpp  | 59 +--
 lldb/source/Commands/Options.td   |  5 ++
 .../thread/select/TestThreadSelect.py | 23 +++-
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index a9f5a4f8a4fbd..9384df319cc22 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1129,8 +1129,44 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
 
 // CommandObjectThreadSelect
 
+#define LLDB_OPTIONS_thread_select
+#include "CommandOptions.inc"
+
 class CommandObjectThreadSelect : public CommandObjectParsed {
 public:
+  class CommandOptions : public Options {
+  public:
+CommandOptions() { OptionParsingStarting(nullptr); }
+
+~CommandOptions() override = default;
+
+void OptionParsingStarting(ExecutionContext *execution_context) override {
+  m_thread_id = false;
+}
+
+Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+  ExecutionContext *execution_context) override {
+  const int short_option = m_getopt_table[option_idx].val;
+  switch (short_option) {
+  case 't': {
+m_thread_id = true;
+break;
+  }
+
+  default:
+llvm_unreachable("Unimplemented option");
+  }
+
+  return {};
+}
+
+llvm::ArrayRef GetDefinitions() override {
+  return llvm::ArrayRef(g_thread_select_options);
+}
+
+bool m_thread_id;
+  };
+
   CommandObjectThreadSelect(CommandInterpreter &interpreter)
   : CommandObjectParsed(interpreter, "thread select",
 "Change the currently selected thread.", nullptr,
@@ -1165,6 +1201,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 nullptr);
   }
 
+  Options *GetOptions() override { return &m_options; }
+
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
 Process *process = m_exe_ctx.GetProcessPtr();
@@ -1173,22 +1211,29 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
   return;
 } else if (command.GetArgumentCount() != 1) {
   result.AppendErrorWithFormat(
-  "'%s' takes exactly one thread index argument:\nUsage: %s\n",
-  m_cmd_name.c_str(), m_cmd_syntax.c_str());
+  "'%s' takes exactly one thread %s argument:\nUsage: %s\n",
+  m_cmd_name.c_str(), m_options.m_thread_id ? "ID" : "index",
+  m_cmd_syntax.c_str());
   return;
 }
 
 uint32_t index_id;
 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
-  result.AppendErrorWithFormat("Invalid thread index '%s'",
+  result.AppendErrorWithFormat("Invalid thread %s '%s'",
+   m_options.m_thread_id ? "ID" : "index",
command.GetArgumentAtIndex(0));
   return;
 }
 
-Thread *new_thread =
-process->GetThreadList().FindThreadByIndexID(index_id).get();
+Thread *new_thread = nullptr;
+if (m_options.m_thread_id) {
+new_thread = process->GetThreadList().FindThreadByID(index_id).get();
+} else {
+new_thread = 
process->GetThreadList().FindThreadByIndexID(index_id).get();
+}
 if (new_thread == nullptr) {
-  result.AppendErrorWithFormat("invalid thread #%s.\n",
+  result.AppendErrorWithFormat("invalid thread %s%s.\n",
+   m_options.m_thread_id ? "ID " : "#",
command.GetArgumentAtIndex(0));
   return;
 }
@@ -1196,6 +1241,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
 result.SetStatus(eReturnStatusSuccessFinishNoResult);
   }
+
+  CommandOptions m_options;
 };
 
 // CommandObjectThreadList
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 542c78be5a12d..23886046df8f6 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
 Desc<"Display thread plans for unreported threads">;
 }
 
+let Command = "thread select" in {
+  def thread_thread_id : Option<"thread_id", "t">,
+Desc<"Provide a thread ID instead of a thread index.">;
+}
+
 let Command = "thread trace dump function calls" in {
   def thread_trace_dump_function_calls_file : Option<"file", "F">, Group<1>,
 Arg<"Filename">,
diff --git a/lldb/test/API/commands/thread/select/TestThreadSelect.py 
b/lldb/test/API/comman

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-12-05 Thread Michael Christensen via lldb-commits

mdko wrote:

Latest change:
* Reverts `eCustomCompletion` to original value
* Moves `eThreadIDCompletion` after `eCustomCompletion`
* Adds `eTerminatorCompletion` as last value in enum
* Sets all values to 64 bit to future-proof it

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-12-05 Thread Michael Christensen via lldb-commits

https://github.com/mdko updated https://github.com/llvm/llvm-project/pull/73596

>From 97a6e23c85457a14c91c5800fa03bb872e6f1fa6 Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Mon, 27 Nov 2023 12:49:24 -0800
Subject: [PATCH 1/7] Add option to pass thread ID to thread select command

---
 lldb/source/Commands/CommandObjectThread.cpp  | 59 +--
 lldb/source/Commands/Options.td   |  5 ++
 .../thread/select/TestThreadSelect.py | 23 +++-
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index a9f5a4f8a4fbd..9384df319cc22 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1129,8 +1129,44 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
 
 // CommandObjectThreadSelect
 
+#define LLDB_OPTIONS_thread_select
+#include "CommandOptions.inc"
+
 class CommandObjectThreadSelect : public CommandObjectParsed {
 public:
+  class CommandOptions : public Options {
+  public:
+CommandOptions() { OptionParsingStarting(nullptr); }
+
+~CommandOptions() override = default;
+
+void OptionParsingStarting(ExecutionContext *execution_context) override {
+  m_thread_id = false;
+}
+
+Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+  ExecutionContext *execution_context) override {
+  const int short_option = m_getopt_table[option_idx].val;
+  switch (short_option) {
+  case 't': {
+m_thread_id = true;
+break;
+  }
+
+  default:
+llvm_unreachable("Unimplemented option");
+  }
+
+  return {};
+}
+
+llvm::ArrayRef GetDefinitions() override {
+  return llvm::ArrayRef(g_thread_select_options);
+}
+
+bool m_thread_id;
+  };
+
   CommandObjectThreadSelect(CommandInterpreter &interpreter)
   : CommandObjectParsed(interpreter, "thread select",
 "Change the currently selected thread.", nullptr,
@@ -1165,6 +1201,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 nullptr);
   }
 
+  Options *GetOptions() override { return &m_options; }
+
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
 Process *process = m_exe_ctx.GetProcessPtr();
@@ -1173,22 +1211,29 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
   return;
 } else if (command.GetArgumentCount() != 1) {
   result.AppendErrorWithFormat(
-  "'%s' takes exactly one thread index argument:\nUsage: %s\n",
-  m_cmd_name.c_str(), m_cmd_syntax.c_str());
+  "'%s' takes exactly one thread %s argument:\nUsage: %s\n",
+  m_cmd_name.c_str(), m_options.m_thread_id ? "ID" : "index",
+  m_cmd_syntax.c_str());
   return;
 }
 
 uint32_t index_id;
 if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) {
-  result.AppendErrorWithFormat("Invalid thread index '%s'",
+  result.AppendErrorWithFormat("Invalid thread %s '%s'",
+   m_options.m_thread_id ? "ID" : "index",
command.GetArgumentAtIndex(0));
   return;
 }
 
-Thread *new_thread =
-process->GetThreadList().FindThreadByIndexID(index_id).get();
+Thread *new_thread = nullptr;
+if (m_options.m_thread_id) {
+new_thread = process->GetThreadList().FindThreadByID(index_id).get();
+} else {
+new_thread = 
process->GetThreadList().FindThreadByIndexID(index_id).get();
+}
 if (new_thread == nullptr) {
-  result.AppendErrorWithFormat("invalid thread #%s.\n",
+  result.AppendErrorWithFormat("invalid thread %s%s.\n",
+   m_options.m_thread_id ? "ID " : "#",
command.GetArgumentAtIndex(0));
   return;
 }
@@ -1196,6 +1241,8 @@ class CommandObjectThreadSelect : public 
CommandObjectParsed {
 process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
 result.SetStatus(eReturnStatusSuccessFinishNoResult);
   }
+
+  CommandOptions m_options;
 };
 
 // CommandObjectThreadList
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 542c78be5a12d..23886046df8f6 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1117,6 +1117,11 @@ let Command = "thread plan list" in {
 Desc<"Display thread plans for unreported threads">;
 }
 
+let Command = "thread select" in {
+  def thread_thread_id : Option<"thread_id", "t">,
+Desc<"Provide a thread ID instead of a thread index.">;
+}
+
 let Command = "thread trace dump function calls" in {
   def thread_trace_dump_function_calls_file : Option<"file", "F">, Group<1>,
 Arg<"Filename">,
diff --git a/lldb/test/API/commands/thread/select/TestThreadSelect.py 
b/lldb/test/API/comman

[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-12-05 Thread Michael Christensen via lldb-commits


@@ -1270,36 +1270,37 @@ enum WatchpointValueKind {
 };
 
 enum CompletionType {
-  eNoCompletion = 0u,
-  eSourceFileCompletion = (1u << 0),
-  eDiskFileCompletion = (1u << 1),
-  eDiskDirectoryCompletion = (1u << 2),
-  eSymbolCompletion = (1u << 3),
-  eModuleCompletion = (1u << 4),
-  eSettingsNameCompletion = (1u << 5),
-  ePlatformPluginCompletion = (1u << 6),
-  eArchitectureCompletion = (1u << 7),
-  eVariablePathCompletion = (1u << 8),
-  eRegisterCompletion = (1u << 9),
-  eBreakpointCompletion = (1u << 10),
-  eProcessPluginCompletion = (1u << 11),
-  eDisassemblyFlavorCompletion = (1u << 12),
-  eTypeLanguageCompletion = (1u << 13),
-  eFrameIndexCompletion = (1u << 14),
-  eModuleUUIDCompletion = (1u << 15),
-  eStopHookIDCompletion = (1u << 16),
-  eThreadIndexCompletion = (1u << 17),
-  eWatchpointIDCompletion = (1u << 18),
-  eBreakpointNameCompletion = (1u << 19),
-  eProcessIDCompletion = (1u << 20),
-  eProcessNameCompletion = (1u << 21),
-  eRemoteDiskFileCompletion = (1u << 22),
-  eRemoteDiskDirectoryCompletion = (1u << 23),
-  eTypeCategoryNameCompletion = (1u << 24),
-  // This item serves two purposes.  It is the last element in the enum, so
-  // you can add custom enums starting from here in your Option class. Also
-  // if you & in this bit the base code will not process the option.
-  eCustomCompletion = (1u << 25)
+  eNoCompletion = 0ul,
+  eSourceFileCompletion = (1ul << 0),
+  eDiskFileCompletion = (1ul << 1),
+  eDiskDirectoryCompletion = (1ul << 2),
+  eSymbolCompletion = (1ul << 3),
+  eModuleCompletion = (1ul << 4),
+  eSettingsNameCompletion = (1ul << 5),
+  ePlatformPluginCompletion = (1ul << 6),
+  eArchitectureCompletion = (1ul << 7),
+  eVariablePathCompletion = (1ul << 8),
+  eRegisterCompletion = (1ul << 9),
+  eBreakpointCompletion = (1ul << 10),
+  eProcessPluginCompletion = (1ul << 11),
+  eDisassemblyFlavorCompletion = (1ul << 12),
+  eTypeLanguageCompletion = (1ul << 13),
+  eFrameIndexCompletion = (1ul << 14),
+  eModuleUUIDCompletion = (1ul << 15),
+  eStopHookIDCompletion = (1ul << 16),
+  eThreadIndexCompletion = (1ul << 17),
+  eWatchpointIDCompletion = (1ul << 18),
+  eBreakpointNameCompletion = (1ul << 19),
+  eProcessIDCompletion = (1ul << 20),
+  eProcessNameCompletion = (1ul << 21),
+  eRemoteDiskFileCompletion = (1ul << 22),
+  eRemoteDiskDirectoryCompletion = (1ul << 23),
+  eTypeCategoryNameCompletion = (1ul << 24),
+  eCustomCompletion = (1ul << 25),
+  eThreadIDCompletion = (1ul << 26),
+  // This last enum element is just for input validation.
+  // Add new completions before this element.
+  eTerminatorCompletion = (1ul << 63)

mdko wrote:

@jimingham Thanks for the quick feedback, makes sense. Latest changes update 
`eTerminatorCompletion` value based on your comments.

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add option to pass thread ID to thread select command (PR #73596)

2023-12-14 Thread Michael Christensen via lldb-commits

mdko wrote:

@jimingham @clayborg IIUC I don't have merge permissions, otherwise I'd squash 
and merge this myself. Please let me know if there's anything I should do at 
this point. Thanks!

https://github.com/llvm/llvm-project/pull/73596
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [easy] Fix spacing in help message of 'process save-core' command (PR #89445)

2024-04-19 Thread Michael Christensen via lldb-commits

https://github.com/mdko created https://github.com/llvm/llvm-project/pull/89445

Very minor change to help message on `process save-core`. Adds space between 
two sentences explaining the `-p` option: 

"Specify a plugin name to create the core file.This allows core files to be 
saved in different formats." 
-->
"Specify a plugin name to create the core file. This allows core files to be 
saved in different formats."

Before:
```
(lldb) help process save-core
Save the current process as a core file using an appropriate file type.

Syntax: process save-core [-s corefile-style -p plugin-name] FILE

Command Options Usage:
  process save-core [-p[]] [-s ] 

   -p[] ( --plugin-name=[] )
Specify a plugin name to create the core file.This allows core 
files to be saved in different formats.

   -s  ( --style  )
Request a specific style of corefile to be saved.
Values: full | modified-memory | stack

 This command takes options and free-form arguments.  If your arguments 
resemble option specifiers (i.e., they start with a -
 or --), you must use ' -- ' between the end of the command options and the 
beginning of the arguments.
```

After:
```
michristensen@devbig356 build/Debug » $HOME/llvm-sand/build/Debug/bin/lldb -x
(lldb) help process save-core
Save the current process as a core file using an appropriate file type.

Syntax: process save-core [-s corefile-style -p plugin-name] FILE

Command Options Usage:
  process save-core [-p[]] [-s ] 

   -p[] ( --plugin-name=[] )
Specify a plugin name to create the core file. This allows core 
files to be saved in different formats.

   -s  ( --style  )
Request a specific style of corefile to be saved.
Values: full | modified-memory | stack

 This command takes options and free-form arguments.  If your arguments 
resemble option specifiers (i.e., they start with a -
 or --), you must use ' -- ' between the end of the command options and the 
beginning of the arguments.
```

>From 38f81bc7c9581b2e5f8972b465c6b2461499437c Mon Sep 17 00:00:00 2001
From: Michael Christensen 
Date: Fri, 19 Apr 2024 11:54:45 -0700
Subject: [PATCH] fix spacing in help message of 'process save-core' command

---
 lldb/source/Commands/Options.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 62bbfdc117834f..00238d67d73215 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -784,7 +784,7 @@ let Command = "process save_core" in {
 EnumArg<"SaveCoreStyle">, Desc<"Request a specific style "
 "of corefile to be saved.">;
   def process_save_core_plugin_name : Option<"plugin-name", "p">,
-OptionalArg<"Plugin">, Desc<"Specify a plugin name to create the core 
file."
+OptionalArg<"Plugin">, Desc<"Specify a plugin name to create the core 
file. "
 "This allows core files to be saved in different formats.">;
 }
 

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits