Archive: Bug in ExecDos


Bug in ExecDos
I have found what I think is a bug in the NSIS compiler or in ExecDos.

I have ExecDos set with a very standard line of code, which causes the program to spawn a second copy of its process into memory!

ExecDos::exec /NOUNLOAD /TIMEOUT=10000 "$TORDIRECTORY\TorCircuitStatus 82"

which usually causes torcircuitstatus.exe to run, instead causes the main program to spawn another instance of itself and torcircuitstatus never runs at all!

It used to work, and now it doesn't.

I can provide full source if need be, but I am 100% sure it is that line that is the error.


Is 'main' program your installer or some other application? Not long ago I made changes in ExecDos (added 'output to stack' option), but you can test situation with previous plug-in version from this page http://nsis.sourceforge.net/File:ExecDos.zip Can you reproduce 'fork' with any other application? ExecDos call exit code (Pop)?
Also. You should set a full file name in the command line including extension, torcircuitstatus.exe, otherwise, while we not using shell, file will not be found. And '/nounload' switch in the sync mode usefull for serial dll calls only. Short script sample (with files required) may help.


Main program is indeed my installer.

The strange issue is that when I have some entirely unrelated files around, it works just fine. Very very strange.


I have a new development. The programs don't work if they are moved at all whatsoever! If I move the directory, and exact copy of it, to anywhere else, the installer forks.

Further, when I removed the /NOUNLOAD i got this:

The instruction at "0x011613a5" referenced memory at "0xffffffff". The memory could not be "read".
I have seen this problem happen with the correct program being run instead of the main installer program. I am thinking it is possible that execdos is infact running the correct program, but that it is using the main installers name. However Execdos isn't allowing the program to throw back a code from the stack. BTW, unless your execdos is of a different size, I was using your old version (July 1st).

Update: strange to stranger
I substituted NsExec in place of ExecDOS... Now there isn't just one extra copy of the loader but more and more continually.

And I am indeed using the exact and full path of the program. Yet still it breaks and runs the new process under the name of the installer.

Could this be an issue with the NSIS compiler?


One more.. If path includes blank spaces use double quotas:
'"$TORDIRECTORY\TorCircuitStatus" 82'
Both ExecDos and nsExec start one process only.


Still no good. I'm about to post the source and programs so you can see the insanity for yourself. I've found a new error as well in FindProcDLL:FindProc that may be related to this problem.

In my code I have:

DoneWithFlagCheck:
MessageBox MB_OK `R0 = $R0`
FindProcDLL::FindProc "tor.exe" ;Make sure tor.exe is still running
Pop $R0
MessageBox MB_OK `The value returned was: $R0`
The first message box returns "R0 = 0"
The second message box returns "The value returned was: I:\soapbox2\App\tor\TorCircuitStatus.exe 82"

This is really strange because that is the string I am sending to ExecDos. And for some reason, FindProcDLL pulls that from somewhere and returns it as $R0!

Okay, the issue isn't with FindProcDLL, it has to do with something with ExecDOS or the compiler or environment.

I changed the code:

DoneWithFlagCheck:
MessageBox MB_OK `R0 = $R0`
FindProcDLL::FindProc "tor.exe" ;Make sure tor.exe is still running
Pop $R1
StrCmp $DEBUGON 1 "" +2
MessageBox MB_OK `R0: $R0, R1 = $R1`
The output was:
R0 = 0
R0 = 1 R1 = I:\soapbox2\App\tor\TorCircuitStatus.exe 82

So apparently ExecDos is forcing the string "I:\soapbox2\App\tor\TorCircuitStatus.exe 82" on the stack.

Okay. The i have removed all "POP $R0" after FindProcDLL as they are all useless since FindProcDLL pushes the return to $R0.

The problem is very odd. When the directory is on a USB stick, it runs fine. If it is in a certain directory on my computer, it runs fine. If it is moved anywhere else, the installer "Torpark.exe" keeps respawning its process anytime i try to ExecDos TorCircuitStatus.exe.

Check it for yourself. Put it into debug mode by running it with /debug like so "Torpark /debug" from the command prompt.

Full BIN, dir structure, and source available here:
http://torpark.nfshost.com/soapbox2.zip

The strangest thing of all... I used to have a message at the beginning of the installer, and that is what kept popping up when the process restarted. I changed that message slightly and recompiled it, and when it ran the installer again it gave me the original message! Very strange.


Okay. I think it is the environment, but it may be effected by the compiler.

When I compile the program and run it, often, it will fork two other processes that I am calling with ExecDos. Not just torpark.exe, but sometimes an extra tor.exe will show up.

When I take that same code, copy it to a different medium and run it from there, no problems.

So I rebooted and ran the program from the original location. It started forking again. I tried the one at the different drive and it was fine, just as before.

Is it possible that versions of the program are being called from the system cache, and that is what is causing the appearance of multiple processes?

Admittedly, I highly doubt this as the machine I am experiencing this problem on has no pagefile / 0MB set, as it has 1.5GB Ram.


All of your ExecDos calls cause stack corruption. You pass only the application to run and not the stdin string and the log file name. Seeing FindProc returning/getting parts of the stack of ExecDos, you definitely have a stack corruption and it might be related to this issue.


Why would execdos calls be causing stack corruption? Is this because of the formatting I have used?

How should syntax be if I am running, with no log file:

$TORDIRECTORY\TorCircuitStatus 82

It was said that it was: '"$TORDIRECTORY\TorCircuitStatus" 82' but this does not address the log file.

So I assume it should be:
'"$TORDIRECTORY\TorCircuitStatus" 82' "" ""

BTW, I tried the program on a different machine, and was able to reproduce forking after running and exiting the program 10 or so times.


It's because of the way you've used ExecDos. You've passed only one argument where ExecDos expects 3 (numbers might be off, see the readme for the exact numbers). This makes it pop two more arguments from the stack that have nothing to do with ExecDos. It causes stack corruption because something else was expecting those stack items.