Commit Graph

205 Commits

Author SHA1 Message Date
hjk
e64ce914f9 Utils/Ssh: Move SshRemoteProces::isRunning() to QtcProcess base
... and use it on a few places.

Change-Id: Id2cea709e355a46821a720e593740ac032888ced
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
2021-12-06 13:44:23 +00:00
Jarek Kobus
15edfc85cb Remove unused m_exitStatus member
Change-Id: Ice572b27964b4c9a3977091caa3224585bc08879
Reviewed-by: hjk <hjk@qt.io>
2021-11-10 12:47:41 +00:00
Jarek Kobus
0556eec9b7 Use a new enum indicating various start failures
Before the m_startFailure flag was used to detect the case
when the process failed to start because of wrong filename.
As this flag was set on any possible error we have always
detected the wrong filename case. Replace this flag with a
new enum describing various start failures.

Don't report again the crashed message. Check if we have already
reported the stop and we don't report it again. The
processExited() handler is being called twice: directly from
localGuiProcessError() and through the delayed localProcessDone().

Fixes: QTCREATORBUG-26467
Change-Id: I3cc6aa0c0b702256cefd77ba95793cd31e82ae10
Reviewed-by: hjk <hjk@qt.io>
2021-10-27 07:53:53 +00:00
Jarek Kobus
4b6b9f4dec Don't instantiate QTimer and QEventLoop for every QtcProcess
These two objects are only used when QtcProcess::runBlocking()
with m_processUserEvents option set is called, otherwise
they are unused. Create them only when they are needed.

This also solves the issue that these two QObjects were not
moved together with QtcProcess when it was moved to another
thread.

Change-Id: I7de6a92a51fc249184fc5811dac7a7bbf05d351f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
2021-10-27 06:43:01 +00:00
Alessandro Portale
2fc0ce4843 Utils: Introduce QtcProcess::toStandaloneCommandLine()
The goal is to make a QtcProcess incl. environment, working directory,
executable and arguments testable, e.g. in a terminal. The new
toStandaloneCommandLine() returns a string containing the command line
for a call of "env" the data of the QtcProcess instance as parameters.

To be used like:
  qDebug().noquote() << qtcProc.toStandaloneCommandLine();

..and the debug output can be pasted into a terminal.

Change-Id: Ib6cbea290e1eff3279d6e0a67076a624312af879
Reviewed-by: hjk <hjk@qt.io>
2021-09-10 11:49:07 +00:00
hjk
bdefc13eba Utils: Rename FilePath::absolutePath(FilePath) to resolvePath
There was already a similar function taking a QString.

After that, the remaining no-argument version of absolutePath()
can be deprecated.

Change-Id: I5b9ad8c8b68a5723891b0aa9f5a37e90db0fe09e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Schulz <david.schulz@qt.io>
2021-09-09 05:42:30 +00:00
hjk
152fdd35f5 Utils: Add runAsRoot and useTerminal flags for QtcProcess
Not implemented right now.

Change-Id: Ifdd5870b757f260c72fccb423140584688aa9898
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
2021-09-08 14:12:34 +00:00
Jarek Kobus
ace765c199 Move ProcessReaper into lib/utils
Reuse ProcessReaper inside process launcher.
Automatically reap all internal QProcesses of QtcProcess
(either direct child of QtcProcess in QProcessImpl
or indirectly inside process launcher).
Make ProcessReaper work again on QProcess instead of on
QtcProcess, so it may still be reused for non-QtcProcesses.

Change-Id: I950cac5cec28f17ae97fe474d6a4e48c01d6aaa2
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
2021-09-06 21:28:19 +00:00
Jarek Kobus
f7aa963a07 Make all objects created by QtcProcess children of it
Sometimes after creating QtcProcess we move it into a different
thread. In this case we should move all the children, too.
Without parent-child relation all the children will stay in the
old thread.

Change-Id: Ibde44d6153092a155dd2d200a7116a046910dddc
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2021-09-03 10:56:26 +00:00
Jarek Kobus
a454b3dc23 Use QProcess' / process lanuncher's exit code
Change-Id: I802116c45847daf9a647771ee293aef8463fc3c7
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
2021-09-03 10:56:19 +00:00
Christian Kandeler
3be9f52980 Fix some warnings
Unused functions & variables, initialization order, signedness, non-
virtual destructor.

Change-Id: I405d768fe0e02a36a16c2cead9e1bc2f6a23fb75
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-09-02 13:47:07 +00:00
The Qt Project
3c4e7321bf Merge "Merge remote-tracking branch 'origin/5.0'" 2021-09-01 10:56:08 +00:00
Jarek Kobus
1acda50e7f Compile fix
Amends cc940d52be

Change-Id: I8e498a43b3e081415e449d1347398fb01433882d
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-09-01 08:42:07 +00:00
Eike Ziller
47de984972 Merge remote-tracking branch 'origin/5.0'
Change-Id: I712fce3cc0171327de122a1cd53b5bae67541084
2021-09-01 10:10:33 +02:00
Jarek Kobus
cc940d52be Measure the time spent on starting and waiting for start
Measure it on demand. The printout will appear when
QTC_MEASURE_PROCESS env variable is set. It may be easily
combined with QTC_USE_QPROCESS to compare the time spent
on freezing Creator when starting Creator or when loading
a big project, like Creator project.

In order to compare the measurement between
old implementation (using directly QProcess) and
new implementation (using process launcher) of QtcProcess
do the following (linux):

1. To measure the new implementation:
QTC_MEASURE_PROCESS= ./bin/qtcreator

2. To measure the old implementation:
QTC_USE_QPROCESS= QTC_MEASURE_PROCESS= ./bin/qtcreator

How to measure (two scenarios, A and B):

