Ticket #4548 (new defect)

Opened 6 days ago

Last modified 17 hours ago

Mc start up is slow on FreeBSD with Bash shell when mc is using a subshell

Reported by: tonythed1111 Owned by:
Priority: major Milestone: Future Releases
Component: mc-core Version: master
Keywords: Cc:
Blocked By: Blocking:
Branch state: no branch Votes for changeset:

Description

Mc start up is slow on FreeBSD systems when running a Bash shell and the mc subshell feature is in use. There is an annoying delay of about 1 to 2 seconds during start up of the mc program. This occurs on any FreeBSD version that I have used when running bash as my login shell. The delay does not occur on any Linux system that I have used, it only happens on the FreeBSD systems. On FreeBSD when mc is started as 'mc -u' with no subshell the program starts almost instantly and is the expected behavior. When mc is started as 'mc' which does have a subshell, there is an annoying 1 to 2 second delay before it starts up.

What steps will reproduce the problem?

  1. On any FreeBSD operating system set your login shell to use Bash (any bash version).
  1. On the console or xterm, run 'mc'.
  1. You will observe a 1 to 2 second annoying delay before the program starts up.
  1. Now run 'mc -u'.
  1. You will observe an almost instant start up, which is the expected behavior for mc.
  1. The inclusion of a subshell causes the annoying delay.

Change History

comment:1 Changed 5 days ago by zaytsev

Can you strace to see what is it waiting for? In the past subshell startup delays were due to some user tweaks to the shell configuration. Does this happen for new users in FreeBSD without any tweaks to .bashrc? Are FreeBSD bash defaults somehow different than Linux?

comment:2 Changed 5 days ago by tonythed1111

It happens irrespective of any .bashrc or .bash_profile content. I can set .bashrc to contain only the following:

# If not running interactively, don't do anything
case $- in

*i*) ;;

*) return;;

esac

And the .bash_profile to contain only the following:

umask 0022

..And the problem still occurs. The same delay occurs whether a heavy .bashrc or minimal .bashrc is used and does not have anything to do with what is ran from them.

I am using the default standard binaries in FreeBSD. The port build settings/deps used for midnight commander are:

Dependencies:
textproc/diffutils-3.8_1
security/libssh2-1.11.0_1,3
lang/python39-3.9.18_2
lang/perl5.36-5.36.3_1
devel/libslang2-2.3.3_2
devel/glib20-2.80.3,2
devel/gettext-runtime-0.22.5
archivers/zip-3.0_2

Compile Options:
ASPELL=off
DOCS=on
EDITOR=on
EXTATTR=off
ICONV=on
NCURSES=off
NLS=on
PCRE2=off
SFTP=on
SLANG=on
SUBSHELL=on
X11=on

The port build settings/deps for Bash are:

Dependencies:
print/indexinfo-0.3.1
devel/readline-8.2.10
devel/gettext-runtime-0.22.5

Compile Options:
DOCS=on
FDESCFS=off
HELP=on
NLS=on
PORTS_READLINE=on
STATIC=off
SYSBASHRC=off
SYSLOG=off

comment:3 Changed 5 days ago by zaytsev

Well, alright, so it's not a problem with your custom profile, which is sadly often the case. But can you strace or whatever you'd do instead on FreeBSD to check what it's waiting on? We don't have BSD and don't really know our way around.

comment:4 Changed 5 days ago by tonythed1111

Forgot to mention that others having this problem have ran an strace and found that mc is hanging and times out a delay in the code when it tries to create the subshell. See https://forums.freebsd.org/threads/mc-midnight-commander-slow-start.79608/

Snippet from that link:
---

...

It's an interesting issue. I tried to have a quick look into it on FreeBSD 14 (4.8.30) and Debian 12.4 (4.8.29). Version mismatch doesn't matter, we observed this issue for some time now with various versions.

This is what I did:

o) modified src/subshell/common.c so it gives me more verbose information on what is happening
o) tested with root's shell csh and bash for comparison (full logout before starting mc)

