You might see if there is some way to implement an equivalent of 
IOHandlerEditline that works on the windows terminal? Maybe a class like 
IOHandlerWindowsTerminal which would be specified to native windows terminal. 
There has to be a way to control the cursor and do line kind of commands. I 
believe that erase to beginning of line is all you would need to do to fix this 
correctly. 


> On Mar 21, 2016, at 1:13 PM, Ted Woodward <ted.woodw...@codeaurora.org> wrote:
> 
> I dug into this some more. Windows is not using editline, so it's using the 
> LLDB_DISABLE_LIBEDIT code path.
> 
> IOHandlerEditline::GetLine() will print the prompt, then get the next line. 
> Type in a command, and it will continue doing this. The prompt comes out 
> before the command finishes (in this case, anyway), so we get the prompt, 
> then the output from the command, then nothing.
> 
> I've got a simple solution that works for hitting breakpoints and stepping, 
> at least. In IOHandlerEditline::PrintAsync(), in the LLDB_DISABLE_LIBEDIT 
> code path, print the prompt after calling IOHandler::PrintAsync().
> 
> I'll put up a patch to phabricator.
> 
> --
> Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a 
> Linux Foundation Collaborative Project
> 
> 
> -----Original Message-----
> From: Greg Clayton [mailto:gclay...@apple.com] 
> Sent: Monday, March 21, 2016 1:01 PM
> To: Ted Woodward <ted.woodw...@codeaurora.org>
> Cc: LLDB <lldb-dev@lists.llvm.org>
> Subject: Re: [lldb-dev] Windows lldb prompt issue
> 
> All input and output are handled by IOHandler subclasses. There is a stack of 
> them. When you start LLDB you get one thing on the IOHandler stack: the LLDB 
> command interpreter:
> 
> IOHandlers:
> [0] IOHandlerEditline for command interpreter
> 
> If you type "script" at the LLDB command prompt, the command interpreter 
> pushes a IOHandlerPythonInterpreter onto the stack and all STDIN/OUT/ERR. Now 
> your stack looks like:
> 
> [0] IOHandlerEditline for command interpreter [1] IOHandlerPythonInterpreter
> 
> When you type "quit()" in the IOHandlerPythonInterpreter, it will exit and 
> pop off and return to:
> 
> [0] IOHandlerEditline for command interpreter
> 
> Note that these transitions happen on the same thread, so it is very easy to 
> coordinate the output since it all happens in one thread of execution. 
> 
> When your process runs, by typing "run" on the command interpreter, the 
> Process might push an IOHandler onto the stack so that when the process 
> resumes you can do STDIN and receive any STDOUT/STDERR when your program 
> runs, but it does so from _another_ thread. This is the only IOHandler that 
> does things this way. So as soon as your resume a process that you have 
> launched (if you attach, you don't get STDIN/OUT/ERR) we push the 
> IOHandlerProcessSTDIO. When you stop, we must pop the IOHandlerProcessSTDIO. 
> Again, this popping of the IOHandlerProcessSTDIO happens on another thread, 
> not from the thread that is running the command interpreter. So this is why 
> we have trouble coordinating the output. The threads the LLDB driver has are 
> as follows:
> 
> 1 - thread that runs the command interpreter
> 2 - thread that listens for debugger events (this includes process events for 
> stops and runs)
> 3 - private process state thread that tracks any starts and stops and figure 
> out when the send a public state change event
> 
> Thread 3 might start and stop a process 10 times for one source level single 
> step, but it will only send out one public eStateRunning event and one 
> eStateStopped event. So when a public eStateStopped event get delivered from 
> thread 3 to thread 2, we set off a chain of events where we must pop the 
> 
> So when a stopped event comes in, thread 2 receives the eStateStopped event 
> and will handle flushing any pending STDOUT and STDERR and then pop the 
> IOHandlerProcessSTDIO. When anyone wants to display text on the top 
> IOHandler's output file, the must coordinate with the IOhandler stack. This 
> is done by calling:
> 
> void
> Debugger::PrintAsync (const char *s, size_t len, bool is_stdout);
> 
> This coordinates with the top IOHandler by calling:
> 
> void
> IOHandler::PrintAsync (Stream *stream, const char *s, size_t len);
> 
> Now the command interpreter, when active will print its prompt of "(lldb) ". 
> When async output comes in, it will eventually end up calling:
> 
> void
> Editline::PrintAsync (Stream *stream, const char *s, size_t len) {
>    Mutex::Locker locker(m_output_mutex);
>    if (m_editor_status == EditorStatus::Editing)
>    {
>        MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
>        fprintf(m_output_file, ANSI_CLEAR_BELOW);
>    }
>    stream->Write (s, len);
>    stream->Flush();
>    if (m_editor_status == EditorStatus::Editing)
>    {
>        DisplayInput();
>        MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
>    }
> }
> 
> This clears the current line, so it erases the "(lldb) ", prints the output 
> in "stream", the it must refresh the current IOHandler, which for out command 
> interpreter will restore the "(lldb) " prompt.
> 
> So the question is: does the erase/print/restore feature in 
> Editline::PrintAsync() even work on windows? I know that there is an Editline 
> implementation on windows, but I am not sure it will do the right thing in 
> this case as we are printing control characters to the screen in order to 
> clear the "(lldb) " prompt with:
> 
>    if (m_editor_status == EditorStatus::Editing)
>    {
>        MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
>        fprintf(m_output_file, ANSI_CLEAR_BELOW);
>    }
> 
> Then we write the "Stream" content. So after a very long story, you might 
> better understand what is happening. It would be worth testing something on 
> windows where you just call Debugger::PrintAsync() while the "(lldb) " prompt 
> is up and on the screen and see what happens. If this isn't working, then we 
> know why the issue is happening. So if you have the following displayed in 
> the LLDB driver:
> 
> "(lldb) "
> 
> And you call "Debugger::PrintAsync("hello world\n", 12, true)" on a thread 
> that is not thread 1 from the initial thread list shown at the beginning, you 
> should see your screen be:
> 
> "hello world
> (lldb) "
> 
> If you see:
> 
> "(lldb)
> hello world
> (lldb) "
> 
> Then you know that the erasing feature isn't working in 
> Editline::PrintAsync() and it will explain why you see this issue.
> 
> Greg Clayton
> 
>> On Mar 21, 2016, at 10:10 AM, Ted Woodward via lldb-dev 
>> <lldb-dev@lists.llvm.org> wrote:
>> 
>> I run lldb on Windows and Linux, launching my gdb-server based Hexagon 
>> simulator automatically on a process launch. On Windows I’m seeing the 
>> (lldb) prompt before the stop message, and no prompt after. On Linux I see 
>> the prompt after.
>> 
>> Windows:
>> Current executable set to 'u:\lldb_test\factwin' (hexagon).
>> (lldb) b main
>> Breakpoint 1: where = factwin`main + 28 at factorial.c:32, address = 
>> 0x00005130
>> (lldb) r
>> Process 1 launched: 'u:\lldb_test\factwin' (hexagon)
>> (lldb) Process 1 stopped
>> * thread #1: tid = 0x0001, 0x00005130 factwin`main(argc=1, argv=0x0000e110) 
>> + 28 at factorial.c:32, stop reason = breakpoint 1.1
>>    frame #0: 0x00005130 factwin`main(argc=1, argv=0x0000e110) + 28 at 
>> factorial.c:32
>>   29     }
>>   30   */
>>   31
>> -> 32     base = 10;
>>   33
>>   34     printf("Factorial of %d is %d\n", base, factorial(base));
>>   35     return 0;
>> 
>> 
>> Linux:
>> Current executable set to '/usr2/tedwood/lldb_test/factorial' (hexagon).
>> (lldb) b main
>> Breakpoint 1: where = factorial`main + 28 at factorial.c:32, address = 
>> 0x00004130
>> (lldb) r
>> Process 1 launched: '/usr2/tedwood/lldb_test/factorial' (hexagon) 
>> Process 1 stopped
>> * thread #1: tid = 0x0001, 0x00004130 factorial`main(argc=1, 
>> argv=0x0000b100) + 28 at factorial.c:32, stop reason = breakpoint 1.1
>>    frame #0: 0x00004130 factorial`main(argc=1, argv=0x0000b100) + 28 at 
>> factorial.c:32
>>   29     }
>>   30   */
>>   31
>> -> 32     base = 10;
>>   33  
>>   34     printf("Factorial of %d is %d\n", base, factorial(base));
>>   35     return 0;
>> (lldb)
>> 
>> 
>> 
>> Any idea why the prompt is coming out before the stop message?
>> 
>> 
>> --
>> Qualcomm Innovation Center, Inc.
>> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
>> a Linux Foundation Collaborative Project
>> 
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
> 
> 

_______________________________________________
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

Reply via email to