2

I've experienced multiple unresponsive Termux sessions on Oneplus 5T by nothing more intensive than opening around five webpages in lynx (each in their own... again, session in tmux; Ctrl + B, C on the keyboard).

I've waited for several days and the sessions don't appear to recover.

Have the following sessions crashed outright or does Termux consider them to be in some frozen state?

screenshot

1 Answer 1

1

According to the source code, the red strikethrough sessions are sessions that are finished running with non-zero exit code (e.g. session killed).


The TermuxSessionsListViewController class handles the UI for sessions list:

  • If the session is not running, then it will strikethrough the text
  • If the session is either not running and has non-zero exit status, then it will be colored in red
TerminalSession sessionAtRow = getItem(position).getTerminalSession();

...

boolean sessionRunning = sessionAtRow.isRunning();

if (sessionRunning) {
    sessionTitleView.setPaintFlags(sessionTitleView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
} else {
    sessionTitleView.setPaintFlags(sessionTitleView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
int defaultColor = shouldEnableDarkTheme ? Color.WHITE : Color.BLACK;
int color = sessionRunning || sessionAtRow.getExitStatus() == 0 ? defaultColor : Color.RED;
sessionTitleView.setTextColor(color);

The TerminalSession class handles the logic, including when it's considered finished running (PID = -1) with its exit code.

/** The pid of the shell process. 0 if not started and -1 if finished running. */
int mShellPid;

/** The exit status of the shell process. Only valid if ${@link #mShellPid} is -1. */
int mShellExitStatus;

...

/** Cleanup resources when the process exits. */
void cleanupResources(int exitStatus) {
    synchronized (this) {
        mShellPid = -1;
        mShellExitStatus = exitStatus;
    }

    ...

}

...

public synchronized boolean isRunning() {
    return mShellPid != -1;
}

/** Only valid if not {@link #isRunning()}. */
public synchronized int getExitStatus() {
    return mShellExitStatus;
}

...

@SuppressLint("HandlerLeak")
class MainThreadHandler extends Handler {

    ...

    @Override
    public void handleMessage(Message msg) {

        ...

        if (msg.what == MSG_PROCESS_EXITED) {
            int exitCode = (Integer) msg.obj;
            cleanupResources(exitCode);

            String exitDescription = "\r\n[Process completed";
            if (exitCode > 0) {
                // Non-zero process exit.
                exitDescription += " (code " + exitCode + ")";
            } else if (exitCode < 0) {
                // Negated signal.
                exitDescription += " (signal " + (-exitCode) + ")";
            }
            exitDescription += " - press Enter]";

            byte[] bytesToWrite = exitDescription.getBytes(StandardCharsets.UTF_8);
            mEmulator.append(bytesToWrite, bytesToWrite.length);
            notifyScreenUpdate();

            mClient.onSessionFinished(TerminalSession.this);
        }
    }

}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .