<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/121715>121715</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [lldb] Interactive command line interface nonfunctional on Windows with cross-platform libedit
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          lulle2007200
      </td>
    </tr>
</table>

<pre>
    I have built LLDB 19.1.6 on windows with libedit support using this cross-platform libedit port: [https://github.com/michaeljclark/libedit](https://github.com/michaeljclark/libedit).

Here is the cmake command used:

```
cmake -S llvm -B build -G Ninja `
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX="install" `
-DCMAKE_CXX_COMPILER=cl -DCMAKE_C_COMPILER=cl `
-DLLDB_EMBED_PYTHON_HOME=0 `
-DLLVM_ENABLE_PROJECTS="lldb;clang" `
-DLLDB_INCLUDE_TESTS=Off `
-DLLDB_ENABLE_LIBEDIT=On `
-DLLDB_ENABLE_CURSES=Off `
-DLLDB_ENABLE_LZMA=Off `
-DLLDB_ENABLE_LIBXML2=Off `
-DLLDB_ENABLE_PYTHON=Off `
-DLLDB_ENABLE_LUA=Off `
-DLibEdit_LIBRARIES="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\Crypt32.Lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\Winmm.Lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\UserEnv.Lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\Secur32.Lib;C:\Users\Christoph\Dev\libedit\install\lib\edit.lib;C:\libedit\install\lib\compat.lib;C:\libedit\install\lib\regex.lib;C:\libedit\install\lib\terminfo.lib;C:\libedit\install\lib\edit.lib;C:\libedit\install\lib\pdcurses.lib" `
-DLibEdit_INCLUDE_DIRS="C:\libedit\libedit"
```

The `getline` function libedit provides in `libedit\compat\win32` is incomplete and doesn't return -1 on errors or when no characters were read and doesn't handle memory allocations. I have replaced it with the following:

```
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
   size_t lim = *n;
   size_t size = *n;
   char *s = *lineptr;

   if(s && !lim){
      abort();
   }

   if(!s){
 size = 0;
      lim = 0;
   }

   int c, i = 0;
   while (--lim > 0 && (c=fgetc(stream)) != EOF && c != '\n'){
      if(i >= size){
         size += 80;
         char *ptr = (char*)realloc(s, size);
         if(!ptr){
 goto error;
         }
         s = ptr;
      }
      s[i++] = c;
   }

   if (c == '\n'){
      if(i >= size){
         size += 80;
 char *ptr = (char*)realloc(s, size);
         if(!ptr){
 goto error;
         }
         s = ptr;
      }
      s[i++] = c;
 }

   if(i >= size){
      size += 80;
      char *ptr = (char*)realloc(s, size);
      if(!ptr){
         goto error;
      }
 s = ptr;
   }
   s[i] = '\0';

   *lineptr = s;
   *n = size;

 if(i){
      return i;
   }
   return -1;

   error:
   free(s);
 *lineptr = NULL;
   *n = 0;
   return -1;
}
```

Pretty ugly, but works.

The resulting lldb executable is not functional.
Launching and attaching to a process by pid (e.g. lldb --attach-pid xxxx) etc. works fine, but the interactive command line is non-functional and does not accept any user keyboard input (command line stays blank).

Here is a call stack when suspending lldb:

```
SelectHelper.cpp Line 228   C++ liblldb.dll!SelectHelper::Select() 
ConnectionFileDescriptorPosix.cpp Line 477  C++ liblldb.dll!lldb_private::ConnectionFileDescriptor::BytesAvailable(const lldb_private::Timeout<std::ratio<1,1000000>> & timeout, lldb_private::Status * error_ptr) 
ConnectionFileDescriptorPosix.cpp Line 272  C++ liblldb.dll!lldb_private::ConnectionFileDescriptor::Read(void * dst, unsigned __int64 dst_len, const lldb_private::Timeout<std::ratio<1,1000000>> & timeout, lldb::ConnectionStatus & status, lldb_private::Status * error_ptr) 
Editline.cpp Line 576   C++ liblldb.dll!lldb_private::Editline::GetCharacter(wchar_t * c) 
read.c Line 401 C liblldb.dll!el_wgetc(editline * el, wchar_t * cp) 
read.c Line 225 C liblldb.dll!read_getcmd(editline * el, unsigned char * cmdnum, wchar_t * ch) 
read.c Line 514 C                                 liblldb.dll!el_wgets(editline * el, int * nread) 
eln.c Line 72   C liblldb.dll!el_gets(editline * el, int * nread) 
Editline.cpp Line 1497  C++ liblldb.dll!lldb_private::Editline::GetLine(std::string & line, bool & interrupted) 
IOHandler.cpp Line 354  C++ liblldb.dll!lldb_private::IOHandlerEditline::GetLine(std::string & line, bool & interrupted) 
IOHandler.cpp Line 596  C++ liblldb.dll!lldb_private::IOHandlerEditline::Run() 
Debugger.cpp Line 1107  C++ liblldb.dll!lldb_private::Debugger::RunIOHandlers() 
CommandInterpreter.cpp Line 3404    C++ liblldb.dll!lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions & options) 
Line 1253 C++ liblldb.dll!lldb::SBDebugger::RunCommandInterpreter(bool auto_handle_events, bool spawn_thread) SBDebugger.cpp 
Driver.cpp Line 621 C++ lldb.exe!Driver::MainLoop() 
Driver.cpp Line 807 C++                           lldb.exe!main(int argc, const char * * argv) 
        
