Delphi - How to kill a process by knowing its path? - delphi

Until now I was using this function to kill a process. But what if I have three processes
of the same name and only one of them is the one that I want to kill? If I will do this:
KillTask('csrss.exe') then it will kill the system process. I have the path of my process, how can I use this information to kill it?

Iterate over processes and check the path for each of them, then use the answer from this SO question (use GetModuleFileNameEx):
get the full path from a PID using delphi
If you launched the process then remember the PID or Handle and kill the specific one.

Related

How to reliably clean up dask scheduler/worker

I'm starting up a dask cluster in an automated way by ssh-ing into a bunch of machines and running dask-worker. I noticed that I sometimes run into problems when processes from a previous experiment are still running. Wha'ts the best way to clean up after dask? killall dask-worker dask-scheduler doesn't seem to do the trick, possibly because dask somehow starts up new processes in their place.
If you start a worker with dask-worker, you will notice in ps, that it starts more than one process, because there is a "nanny" responsible for restarting the worker in the case that it somehow crashes. Also, there may be "semaphore" processes around for communicating between the two, depending on which form of process spawning you are using.
The correct way to stop all of these would be to send a SIGINT (i.e., keyboard interrupt) to the parent process. A KILL signal might not give it the chance to stop and clean up the child process(s). If some situation (e.g., ssh hangup) caused a more radical termination, or perhaps a session didn't send any stop signal at all, then you will probably have to grep the output of ps for dask-like processes and kill them all.

How can i start mnesia from a supervisor

I have trying to find information about it everywhere and failed. Is it possible to start mnesia as a worker from a supervisor? I have tried it myself the same way I start other workers but always get error.
Mnesia is an application and comes with its own supervisor. You should only need to run application:start(mnesia). But if you really want to add your own supervision, you should be able to start it as a worker. However, you need to start it from your supervisor in much the same way that it is specified by the mod key in the mnesia.app file (but note that the details there have changed between OTP 19 and the upcoming OTP 20). You'll also need to ensure that its settings are loaded before it starts. You could call application:load(mnesia) yourself, or you could specify Mnesia as an included application of your own app - see http://erlang.org/doc/design_principles/included_applications.html for more info (you can probably ignore the stuff about start phases).

Otp application:stop(..) kills all spawned processes, not just spawn_linked ones?

I've set up a simple test-case at https://github.com/bvdeenen/otp_super_nukes_all that shows that an otp application:stop() actually kills all spawned processes by its children, even the ones that are not linked.
The test-case consists of one gen_server (registered as par) spawning a plain erlang process (registered as par_worker) and a gen_server (registered as reg_child), which also spawns a plain erlang process (registered as child_worker). Calling application:stop(test_app) does a normal termination on the 'par' gen_server, but an exit(kill) on all others!
Is this nominal behaviour? If so, where is it documented, and can I disable it? I want the processes I spawn from my gen_server (not link), to stay alive when the application terminates.
Thanks
Bart van Deenen
The application manual says (for the stop/1 function):
Last, the application master itself terminates. Note that all processes with the
application master as group leader, i.e. processes spawned from a process belonging
to the application, thus are terminated as well.
So I guess you cant modify this behavior.
EDIT: You might be able to change the group_leader of the started process with group_leader(GroupLeader, Pid) -> true (see: http://www.erlang.org/doc/man/erlang.html#group_leader-2). Changing the group_leader might allow you to avoid killing your process when the application ends.
I made that mistakes too, and found out it must happen.
If parent process dies, all children process dies no matter what it is registered or not.
If this does not happen, we have to track all up-and-running processes and figure out which is orphaned and which is not. you can guess how difficult it would be. You can think of unix ppid and pid. if you kill ppid, all children dies too. This, I think this must happen.
If you want to have processes independent from your application, you can send a messageto other application to start processes.
other_application_module:start_process(ProcessInfo).

delphi JvCreateProcess1: how to send keys

I run an invisible DOS process thanks to JvCreateProcess component; that works fine.
I need to stop this process by CTRL+C and not by JvCreateProcess1.terminate (or send CTRL+C sequence to JVCreateProcess)
Any idea ?
regards
You can do this:
GenerateConsoleCtrlEvent(CTRL_C_EVENT, myProcessInfo.dwProcessId);
but there are some limitations:
You can only call GenerateConcolseCltrEvent from a process that shares its console with the process you are sending the Ctrl-C-Event to. If you need to catch the console output of the spawned process without it being intermingled with the console output of other spawned processes or the app spawning them, then you can't use this (directly, see below).
The process receiving the Ctrl-C-Event in this way will/may not terminate any processes that it spawned itself. (Possibly dependent on the process group settings and console sharing amongst those processes, I didn't check further into this at the time when I was contemplating Ctrl-C'ing a spawned process.)
If you need to send Ctrl-C from an app that does not share its console with the spawned process you are left with creating an intermediate process that does and telling that to terminate by some other means (pipes, COM, whatever) so it can send a ctrl-c to the actual process that you want to spawn and terminate by Ctrl-C.
More info on this, and how to go about creating an intermediate process, can be found here: http://www.microsoft.com/msj/0698/win320698.aspx

How do you go about setting up monitoring for a non-web frontend process?

I have a worker process that is running in a server with no web frontend. what is the best way to set up monitoring fot it? It recently died for 3 days, and i did not know about it
There are several ways to do this. One simple option is to run a cron job that checks timestamps on the process's logs (and, of course, make sure the process logs something routinely).
Roll your own reincarnation job. Have your background process get its PID, then write it to a specific pre-determined location when it starts. Have another process (or perhaps cron) read that PID, then check the symbolic link proc/{pid}/exe. If that link does not exist or is not your process, it needs to be re-started.
With PHP, you can use posix_getpid() to obtain the PID. Then fopen() / fwrite() to write it to a file. use readlink() to read the symbolic link (take care to note FALSE as a return value).
Here's a simple bash-ified example of how the symlink works:
tpost#tpost-desktop:~$ echo $$
13737
tpost#tpost-desktop:~$ readlink /proc/13737/exe
/bin/bash
So, once you know the PID that the process started with, you can check to see if its still alive, and that Linux has not recycled the PID (you only see PID recycling on systems that have been running for a very long time, but it does happen).
This is a very, very cheap operation, feel free to let it do its work every minute, 30 seconds or even shorter intervals.

Resources