esp-idf icon indicating copy to clipboard operation
esp-idf copied to clipboard

[Console] fix: console deinit always deadlocks - adds ability to unblock linenoise (try 2) (IDFGH-9188)

Open chipweinberger opened this issue 2 years ago • 12 comments

Previous PR: https://github.com/espressif/esp-idf/pull/9983

I am re-opening this PR to get more traction on it.

This solves: https://github.com/espressif/esp-idf/issues/9974

Motivation:

  • currently, console deinit causes a deadlock
  • without deinit, we can't create consoles "as needed"
  • for example, USB Serial JTAG console should be destroyed when entering USB host mode
  • for example, "web" consoles should be destroyed when the browser window is closed

chipweinberger avatar Jan 20 '23 00:01 chipweinberger

Hi @chipweinberger, I started looking into your PR. Can I ask you to rebase and fix the build issues and conflict with upstream?

SoucheSouche avatar Apr 18 '23 05:04 SoucheSouche

sure, one moment.

chipweinberger avatar Apr 18 '23 06:04 chipweinberger

@SoucheSouche updated.

chipweinberger avatar Apr 18 '23 06:04 chipweinberger

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Apr 20 '23 06:04 CLAassistant

@SoucheSouche how are things going?

chipweinberger avatar Apr 20 '23 09:04 chipweinberger

@chipweinberger, there has been some changes in the ring buffer so I am now looking at your PR again since the semaphores for rx and tx were removed.

But tomorrow is my last working day before my extended leaves so I will most likely not finish up before. Someone from my team will take over the console related PRs.

SoucheSouche avatar Apr 20 '23 13:04 SoucheSouche

since the semaphores for rx and tx were removed.

I updated the PR and removed the semaphores.

But as I was saying before I think we should move this bit: #define rbBUFFER_UNBLOCK_RX_FLAG ( ( UBaseType_t ) 32 ) to its own variable, to simplify race condition worries.

chipweinberger avatar Apr 21 '23 06:04 chipweinberger

The other issue is that this comment is still valid and your current solution won't be accepted.

I am implementing an alternative to your changes using xTaskAbortDelay proposed solution.

SoucheSouche avatar Apr 21 '23 08:04 SoucheSouche

@SoucheSouche , did you understand Ivans comment? "Thinking about this again, select on a pair of file descriptors (stdin and eventfd) is probably the cleanest solution." I'm not sure what that solution would look like.

If you use xTaskAbortDelay, make sure the thread is not blocked in user code. 1. suspend the linenoise thread. 2. check its location.

chipweinberger avatar Apr 21 '23 19:04 chipweinberger

@SoucheSouche another idea - we could send a "enter" key event to vfs buffers to force the thread to exit line noise.

something like:

  1. esp_linenoise_quit //prevent any further linenoise stdin reads or command lines being returned
  2. usb_serial_jtag_write('\n')

chipweinberger avatar Apr 26 '23 11:04 chipweinberger

Warnings
:warning:

Some issues found for the commit messages in this PR:

  • the commit message "[Console] fix console deinit: add ability to unblock linenoise, to fix deadlock":
    • summary looks empty
    • type/action looks empty

Please fix these commit messages - here are some basic tips:

  • follow Conventional Commits style
  • correct format of commit message should be: <type/action>(<scope/component>): <summary>, for example fix(esp32): Fixed startup timeout issue
  • allowed types are: change,ci,docs,feat,fix,refactor,remove,revert
  • sufficiently descriptive message summary should be between 20 to 72 characters and start with upper case letter
  • avoid Jira references in commit messages (unavailable/irrelevant for our customers)

TIP: Install pre-commit hooks and run this check when committing (uses the Conventional Precommit Linter).

:warning:

The source branch "user/chip/console-unblock-try2" incorrect format:

  • contains more than one slash (/). This can cause troubles with git sync. Please rename your branch.

👋 Hello chipweinberger, we appreciate your contribution to this project!


📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more.

🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project.

Click to see more instructions ...


This automated output is generated by the PR linter DangerJS, which checks if your Pull Request meets the project's requirements and helps you fix potential issues.

DangerJS is triggered with each push event to a Pull Request and modify the contents of this comment.

Please consider the following:
- Danger mainly focuses on the PR structure and formatting and can't understand the meaning behind your code or changes.
- Danger is not a substitute for human code reviews; it's still important to request a code review from your colleagues.
- Resolve all warnings (⚠️ ) before requesting a review from human reviewers - they will appreciate it.
- To manually retry these Danger checks, please navigate to the Actions tab and re-run last Danger workflow.

Review and merge process you can expect ...


We do welcome contributions in the form of bug reports, feature requests and pull requests via this public GitHub repository.

This GitHub project is public mirror of our internal git repository

1. An internal issue has been created for the PR, we assign it to the relevant engineer.
2. They review the PR and either approve it or ask you for changes or clarifications.
3. Once the GitHub PR is approved, we synchronize it into our internal git repository.
4. In the internal git repository we do the final review, collect approvals from core owners and make sure all the automated tests are passing.
- At this point we may do some adjustments to the proposed change, or extend it by adding tests or documentation.
5. If the change is approved and passes the tests it is merged into the default branch.
5. On next sync from the internal git repository merged change will appear in this public GitHub repository.

Generated by :no_entry_sign: dangerJS against f85938e4db2d7bbcdffea24594cffa326216e881

github-actions[bot] avatar Dec 17 '23 20:12 github-actions[bot]

Hi @chipweinberger, Sorry that I left this PR not updated for so long. I will get back at it this week. It's been a while so it might take a bit of time to get back into it but I will update you as I go through it. Hopefully we will finally be able to merge it this time.

SoucheSouche avatar May 07 '24 11:05 SoucheSouche

Hi @chipweinberger, a little update on the PR. Since it was fairly old, I first had to rebase it on the latest master and realized that your solution was no longer working. The concept of adding 2 states to the console repl is great and works just fine but the solution that you were using to force linenoise to return didn't seem to work.

I experimented with select as @igrr suggested and ended up finding a solution. The very drafty logic implemented in linenoiseDumb() and linenoiseRaw() is the following:

[...]
        if (select(in_fd + 1, &read_fds, NULL, &except_fds, NULL) < 0) {
            // select returned with -1, handle the error
        }

        // std_in is either ready to read or an exceptional condition occurred
        if(FD_ISSET(in_fd, &except_fds)) {
            // exceptional condition occurred, return from linenoise back into the while loop
            // of `esp_console_repl_task` where the repl state will be reevaluated
            break;
        }
        else if(FD_ISSET(in_fd, &read_fds)) {
            // do the reading since std_in is ready for reading
        }
        else {
            continue;
        }

I kept uart_unblock_reads and usb_serial_jtag_unblock_reads and I make them fire an "exceptional condition" event that will make the select return and if(FD_ISSET(in_fd, &except_fds)) evaluated to true.

SoucheSouche avatar May 17 '24 06:05 SoucheSouche

seems like a reasonable solution!

impressive :) fun :)

chipweinberger avatar May 17 '24 06:05 chipweinberger

I had to implement the select for the usb serial jtag driver so I will have to first merge this added feature before proceeding with the actual deadlock fix. I will keep you posted.

SoucheSouche avatar May 17 '24 06:05 SoucheSouche

related: https://github.com/espressif/esp-idf/issues/9964 ([USB Serial JTAG] calling select() & poll() crashes)

chipweinberger avatar May 29 '24 17:05 chipweinberger

Hi @chipweinberger, a little update on the fix. I am still waiting to merge the select() feature for the usb cdc and usb serial jtag drivers before I can merge the fix for the deadlock. I will let you know when the select() features have been merged but it might take a little while.

SoucheSouche avatar Jun 27 '24 07:06 SoucheSouche