Which syscall is used for creating of new process/thread on OpenBSD-5.3 - pthreads

In Linux, 'clone()' syscall is used for creating processes/threads.
On OpenBSD-5.3 using ktrace/kdump I determined that for process creation 'vfork()' syscall is used, and for thread creation - 'tfork()'.
I have two questions:
Is my statement correct?
Shouldn't 'vfork()' and 'tfork()' finally use a single system call like 'clone()'?

I have not heard of clone(), but I would use fork(2) to create a new process and pthread_create(3) to create a new thread. These are portable.

Related

Register and spawn_link in Erlang not working together

I have a process running on node2. Can I register this process using register/2 on node1? Basically I am trying to do this:
register(process_name, spawn_link(node2, module, function, [Arg1, Arg2]))
I get this error:
** exception error: bad argument
in function register/2
called as register(process_name, <5902.92.0>)
When I register a process local to node1, this works perfectly fine. I could not find any documentation which prevents registration of processes of other nodes.
Thanks.
Actually it is well documented, and the expected behaviour as register() is for local process registration.
http://www.erlang.org/doc/man/erlang.html#register-2
Failure: badarg if PidOrPort is not an existing, local process or port, [...]
If you want global registration across your cluster, read http://erlang.org/doc/man/global.html
Note that if you use standard OTP behaviours, (gen_server, etc) most of the time you don't need to use the global module directly.

Are Indy 10 TCP command handlers asynchronous?

I have been having exceptions crop in my application, either stack overflow or our of memory. They show up in different places, depending on when the system has had enough. To put it another way, running the app twice won’t lead to the same exception in the same place.
I have some timers which cause database access. The AnyDac d/b component guys tell me that I can't reuse a global TADConnection but have to allocate it dynamically in each timer handler, which I have done.
I just thought that I had had a d'oh! moment when I looked at the latest stack trace.
fMainForm.TMainForm.GetToolNumberFromContext($31846FB4)
fMainForm.TMainForm.Received_HEART_BEAT($249AEFD0)
IdCommandHandlers.TIdCommand.DoCommand
IdCommandHandlers.TIdCommandHandler.DoCommand(???,$31846FB4,'')
IdCommandHandlers.TIdCommandHandler.Check('HEART_BEAT',$31846FB4)
IdCommandHandlers.TIdCommandHandlers.HandleCommand($31846FB4,'HEART_BEAT') <===
uADDatSManager.TADDatSRow.SetBlobLength($7DA10FDC,0,$C18DDDC,10,0,1,False)
uADDatSManager.TADDatSRow.SetBlobData($7DA10FDC,0,$C18DDDC,10,False)
uADDatSManager.TADDatSRow.SetData(0,$C18DDDC,10)
uADPhysMySQL.TADPhysMySQLCommand.FetchRow($7D2F4F90,nil)
uADPhysMySQL.TADPhysMySQLCommand.InternalFetchRowSet($7D2F4F90,nil,50)
uADPhysManager.DoFetch(0,50,50,False)
uADPhysManager.TADPhysCommand.FetchBase($7D2F4F90,False)
uADPhysManager.TADPhysCommandAsyncFetch.Execute
uADStanAsync.TADStanAsyncExecutor.ExecuteOperation(False)
uADStanAsync.TADStanAsyncExecutor.Run
uADPhysManager.TADPhysCommand.ExecuteTask(TADPhysCommandAsyncFetch($7DA24FEC) as IADStanAsyncOperation,TADPhysCommandAsyncFetch($7DA24FF8) as IADStanAsyncHandler,True)
uADPhysManager.TADPhysCommand.Fetch($7D2F4F90,False,True)
uADCompClient.TADCustomCommand.Fetch($7D2F4F90,False,True)
uADCompClient.TADCustomTableAdapter.Fetch(False)
uADCompClient.TADAdaptedDataSet.DoFetch($7D2F4F90,False,fdDown)
uADCompDataSet.TADDataSet.InternalFetchRows(False,True,fdDown)
uADCompDataSet.TADDataSet.GetRecord($7DA1AFF4,gmNext,True)
Data.DB.TDataSet.GetNextRecord
Data.DB.TDataSet.GetNextRecords
Data.DB.TDataSet.SetBufferCount(???)
Data.DB.TDataSet.UpdateBufferCount
Data.DB.TDataSet.DoInternalOpen
Data.DB.TDataSet.OpenCursor(???)
uADCompDataSet.TADDataSet.OpenCursor(False)
uADCompClient.TADRdbmsDataSet.OpenCursor(False)
Data.DB.TDataSet.SetActive(???)
uADCompDataSet.TADDataSet.SetActive(True)
Data.DB.TDataSet.Open
uADCompClient.TADRdbmsDataSet.Open('SELECT * FROM tagged_chemicals',(...),(...))
uADCompClient.TADRdbmsDataSet.Open('SELECT * FROM tagged_chemicals')
fMainForm.TMainForm.CheckEndOfScheduleTimerTimer($B116FAC)
Vcl.ExtCtrls.TTimer.Timer
Vcl.ExtCtrls.TTimer.WndProc(???)
System.Classes.StdWndProc(133584,275,1,0)
:768a62fa ; C:\Windows\syswow64\USER32.dll
:768a6d3a USER32.GetThreadDesktop + 0xd7
:768a77c4 ; C:\Windows\syswow64\USER32.dll
:768a788a USER32.DispatchMessageW + 0xf
Vcl.Forms.TApplication.ProcessMessage(???)
I don't understand that marked line, the sudden switch from AnyDac to Indy code
IdCommandHandlers.TIdCommandHandlers.HandleCommand($31846FB4,'HEART_BEAT') <===
uADDatSManager.TADDatSRow.SetBlobLength($7DA10FDC,0,$C18DDDC,10,0,1,False)
Can someone please explain it? Thanks
My first thought was that Indy was interrupting AnyDac, perhaps because it called Applciation.ProcessMessages or similar, but I don't see that on the stack ...
But if it can do that, then can it interrupt "normal" non-timer handler code?
I was sure that I had it cracked and that the problem was that my TCP command handlers were reusing an AnyDac component used by something else ... then I looked at my code and saw that there is no database access in the command handlers or in anything that they call.
I am stumped. Does what I wrote even make sense? Can anyone offer any advice?
Thanks a 1,000,000 in advance for any help.
Indy's commands handlers are used by TIdCmdTCPServer and TIdCmdTCPClient, which are both multi-threaded components. The command handlers are invoked inside of worker threads that Indy creates internally. There is no way that a command handler can interrupt an operation that is running in a different thread.

