I am currently using the leaks command line utility on Mac OS X. It requires an active process which is a pain with a command line utility. Is there a way to launch a process and on exit freeze it (so it stays running) so leaks can work like the following
leaks executable_binary_name
instead of
leaks currently_running_process_name_or_pid
as the latter is a pain to use with a command line application that doesn't normally just remain open. I assume the program has to run through so leaks can observe the used memory and so I'd have to freeze it on exit.
Part of man page dealing with process
leaks requires one parameter -- either the process ID or executable
name
of the process to examine. It also takes several arguments for modifying
its behavior.
Use iprofiler (manpage) instead. It's the command line equivalent of Instruments and allows an executable or process ID to be specified.
Something like:
$ iprofiler -leaks -d $HOME/tmp executable [args]
You can even pass arguments to executable, if it accepts them.
The -d option specifies where the output .dtps file will be written to, which can be loaded into Instruments for examination.
Related
Say you have a shell command like
cat file1 | ./my_script
Is there any way from inside the 'my_script' command to detect the command run first as the pipe input (in the above example cat file1)?
I've been digging into it and so far I've not found any possibilities.
I've been unable to find any environment variables set in the process space of the second command recording the full command line, the command data the my_script commands sees (via /proc etc) is just _./my_script_ and doesn't include any information about it being run as part of a pipe. Checking the process list from inside the second command even doesn't seem to provide any data since the first process seems to exit before the second starts.
The best information I've been able to find suggests in bash in some cases you can get the exit codes of processes in the pipe via PIPESTATUS, unfortunately nothing similar seems to be present for the name of commands/files in the pipe. My research seems to be saying it's impossible to do in a generic manner (I can't control how people decide to run my_script so I can't force 3rd party pipe replacement tools to be used over build in shell pipes) but it just at the same time doesn't seem like it should be impossible since the shell has the full command line present as the command is run.
(update adding in later information following on from comments below)
I am on Linux.
I've investigated the /proc/$$/fd data and it almost does the job. If the first command doesn't exit for several seconds while piping data to the second command can you read /proc/$$/fd/0 to see the value pipe:[PIPEID] that it symlinks to. That can then be used to search through the rest of the /proc//fd/ data for other running processes to find another process with a pipe open using the same PIPEID which gives you the first process pid.
However in most real world tests I've done of piping you can't trust that the first command will stay running long enough for the second one to have time to locate it's pipe fd in /proc before it exits (which removes the proc data preventing it being read). So if this method will return any information is something I can't rely on.
I ask because I recently made a change to a KornShell (ksh) script that was executing. A short while after I saved my changes, the executing process failed. Judging from the error message, it looked as though the running process had seen some -- but not all -- of my changes. This strongly suggests that when a shell script is invoked, the entire script is not read into memory.
If this conclusion is correct, it suggests that one should avoid making changes to scripts that are running.
$ uname -a
SunOS blahblah 5.9 Generic_122300-61 sun4u sparc SUNW,Sun-Fire-15000
No. Shell scripts are read either line-by-line, or command-by-command followed by ;s, with the exception of blocks such as if ... fi blocks which are interpreted as a chunk:
A shell script is a text file containing shell commands. When such a
file is used as the first non-option argument when invoking Bash, and
neither the -c nor -s option is supplied (see Invoking Bash), Bash
reads and executes commands from the file, then exits. This mode of
operation creates a non-interactive shell.
You can demonstrate that the shell waits for the fi of an if block to execute commands by typing them manually on the command line.
http://www.gnu.org/software/bash/manual/bashref.html#Executing-Commands
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Scripts
It's funny that most OS'es I know, do NOT read the entire content of any script in memory, and run it from disk. Doing otherwise would allow making changes to the script, while running. I don't understand why that is done, given the fact :
scripts are usually very small (and don't take many memory anyway)
at some point, and shown in this thread, people would start making changes to a script that is already running anyway
But, acknowledging this, here's something to think about: If you decided that a script is not running OK (because you are writing/changing/debugging), do you care on the rest of the running of that script ? you can go ahead making the changes, save them, and ignore all output and actions, done by the current run.
But .. Sometimes, and that depends on the script in question, a subsequent run of the same script (modified or not), can become a problem since the current/previous run is doing an abnormal run. It would typically skip some stuff, or sudenly jump to parts in the script, it shouldn't. And THAT may be a problem. It may leave "things" in a bad state; particularly if file manipulation/creation is involved.
So, as a general rule : even if the OS supports the feature or not, it's best to let the current run finish, and THEN save the updated script. You can change it already, but don't save it.
It's not like in the old days of DOS, where you actually have only one screen in front of you (one DOS screen), so you can't say you need to wait on run completion, before you can open a file again.
No they are not and there are many good reasons for that.
One of the things you should keep in mind is that a shell is not an interpreter even if there are some similarities. Shells are designed to work with a stream of commands. Either from the TTY ,a PIPE, FIFO or even a socket.
The shell reads from its resource line by line until a EOF is returned by the kernel.
The most shells have no extra support for interpreting files. they work with a file as they would work with a terminal.
In fact this is considered to be a nice feature because you can do interesting stuff like this How do Linux binary installers (.bin, .sh) work?
You can use a binary file and prepend shell scripts. You can't do this with an interpreter. because it parses the whole file or at least it would try it and fail. A shell would just interpret it line by line and doesnt care about the garbage at the end of the file. You just have to make sure the execution of the script gets terminated before it reaches the binary part.
In Windows you can use the following command in Matlab to start a new instance of MATLAB which will run in the background (i.e. you can keep executing commands in your first version of MATLAB).
system('matlab &')
An analogous call in OSX,
system([matlabroot '/bin/matlab &'])
however results in the display of the splash image, then nothing. If I take out the ampersand, the new instance opens as expected. Unfortunately, this won't work for me, I really need to be able to control the first instance of MATLAB while the second is running.
Does anyone know why this discrepancy between the operating systems exists? By the way, I'm using OSX 10.7, Windows 7 64 bit, and MATLAB R2012a on Mac and R2012b on PC.
As some background, I'm trying to write a generic tester for an interactive command line interface that uses the input() function extensively.
Edit: I should have mentioned that the command
/Applications/MATLAB_R2012a.app/bin/matlab &
works as expected from the OSX terminal. In other words, a new instance of MATLAB opens and new commands can be entered into the terminal. So this problem seems to be specific to the system() function in OSX matlab.
Also, I tried adding that command to a bash script and calling the script from matlab, but had the same problem that I did with putting the command into the system() function.
Thanks
This is a long shot, but it might be happening because when you invoke the new instance of Matlab from Matlab with the system() command on Unix or OS X, the matlab_helper process forks and runs a shell process to run the new application. If you omit the ampersand, the shell blocks and waits for the program to finish, and system() waits for it, so the first Matlab locks up. And (here's the speculation part) if you add the ampersand, Matlab launches in the background, and then the forked shell exits, which then causes the new Matlab process to exit because its parent process (the shell) has exited. (Windows doesn't have the same parent/child process relationships, process launch mechanism, or shells, which would explain the different behavior.)
You could try prefixing the command with nohup, which protects processes from getting killed by SIGHUP, which might be what's happening here to your second Matlab process.
system(['nohup ' matlabroot '/bin/matlab &'])
You could also try using the OS X open command to launch a new independent instance. Something like this. You may need to fiddle with the options and path, but -n should be what gives you a new instance. It should be pointing at /Applications/MATLAB_R2012a.app; I'm assuming that's what matlabroot is returning on OS X.
system(['open -na ' matlabroot])
You could also try running it from the Java process-launching features from within Matlab instead of with system(). Runtime.exec() doesn't block like system() does, and there may be other quirks to system(), like the matlab_helper architecture. Try launching it with java.lang.Runtime from Matlab.
jrt = java.lang.Runtime.getRuntime();
newMatlabProcess = jrt.exec([matlabroot '/bin/matlab']);
You can try the other command line variants above using this mechanism too, and you may need to redirect stdout to /dev/null, since the new processes input and output are buffered in to that newMatlabProcess object.
You can use applescript to do this. I do something like this:
! osascript -e "tell application \"Terminal\" to do script \"cd `pwd`;matlab -nojvm -nosplash -r 'why'\""
This example opens a new Matlab instance, in the current directory, and runs the command "why". You can remove the "-nojvm" if you need java in your background Matlab process
What is the best way of running process in background and receiving its output only when needed?
Intended usage: make prompt-outputting script with heavy initialization be initialized once per session and not on each prompt run. Note: two-way communication is needed: shell needs to tell when new prompt is needed, what is the last command status.
Known solutions:
some explicitly created files on filesystem (FIFO files, UNIX sockets): it would be better to avoid this as this means I need to choose file name, be sure it is garbage-collected on exit and add something to clean no longer used files in case of a crash.
zsh/zpty module: it is a bit like overkill for this job and does not work in bash.
coprocesses: does not work in bash and AFAIK only one coprocess per session is allowed.
Bash supports coprocesses sinces 4.0, but multiple coprocesses is still experimental.
I would have gone with some explicitly created files, naming them ~/.myThing-$HOSTNAME/fifo if they're per user and host. You can use flock to relatively easily determine if the command is still running and optionally start it:
(
flock -n 123 || exit 1
rm/mkfifo ..
exec yourServer < .. > ..
) 123> ~/".myThing-$HOSTNAME/lockfile"
If the command or server dies, the lock is automatically released and you only have a few zero length files lying around. The next time the server starts, it deletes and sets them up again.
Querying the server would be similar, but exiting if the lock is not in use (and optionally using a wait lock to avoid contention).
I am trying to reverse engineer the build system of a commercial Windows based IDE, so I can use make to build my project.
A program is launched to perform a task, and I need to know what command line arguments are passed to this program when it is run. However the windows process viewer does not show the command line arguments.
Is there any way to see what command line arguments are being passed when the program is launched?
(Actually it just occurred to me that I should substitute a stub program to read the command line args. Still, I'd like to know if there's an easy way).
Sysinternals Process Explorer lets you do that.