Tuesday, January 27, 2015

How does processor use stack?

Processor uses stack for saving registers or other data between switching of execution context. For architecture IA-32, IA-64 CPU uses stack in next instructions:

1. CALL and RET 
CALL instruction saves procedure related data on the stack and branches to the called procedure specified using the target operand. The target operand specifies the address of the first instruction in the called procedure. 

RET instruction transfers program control to a return address located on the top of the stack. The address is usually placed on the stack by a CALL instruction, and the return is made to the instruction that follows the CALL instruction.

2. ENTER and LEAVE
ENTER instruction creates a stack frame for a procedure.

LEAVE instruction releases the stack frame set up by an earlier ENTER instruction.

3. INT, INTO and IRET/IRETD
The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand. INTO instruction is a shortcut for INT 4 instruction which means calling overflow exception handler.

IRET/IRETD instruction returns program control from an exception or interrupt handler to a program or procedure that was interrupted by an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform a return from a nested task.
 
4. PUSH, PUSHA/PUSHAD, PUSHF/PUSHFD
PUSH instruction decrements the stack pointer and then stores the source operand on the top of the stack.

PUSHA/PUSHAD pushes the contents of the general-purpose registers onto the stack.

PUSHF/PUSHFD pushes EFLAGS register onto the stack.
 
5. POP, POPA/POPAD
POP instruction loads the value from the top of the stack to the location specified with the destination operand (or explicit opcode) and then increments the stack pointer. The destination operand can be a general-purpose register, memory location, or segment register.

POPAD instruction pops doublewords and POPA pops words from the stack into the general-purpose registers. The registers are loaded in the following order: EDI, ESI, EBP, EBX, EDX, ECX, and EAX (if the operand-size attribute is 32) and DI, SI, BP, BX, DX, CX, and AX (if the operand-size attribute is 16). (These instructions reverse the operation of the PUSHA/PUSHAD instructions.) The value on the stack for the ESP or SP register is ignored. Instead, the ESP or SP register is incremented after each register is loaded.

All descriptions of commands is taken from "Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volumes 2A, 2B & 2C", please check it for more details.

Thursday, January 15, 2015

How to prevent starting another bash script copy?

Usually pidfile is used in order to check if bash script has been already started. If pidfile exists and its content is valid then it means that script has been already started and its second instance exits. If pidfile doesn't exist or it stores invalid PID file it means that script is stopped, so script instance continue to run. Looks like nothing complex, but there is one pitfall. 

If script has been started simultaneously (for example: ./script& ./script&) race condition can happen: both scripts will check that pidfile doesn't exist and then write its PID values to the pidfile. As the result, only last PID value will be stored in the pidfile and both instance will continue to run.

In order to prevent race condition file should be created atomically. 
Below is the example how to do it.


set -C - enable preventing redirection to already existing files;
set +C - disable preventing redirection to already existing files;

You also can notice that echo $$ > $g_sPathToPidFile is surrounded by brackets {}.
It is not the coincidence, these brackets prevent script from printing error "cannot overwrite existing file" to stdout in case if pidfile has been already created.

Pay attention I've tested set -C command behavior only for /bin/bash interpreter.

Sunday, January 11, 2015

Is critical section a kernel object on Windows?

The answer is no, however, Windows creates event inside critical section object when a thread tries to acquire the object, but is blocked by another thread. The event is used in order to notify a blocked thread that the critical section object has been released and can be acquired again.