sigsetjmp/siglongjmp and open file


Topic author
theoldman
Member
Posts: 6
Joined: Fri Feb 26, 2021 5:48 pm
Reputation: 0
Status: Offline

sigsetjmp/siglongjmp and open file

Post by theoldman » Wed May 22, 2024 2:43 pm

Overview (test program attached):

1. sigsetjmp(jmpbuf,1);
2. fopen a file
3. signal(SIGALRM,TOSTMER_TRAP);
4. copy jmpbuf to static so TOSTMER_TRAP can use it
5. alarm(secs)
6. Alarm pops, TOSTMER_TRAP called, resets SIGALRM, siglongjmp, goto to end of program
7. Attempt to fclose() file, get "mount point busy"
8. Attempt to remove() file, get "file locked by another process" even though this is the only process using it.

Somehow the siglongjmp back to the sigsetjmp point is causing the file descriptor to get confused. Note that FILE *fp is in a structure and so is not in a register saved by sigsetjmp. This works on the various unix varieties (linux, solaris, aix).

Any insight is appreciated,
Regards,
Paul
Attachments
vmstmr3.c
(1.38 KiB) Downloaded 64 times


jonesd
Valued Contributor
Posts: 90
Joined: Mon Aug 09, 2021 7:59 pm
Reputation: 0
Status: Offline

Re: sigsetjmp/siglongjmp and open file

Post by jonesd » Mon May 27, 2024 1:23 pm

theoldman wrote:
Mon May 27, 2024 12:39 pm

In banging on this earlier it did occur to me that perhaps the alarm interrupt pops in the middle of the fwrite and something that needs to be written to the file system internal cb gets messed up due to the siglongjmp. In the "real "code we are not pounding fwrites, there is much activity in between. So if that was the case I would expect this error be sporadic, not perfectly reproducible. I am going to simplify my test to do just a few fwrites, then wait on getchar() for the alarm to pop and see if fclose() works.
I've attached my version of the vmstmr3 test program.
Attachments
vmstmr3-ansi.c
(3.13 KiB) Downloaded 56 times


Topic author
theoldman
Member
Posts: 6
Joined: Fri Feb 26, 2021 5:48 pm
Reputation: 0
Status: Offline

Re: sigsetjmp/siglongjmp and open file

Post by theoldman » Fri Jun 07, 2024 6:12 pm

Ok horrifying hack warning, read at your own risk:

1. static int traphit = 0;
2. local signal handler function localhandler. It turns off SIGALRM, sets traphit = 1, returns.
3. Before file operation savehndlr = signal(SIGALRM,localhandler)
4. After file operation signal(SIGALRM,savehndlr);
5. if traphit call savehndlr which then does the longjmp.

Allowing the file operation (fprintf, fread, fseek...) to complete before calling the longjmp makes it work. Slight windows where might miss the SIGALRM but that's not a big problem in the application. Somehow this is issue never occurs on Windows or Linux (or at least I cannot duplicate it there).

Post Reply