A. Launch Creator (don't load any project), wait a bit
   until all processes finished. Look for the last value
   in the 11th column ([A/M] Total Measurement, A means
   all measured functions, M means in main thread only).
   This value has the greatest influence on GUI freeze -
   the higher it is, the longer the GUI is frozen.
   Measure it with 1. (new) and 2. (old) implementation
   and share your results.

B. Launch Creator and load a Creator project.
   Wait until all processes finished (taskbar should be empty).
   Look for the last value in the 11th column.
   Measure it with 1. (new) and 2. (old) implementation
   and share your results.

C* (Additional one)
   If only you notice that launching a certain QtcProcess takes
   suspiciously too long, replay your scenario that triggers
   this process with 1. and 2. and share your results of
   the 11th column.

Change-Id: I549c0a9fd0b3d6223f3d27288130553d99ab768e
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2021-09-01 07:32:24 +00:00
Jarek Kobus
37254cb92c Check if the executable exists before starting
Change-Id: I6d0d4e8885222cc1220c27d7d81e304887302e9b
Reviewed-by: hjk <hjk@qt.io>
2021-09-01 07:08:58 +00:00
Jarek Kobus
99cf99579e Make access to LauncherSocket thread safe
Instead of returning a pointer to LauncherSocket instance,
which might get deleted in meantime of just after,
route all calls to the LauncherSocket through the LauncherInterface.
Make all calls to LauncherInterface secured by the
instance mutex.

Change-Id: I751228de5f4263112471098ee08cc73a5245147e
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2021-08-31 08:45:59 +00:00
Eike Ziller
e465d18215 Always set an environment for QtcProcess
Since e755094480 we have a global option
in Qt Creator to set the (base) environment for any tools run by Qt
Creator. So it is expected that any tool actually uses
Environment::systemEnvironment() as a base, which is the system
environment modified by the global option.

QtcProcess already had a fallback to Environment::systemEnvironment for
resolving environment variables in Qt Creator macros in the command
line. Also use it as a fallback for the actual environment for the
process.

Latest occurrence where the global environment setting was ignored was
for starting language servers by our LSP client.

Change-Id: Id1a4141326d8ef3239b37d7f3daf21928605ca92
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
2021-08-31 06:50:15 +00:00
Jarek Kobus
1a5db9ca4e Refactor CallerHandle / LauncherHandle
Fix a race condition in the following scenario:

  QtcProcess proc(...)
  ...
  proc.start();
  proc.waitForStarted();
  if (!proc.waitForFinished()) {
      // handle failure here
      return;
  }
  // handle success

Move all the data into the caller's handle
and manage the QtcProcess state only from
inside caller's thread. This eliminates race
conditions when state changed from inside launcher's
thread while the caller's thread isn't notified
immediately.

For example: currently, when the launcher's thread receives
finished signal it doesn't change the process state
immediately, but posts a finished signal to be
dispatched in the caller's thread. When the caller's
thread dispatches the posted signal (inside flush() method)
it changes its state and posts the finished signal to the
outside world.

Don't flush all signals from waitForStarted(). Flush
only started signal in this case.

Change-Id: Ia39c4021bf43b8d0e8fcda789c367c096bfd032c
Reviewed-by: hjk <hjk@qt.io>
2021-08-24 18:24:18 +00:00
hjk
fd7fe32c09 Utils: Remove no longer used QtcProcess::start(QString, ...) overload
Change-Id: If74b1247c6c6afccfc04cff8915a9b759c8bfcaa
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
2021-08-20 09:46:17 +00:00
hjk
026b4ddcda Utils: Introduce a QtcProcess::startDetached
A convenience wrapper around QProcess::startDetached().

Change-Id: If4228e8405ad4d5e172930593a6f670874211767
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-08-19 09:56:49 +00:00
Jarek Kobus
a7e8ddd725 Add some more comments
Add some developer comments explaining which method
is designed to be called from a certain thread.
Add also some comments about in which thread
certain QObjects live in.

Change-Id: I38b10216cc29f8a86fd784e588e913407f0fb776
Reviewed-by: hjk <hjk@qt.io>
2021-08-18 10:24:18 +00:00
Eike Ziller
6d44c28f0a Merge remote-tracking branch 'origin/5.0'
Conflicts:
	src/libs/utils/qtcprocess.cpp

Change-Id: I1f7419d927e8534dfdcd10db998f97a6efd4d3e4
2021-08-18 09:48:39 +02:00
Orgad Shaneh
a6917a5484 QtcProcess: Do not discard stdout and stderr buffers when callback is set
All the uses of setStd{Out,Err}Callback in the codebase call proc.stdOut/
stdErr after the execution.

This triggered a soft assertion that was apparently not noticed so far.

It broke for example prompt for conflict resolution on Git pull/rebase.

Change-Id: Ib4b8301f1f50b2b66f02fc4dc6c14d93f895ea33
Reviewed-by: hjk <hjk@qt.io>
2021-08-17 07:58:48 +00:00
hjk
7c28c4f744 Utils: Introduce a FilePath constructor from char arrays
Similar to QT_RESTRICTED_CAST_FROM_ASCII to avoid the need for
decorations in user code.

At the same time, drop some convenience constructors and functions
in CommandLine and Icon essentially serving the same purpose.

Change-Id: Ida4e5ac19c2da0a4298a97b2a8e1511d56bbb79d
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-08-17 05:34:10 +00:00
Jarek Kobus
80d8bca395 Remove repeated line
Change-Id: I9973be042d06ffc0c2d47c617d34d873434117f3
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-08-16 08:20:35 +00:00
Jarek Kobus
3143ba79e3 Use process launcher implementation for all QtC code base
Use QTC_USE_QPROCESS env var to switch back to the original
implementation based on direct use of QProcess. By default
a new implementation employing process launcher will be used.

Change-Id: I75c3efb579e26de377fc785404f1e2a08367d994
Reviewed-by: hjk <hjk@qt.io>
2021-08-12 13:04:12 +00:00
Eike Ziller
ba5f2e27f0 Merge remote-tracking branch 'origin/5.0'
Change-Id: I86049934ae744e22e4a728ab79c0cf6880ff3c7d
2021-08-12 11:05:11 +02:00
hjk
4000819262 Utils: Weaken QTC_CHECK in QtcProcess::stdErr()
The previous tighter check is actually good theoretically, but currently
ShellCommand::runFullySynchronous triggers it and disentangling there
is not trivial. So weaken it a bit for now to not annoy users.

Change-Id: Ifc6b5713b398db0af0f604834c37ff361c2a1ed3
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
2021-08-11 15:08:13 +00:00
Jarek Kobus
b80624611b Reuse ProcessHelper in process launcher
Handle lowPriority and unixTerminalDisabled inside
process launcher.

Change-Id: I7a8998e303da0e79186c1201fc6e1a76edb4e1b3
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2021-08-09 14:38:43 +00:00
Jarek Kobus
4e06d3ac74 Handle setNativeArguments inside process launcher
Change-Id: I4b4db2e5cf6b3ad4d8a39614573564145f125520
Reviewed-by: hjk <hjk@qt.io>
2021-08-09 13:31:24 +00:00
Jarek Kobus
8fa1a1f587 Handle belowNormalPriority inside process launcher on Windows
Remove setCreateProcessArgumentModifier() from the ProcessInterface
API and replace it with belowNormalPriority flag.

Change-Id: I6bcb92e56c3a68af7fa3e3a1c8b8eb13e3a2e5a7
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
2021-08-09 13:23:37 +00:00
Jarek Kobus
d22505c41f Use refactored ProcessMode
This patch needs to be applied together with the parent change.

There are 3 basic cases:
1. The user doesn't write anything to the write channel:
   You don't need to call closeWriteChannel manually anymore.
   By default the QtcProcess you create is in ProcessMode::Reader mode.
   Internally it opens the process in ReadOnly mode and
   closes the write channel just after starting.
2. The user writes some initial data (after being started)
   and then closes the write channel:
   All what is needed now it to set the write data
   (QtcProcess::setWriteData) before calling start.
   You also use the default ProcessMode::Reader mode.
   Internally it opens the process in ReadWrite mode
   and writes the writeData asynchonously when the process
   already started. After writing the data it closes the
   write channel automatically.
3. The user writes the data also after calling start.
   All you need now is to create a process with
   ProcessMode::Writer mode. In this mode the write
   channel is not closed.
   Internally it opens the process in ReadWrite mode
   as some writers also read the data from the process.

All the code base is adapted here to the above rules.

Change-Id: Id103019d1d71a3012fd1eade226fe96b9aaa48c2
Reviewed-by: hjk <hjk@qt.io>
2021-08-09 07:51:31 +00:00
Jarek Kobus
25f585227f Refactor openMode/keepWriteChannelOpen/closeWriteChannel
Change-Id: I4090533875ce1da864b6f8554ce59dbc1392a142
Reviewed-by: hjk <hjk@qt.io>
2021-08-09 07:51:26 +00:00
Jarek Kobus
535d312e93 Implement writing to process inside process launcher
Change-Id: I7321a941024d431cc52b3f6ae0b1ef38d851db8c
Reviewed-by: hjk <hjk@qt.io>
2021-08-06 14:32:21 +00:00
Jarek Kobus
7696f4f37c Remove bytesAvailable from ProcessInterface
It looks like in meantime it became unused.

Change-Id: I03ae4887e4af41e84e3b31ea7ce13ee302e2708e
Reviewed-by: hjk <hjk@qt.io>
2021-08-06 12:54:02 +00:00
hjk
0567f35e21 Utils: Use Utils::CommandLine as input for ProcessArgs::prepareCommand
Change-Id: Ib5878a159bda0e6b6253f1f4e1abc1acb5ecb573
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
2021-08-06 12:51:52 +00:00
hjk
4a42bcd4e8 Utils/ProjectExplorer: Use FilePath for Runnable::workingDirectory
... and in some using code.

Change-Id: I231ea56628908f7d305d13f07eabe8803fe8a791
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-08-06 12:51:24 +00:00
Jarek Kobus
f53d993d95 Move m_keepStdInOpen into the QtcProcessPrivate
In this way it may work transparently when using process launcher.

Change-Id: Idf42500650157b17bbefe5934515ca977adecf57
Reviewed-by: hjk <hjk@qt.io>
2021-08-05 18:53:56 +00:00
Jarek Kobus
ba037a707e Implement readyRead inside process launcher
Change-Id: I3a27edef2307053b8c4c7d8f1dbf7e0400e27416
Reviewed-by: hjk <hjk@qt.io>
2021-08-05 18:53:22 +00:00
Jarek Kobus
cfa8da9ba0 Base unique tokens on global atomic counter
Don't base process token on instance pointer,
as it may happen that the recreated instance may
get the same token again (it happens often when invoking
a function that recreates QtcProcess in sequence).
The consequence may be that on the project launcher side
we may reuse the old process (with possibly broken state)
instead of creating a new one.

Change-Id: I8274691f88ae0eefe008746d944a26f29979bf72
Reviewed-by: hjk <hjk@qt.io>
2021-08-04 16:35:40 +00:00
Eike Ziller
17d716118a Merge remote-tracking branch 'origin/5.0'
Change-Id: I4236e3d2f87d56aea787905f4b78b1f5f933c069
2021-08-03 14:19:44 +02:00
Jarek Kobus
17f907da9b Implement setStandardInputFile() in ProcessLauncherImpl
Change-Id: I4d77c86ecb750573ce5421ca7300eb27f9f76108
Reviewed-by: hjk <hjk@qt.io>
2021-08-02 13:48:46 +00:00
Christian Stenger
fe65998351 Utils: Fix readDataFromProcess()
The internal handling of output gets in the way when trying
to read output from a process synchronously.
Make usage of the internal one instead of relying on the
original output handling.

Fixes: QTCREATORBUG-25958
Change-Id: Ie96b5e8d17799a613ff15a52a23a8bdc31cb2939
Reviewed-by: hjk <hjk@qt.io>
2021-07-30 04:49:15 +00:00
Orgad Shaneh
61008441da Merge remote-tracking branch 'origin/5.0'
Change-Id: I9aa7b7a6490e8fb592a0e785a57128d438fdbab5
2021-07-27 11:39:29 +03:00
Christian Stenger
b8bcdd9568 Docker: Correct environment for docker exec calls
Provide way to clean QtcProcess environment which is needed as
e.g. toolchains, build tools, and debugger otherwise run
inside a wrong environment when using docker exec for the
respective process calls.

Change-Id: Ia6de1c90f2134fce260d293a2f6937ab3cfca2ce
Reviewed-by: hjk <hjk@qt.io>
2021-07-23 11:55:27 +00:00
hjk
09286d062f Merge remote-tracking branch 'origin/5.0'
Change-Id: I074571dac56b26a8a1449c29aef53b9052d8e304
2021-07-22 15:00:19 +02:00
hjk
7aef03134d Utils: Move writeData handling to QtcProcess::start()
So that this doesn't only apply to runBlocking()

Change-Id: I6ef7c72e13a5e214c7476ede942662a9893c843c
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-07-21 13:05:31 +00:00
hjk
9d08e5f173 Utils: Keep write channel open by default if we know we'll use it
Change-Id: I4591f3e7e3b33ef6ea43d6aa9a5c9246c8bfd2ab
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2021-07-21 12:54:21 +00:00
Jarek Kobus
f7cf48bc28 Refactor process launcher
Move launcher process into a separate thread.
Implement blocking API by using wait condition
on the caller's side. Replay all collected
signals from the launcher's thread when leaving
waitingFor* state. In case we were not waiting
for anything deliver the signals asynchronously
from launcher's thread to the caller's thread.

Change-Id: Id44fe5f7ceaac407004984a1dfb6ea65f197d297
Reviewed-by: hjk <hjk@qt.io>
2021-07-16 07:52:58 +00:00