This is what I observed
o) there's no delay with csh because read_command_line_buffer () is not executed on startup at all
o) both csh/bash have the same stty settings
o) delay is happening due to the select() here at line 570: src/subshell/common.c:L#570, select has now timeout set to 1sec.

In Linux this select() doesn't take so long; it does under FreeBSD..

o) starting mc in loop (mc, exit, mc, exit, mc, exit .. ) doesn't yield the same results. This select() in loop with 1sec timeout keeps failing either with errno 2(ENOENT) or errno 4 (EINTR). errno 4 is something I understand but I don't know what's happening with errno 2 (race condition during start?). But as this is happening also under Linux I didn't pay much attention to it..

So basically that 1s timeout is what is causing delay under FreeBSD. I didn't dig deep why is csh not using this at all (during startup; during usage I had trouble triggering that function even when I used subshell). Setting this timeout to 0sec sometimes works (mc starts up immediatelly), sometimes it gets stuck during startup and actually starts without proper mc profile (not shell profile, mc profile). I know that time in select() "can lengthen the interval by an indeterminate amount" too.

Last edited 4 days ago by zaytsev (previous) (diff)

comment:5 Changed 4 days ago by zaytsev

Well, I can tell you why it doesn't happen for tcsh - we only support persistent subshell buffer via our hooks on bash and lately zsh. I don't know if it's possible at all with csh, but even if it is, it's simply not supported at the moment.

We had to increase the timeout to 1 second, because in the past, users were complaining on FreeBSD that mc would start without subshell, because our timeout was set so low. Now they complain that subshell works reliably, but the start is too slow, lol. You just can't please the users...

Can you figure out why the select hangs on FreeBSD and not on other systems?

comment:6 Changed 4 days ago by tonythed1111

Can you figure out why the select hangs on FreeBSD and not on other systems?

Well, I guess that is the million dollar question. It would require a significant learning curve for me to do that. I am reporting it to you with the hope that you will be interested enough to fix the issue at your end. I am sure that many FreeBSD users would be very thankful if did. Midnight Commander is a very useful program. Whether you decide to fix the issue or not, I want to thank you for creating and maintaining Midnight Commander. Your expertise and hard work is greatly appreciated by myself and many more.

comment:7 Changed 4 days ago by zaytsev

Well, as I said, I'd be happy to contribute to fixing the issue, but I've never used FreeBSD, and I don't have access to a FreeBSD machine. Also debugging methods on FreeBSD are not the same as on Linux. So if I set up a VM, I wouldn't even know what to do. So maybe you can report back in the forum thread and ask if anyone has skill and interest to do something about it... Otherwise I don't see us finding enough time in the future to improve FreeBSD platform support.

comment:8 Changed 4 days ago by tonythed1111

No worries, thanks for looking into the issue.

comment:9 Changed 22 hours ago by zaytsev

I wonder if #4549 could have anything to do with shell initiation on FreeBSD...

comment:10 Changed 17 hours ago by tonythed1111

#4549 seems to be mostly caused when there are multiple versions of bash installed (which does not seem like a good idea from the start). SHELL is usually set by the login utility from the SHELL path in the password file. When bash sees a non-empty SHELL variable it does not change it. Bash then sets the BASH variable to the full file name used to call it. And then there is the path to bash that can be determined by searching the PATH variable. Under normal circumstances all three of these paths should be the same.

In FreeBSD they are all the same when the standard FreeBSD binary package is the only bash version installed on the system. When/if midnight commander runs a copy of "bash" locating the executable by searching the $PATH, there should not be a problem since the path to bash derived this way will be the same as the parent shell.

To verify: On FreeBSD the bash executable is at /usr/local/bin/bash. The SHELL variable is set by the tty login utility on user login to /usr/local/bin/bash as read from the password file.

In the initial login bash shell:

echo $SHELL => /usr/local/bin/bash
echo $BASH => /usr/local/bin/bash
which bash => /usr/local/bin/bash

Now run midnight commander 'mc' and control-o to the subshell:

echo $SHELL => /usr/local/bin/bash
echo $BASH => /usr/local/bin/bash
which bash => /usr/local/bin/bash

No problem here, all paths line up.

Note: See TracTickets for help on using tickets.