Default process flags

Is there a way to instruct the Erlang VM to apply a set of process flags to every new process that is spawned in the system?
For example in testing environment I would like every process to have save_calls flag set.
One way for doing this is to combine the Erlang tracing functionalities with a .erlang file.
Specifically, you could either use the low-level tracing capabilities provided by erlang:trace/3 or you could simply exploit the dbg:tracer/2 function to create a new tracing process which executes your custom handler function every time a tracing message is received.
To automate things a bit, you could then create an Erlang Start Up File in the directory where you're running your code or in your home directory. The Erlang Start Up File is a special file, called .erlang, which gets executed every time you start the run-time system.
Something like the following should do the job:
% -*- Erlang -*-
erlang:display("This is automatically executed.").
dbg:tracer(process, {fun ({trace, Pid, spawn, Pid2, {M, F, Args}}, Data) ->
process_flag(Pid2, save_calls, Data),
Data;
(_Trace, Data) ->
Data
end, 100}).
dbg:p(new, [procs, sos]).
Basically, I'm creating a new tracing process, which will trace processes (first argument). I'm specifying an handler function to get executed and some initial data. In the handler function, I'm setting the save_calls flag for newly spawned processes, whilst I'm ignoring all other tracing messages. I set the save_calls' option to 100, using the Initial Data parameter. In the last call, I'm telling dbg that I'm interested only in newly created processes. I'm also setting the sos (set_on_spawn) option to ensure inheritance of the tracing flags.
Finally, note how you need to use a variant of the process_flag function, which takes an extra argument (the Pid of the process you want to set the flag for).

Restart Delphi Application Programmatically