```                                                                                                                                                                                                                                                                                                                                                     

In particular, the call
```
const int num_set_fds = ::select(nfds, read_fdset_ptr, write_fdset_ptr, error_fdset_ptr, tv_ptr);
```
in SelectHelper.cpp line 214 always fails and the loop
```
while (handle == m_io_sp->GetWaitableHandle()) { ... }`
```
in ConnectionFileDescriptorPosix.cpp line 473 is never left.

I'm not too familiar with the inner workings of lldb.

 
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUWV1z4jrS_jXKjQrKlmMgF7kAQ87wHjJJJZl35uyNS9gN6IwsuSQZkv31Wy1_QIDkTPZsamuppMBy6-mnW63uls2tFWsFcE3iCYmnF7xyG22uZSUlsCAYsiC4WOr85XpON3wLdFkJ6ehiMZ3Q8Kof9gdUK7oTKtc7S3fCbagUS8iFo7YqS20craxQa-o2wtLMaGt7peRupU3RSaIYicaUxJONc6Ul0ZiwG8Ju1sJtqmU_0wVhN4XINhzkn5nk5idhN81sEk8JG_0b89hVnwRjEoy_gAEqLHUboFnBfwLNdFFwldPKQo6gXowMguYvGNdivUcq5bagvYl3S057v9GvQv3JaS3Vmya3499n6eTbfDFNn_64n5Fo-gDyu3CbKSznaqVpKzP_-vg0XizS-4fZzfwHiaaEMaGs41ISxo4Akx8_0uTu9n6-mD2QaJrJDiY5Gm_n4YKls9vJbJre__H05e5r-uXuFukEByL_f5vOvo4ni1l6_3D3f7Pk6bHmIWW-JNEkk1ytD8l40PnXZPFtOkufZo9e_m61OtJaQy7mk9l0_oQS6qxA8u3hcfYuwj9ux-8r-HG7YO9I1Ja_B_HtRIFYznLhEPxh_DCfNR5JMCri5N7oteEFvRESLCVs9DwaEHZF4uR7syN-F86SOAkDEicLsfQ_-0GfsQEL-zhYFSROngeXJE4S81K6iPVRLpp8iorvQhXFZyr4ZsHM1PYzVTxCVpljN6FeREg2Rlinyw2JkylsSZx0aSJpt5MfI3GCw315iPK2bKaLkv-ytIE1PP-qsANTCLXSvyr_EdplnlXGgvXyhzu3Cet2807nD68jew_ZpUt2lANJMH7aAEKuwUmhgAwCuqpU5oRW-9xu9FbkYKnwu36PW3uUxMlOqIjhXIFCOCzBAcX8m2uwirChowZcZRTthVhuwBhtLNWG7jagqNI023DDMwfG0h1mcwM8P0LYcJVLoAUU2rxQLqXOODK1fdqUNgOl5BnkVLi6kmFBWGkp9U6o9dk6YK34J6SOth5gI2RCCRsTNsaR0hnCEtqIETZWeHkzX8zwwjoDvMCtEIzJcEKCMaWtrBQFJdG0nhO9vodfpzdb1ba91RLwArWMWBE2wj04IGxACQul8Ppb5ZRSvsRyzEY43EKT4fQ1BGGh3c_r-ATdDEo7C4LzMMrRDJ0hjoR2GyEBs0SvVyPMaLAnPMpINF2twWVoSOc_doXGINDs7qaVztoxwoYkTjAOjmz1tiABLIXejCOBxueUsAlKjF4ZeODz0pnG6z4CfABcGfBhhkTbIDh06gEFwkIfKa3utXa6DvMj6dqDe25eabfGpzKWxBOB5Bl2d146e2NVPXeU-ByP_Q976iT637P_7XD5mx44a377Oe-Gxr5T2zvDa6sbe-tFD_DrIGXsE4kXsnsQNla080I3o_bQEcUmf4tTBl1mP9TZWNJcrQxA7ZjWIUecvn5bLE5p7Z1_rKNez9e17N6Acy-0WssXXIBl5ehOm5-2vy91BmwlHZ5msCOm8AxZ5fhS-tOD0q6rflzirAWvVLZBcaxE3DleXzlNOdbFDKylyxdaihxjAfrrfg3c69XCPbzz_Pz8jOkNXNavGdGVLzU1R6xRQjnA8ie2-6MLuqempXp7Wl1N9HR5lkHpKFcveNIx9Ce8LDU3ORWqrJyPz0M06_iLpUvJ1c_TwxOnGZcSZbKfdVm2lS1B5a27ztbPR5CQuS8gSzD9rCzpAhUxNqKUJvVmxE4C5_dzPAmFhzMQMmow6oJFSTBOtFLg7cV-cwo2M6J02txrK573Si6Hw7d04M-0NGLLHdQ63sKs705eHNjxlguJweDdpqyjpzBPogBdORIl1uX1kMEmhERJSFgSBv7jcwv2BwPqmgksOYP26LirsJaP6_2S1pnhAz5gQ_af8sED8Jyw0Vb7YB7T3HrWlfKPF3KapkK5wSWOpxJ8F_RZXjqm2_lpgOHpKvthd2KvjFtg77l4OHgzRE-h2_n11W_gkrZfJWy0wyJQN4fYEHmF2L_2syZQg5AmRypAprumB4IGuyYu0bZXiOUZSMbiE0i8nyJmkZ9H7ZayrWM0K3JVFScaN2c0xuElTehffc4aac_Twf4Rr5Txkec1glStQozsc277GODpwoeXVx_IGycLv6hPCV1gW2cwQWJsyjaray39gE_rpiodtHTmd1_8KeYgV0bx5a_T6eZ_Pq_4avC3eT1Uap_Wp7Cs1utDFWEYfGAp2vkddKfUHtYOX-_maGFpwL3y9GVwST-w6U-xOtVnbrHRryA8VOqu9KdWvxK6_t2Qr53C4ugdik2qm5x44ywlv-S8cjqtT88pbEE520WDLflOpW7T7pg9rncbrpoR20MnDli4Z4fU4BkIC2uxmswtF2qhdXmw9Ecgo2DYgbyTTPbwBRcYSbjDuVln--LTpTL852a9bTSS4Op1p3L13_7DzmmuaMmNE1kluX-s4J9YcymPn05729BaVRWpBZeu8uahQL25245JrXK_mD73r3KUbB5Y7Ixw8HqoLoqvhty2KZJNX33AQSh60tz5hMvCS8rlDlvJFRfS-pYUDZG45q9BukcBzcOb5nBapEKntuyRaPYbuO9c-Ca83s3NgwtcxuGE9vt9f9Kom_zX9P66R5J1nxj5Phq2YKiElWsa3zlhw8K30U5ruuKFkIKb_YMjoRQY37ALtbZUr-qAbI44F_l1lF9FV_wCrsNhNAjZIIyii811tArzZRyymEGeZxCMWMxjvryKAmA8YnAhrlnA4iAMBkEYxlHUD4Llaplnl9GA5_GIZeQygIIL2ZdyW_S1WV8Iayu4Dlk4DOMLyZcgrX_dw5iCHfV3CWMknl6Ya5zUW1ZrSy4DKayzexgnnPTviXwiiad0_ua5A2-seAZ4_Dg4fWhFvx--Kjr_PuiiMvL6nRc6SKj56pVG_-lj-cabYQm7aezcXrN_BQAA___eE_Bs">