It should not be possible to run multiple instances of my application. Therefore the project source contains:
CreateMutex (nil, False, PChar (ID));
if (GetLastError = ERROR_ALREADY_EXISTS) then
Halt;
Now I want to restart my application programmatically. The usual way would be:
AppName := PChar(Application.ExeName) ;
ShellExecute(Handle,'open', AppName, nil, nil, SW_SHOWNORMAL) ;
Application.Terminate;
But this won't work in my case because of the mutex. Even if I release the mutex before starting the second instace it won't work because shutdown takes some time and two instance cannot run in parallel (because of common resources and other effects).
Is there a way to restart an application with such characteristics? (If possible without an additional executable)
Thanks in advance.
Perhaps you should think outside the box. Instead of futzing with the mutex / instance logic, you could simply create another executable that waits for your app to close then starts it again. As an added bonus, you can later use this mechanism to, for example, update some of your main app's binaries. It's also much easier to run it elevated instead of maintaining different integrity levels inside the same app, etc.
Why can't you just release the mutex before attempting to restart? If by some chance another instance gets going before the one you explicitly invoke with the restart that doesn't matter, you'll still have your app up and running again with whatever changes effected that required the restart. I don't think you need any of the complexity of the other solutions.
Include in your ShellExecute some parameter, for example, /WaitForShutDown and create one more mutex. In your program, before the initialization, for example, in its .dpr file, insert something like:
if (Pos('/WaitForShutDown', CmdLine) <> 0) then
WaitForSingleObject(ShutDownMutexHandle, INFINITE);
Also, in your program, after all the finalizations and releasing your common resources, include something like
ReleaseMutex(ShutDownMutexHandle);
EDIT...
OK. Now I belive that I know where is your problem...
You have problems with program units finalization!
Try to add at program section as first unit my bottom RestartMutex unit.
program MyProgramName;
uses
Mutex,
Forms,
...
;
unit RestartMutex;
interface
var
Restart: boolean = false;
implementation
uses
windows,
ShellApi;
var
MutexHandle: cardinal;
AppName: PChar;
const
ID = 'MyProgram';
initialization
MutexHandle := CreateMutex (nil, False, PChar (ID));
if (GetLastError = ERROR_ALREADY_EXISTS) then
Halt;
finalization
ReleaseMutex(MutexHandle);
if Restart then
begin
AppName := PChar('MyProgramName.exe') ;
ShellExecute(0,'open', AppName, nil, nil, SW_SHOWNORMAL) ;
end:
end.
When you want to restart application just set variable Restart to true and than terminate an application.
So, because is RestartMutex added as first in program section, this will couse that finalisation of unit RestartMutex will hepped nearly at the end of closing an application and all other units will do finalization before unit RestartMutex, that mean the Application can start safe again!
You could pass a command line argument like "restart" and run a Sleep() before you try to acquire the Mutex or try to acquire the mutex in a loop that sleeps a while.
Also you could set up communication between both processes, but that might be overkill.
hi take a look a the following article by Zarko Gajic - there you will get some ideas, sample code and even a whole component to use.
hth,
reinhard
Your ReleaseMutex is probably failing since you're passing 'False' for 'bInitialOwner' while calling CreateMutex. Either have the initial ownership of the mutex, or call CloseHandle instead of 'ReleaseMutex' passing your mutex handle.
checkout this way:
Simply runs a new application and kills the currernt one;
http://www.delphitricks.com/source-code/windows/restart_the_own_program.html
(beating the sleep idea)
if you want to make sure the original process is really terminated/closed before you create the mutex, then one idea is to pass the PID to the new process (command line is the easiest, any other IPC method works as well), then use OpenProcess(SYNCHRONIZE, false, pid) and WaitForSingleObject (I'd use a loop with a timeout (100 ms is a good value) and act accordingly if the original process takes too long to close)
What I ended up doing, beside the above, was to also create a RestartSelf procedure in the same unit with the mutex, and do the logic there, in order to keep the single instance and restart logic in the same place (the parameter being hardcoded, you don't want hardcoded stuff to be scattered around your application(s).

How to redirect registry access of a dll loaded by my program

I have got a dll that I load in my program which reads and writes its settings to the registry (hkcu). My program changes these settings prior to loading the dll so it uses the settings my program wants it to use which works fine.
Unfortunately I need to run several instances of my program with different settings for the dll. Now the approach I have used so far no longer works reliably because it is possible for one instance of the program to overwrite the settings that another instance just wrote before the dll has a chance to read them.
I haven't got the source of the dll in question and I cannot ask the programmer who wrote it to change it.
One idea I had, was to hook registry access functions and redirect them to a different branch of the registry which is specific to the instance of my program (e.g. use the process id as part of the path). I think this should work but maybe you have got a different / more elegant.
In case it matters: I am using Delphi 2007 for my program, the dll is probably written in C or C++.
As an alternative to API hooking, perhaps you could use RegOverridePredefKey API.
Instead of hooking the registry access for the dll, you can use an inter-process lock mechanism for writing the values to the registry for your own app. The idea being that the lock acquired by instance1 isn't released until its dll "instance" has read the values, so that when instance2 starts it won't acquire the lock until instance1 has finished. You'd need a locking mechanism that works between processes for this to work. For example mutexes.
To create mutexes:
procedure CreateMutexes(const MutexName: string);
//Creates the two mutexes checked for by the installer/uninstaller to see if
//the program is still running.
//One of the mutexes is created in the global name space (which makes it
//possible to access the mutex across user sessions in Windows XP); the other
//is created in the session name space (because versions of Windows NT prior
//to 4.0 TSE don't have a global name space and don't support the 'Global\'
//prefix).
const
SECURITY_DESCRIPTOR_REVISION = 1; // Win32 constant not defined in Delphi 3
var
SecurityDesc: TSecurityDescriptor;
SecurityAttr: TSecurityAttributes;
begin
// By default on Windows NT, created mutexes are accessible only by the user
// running the process. We need our mutexes to be accessible to all users, so
// that the mutex detection can work across user sessions in Windows XP. To
// do this we use a security descriptor with a null DACL.
InitializeSecurityDescriptor(#SecurityDesc, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(#SecurityDesc, True, nil, False);
SecurityAttr.nLength := SizeOf(SecurityAttr);
SecurityAttr.lpSecurityDescriptor := #SecurityDesc;
SecurityAttr.bInheritHandle := False;
CreateMutex(#SecurityAttr, False, PChar(MutexName));
CreateMutex(#SecurityAttr, False, PChar('Global\' + MutexName));
end;
To release a mutex, you'd use the ReleaseMutex API and to acquire a created mutex, you'd use the OpenMutex API.
For CreateMutex see: http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx
For OpenMutex see: http://msdn.microsoft.com/en-us/library/ms684315(v=VS.85).aspx
For ReleaseMutex see: http://msdn.microsoft.com/en-us/library/ms685066(v=VS.85).aspx
dirty method: open the dll in a hexeditor and change/alter the registry-path from the original hive to any other you want to use or have your proper settings.

Resources