Bug 8044 - 4.0.0 RC2 crash on Windows
Summary: 4.0.0 RC2 crash on Windows
Status: RESOLVED MOVED
Alias: None
Product: Spamassassin
Classification: Unclassified
Component: Libraries (show other bugs)
Version: 4.0.0
Hardware: PC Windows 10
: P2 normal
Target Milestone: Undefined
Assignee: SpamAssassin Developer Mailing List
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-09-14 13:38 UTC by RvdH
Modified: 2022-09-26 19:30 UTC (History)
5 users (show)



Attachment Type Modified Status Actions Submitter/CLA Status
spamd.log text/plain None RvdH [NoCLA]
patch to make default for pyzor_fork and razor_fork 0 on Windows. Mention in perldoc patch None Sidney Markowitz [HasCLA]
MSG_DONTWAIT workaround for Windows in DnsResolver patch None Sidney Markowitz [HasCLA]
MSG_DONTWAIT workaround for Windows in DnsResolver, v2 patch None Sidney Markowitz [HasCLA]
MSG_DONTWAIT workaround for Windows in DnsResolver, v3 patch None Sidney Markowitz [HasCLA]

Note You need to log in before you can comment on or make changes to this bug.
Description RvdH 2022-09-14 13:38:55 UTC
Created attachment 5816 [details]
spamd.log

I had some strange crashes on Windows using 4.0.0 RC2, spamd would just stop without error and/or warning, even when using --debug

Meanwhile i have found the possible reason, eg: when using Razor2::Client::Agent version 2.86 it crashes, but with Razor2::Client::Agent, version 2.84 it works OK

I’ have attached a example spamd log using when using Razor2::Client::Agent version 2.86 that suddenly crashed without warning/reason, see line 2597
Strange thing is the fact it doesn’t happen every time, some messages are processed correctly, others are not due to this crash 
 
My SA 4.0 rc2 test instance config, is pretty straight forward, only using default plugins & KAM rules
Comment 1 Henrik Krohns 2022-09-14 14:46:32 UTC
Perhaps try "razor_fork 0" setting if it makes a difference. Default forks a parallel process, maybe something funky there.
Comment 2 RvdH 2022-09-14 15:21:13 UTC
Not sure if 2.84 vs 2.86 makes so much difference after all... same crash happens with 2.84 (but as before not every time)

but if i disable razor2 altogether it won't crash at all, so it has to be related to razor2, what version Razor2::Client::Agent am i supposed to use, latest? (eg: 2.86)
Comment 3 RvdH 2022-09-14 18:16:21 UTC
(In reply to Henrik Krohns from comment #1)
> Perhaps try "razor_fork 0" setting if it makes a difference. Default forks a
> parallel process, maybe something funky there.

razor_fork 0 seems to fix this issue on Windows, but that is not ideal is it?
Comment 4 Kevin A. McGrail 2022-09-14 21:14:30 UTC
The forking is a brand new feature so it might have some bugs especially under windows.  No it is not ideal BUT it's no worse than 3.4.x with the forking disabled.
Comment 5 Henrik Krohns 2022-09-14 23:09:44 UTC
The fork() limitations are well documented for Windows:
https://perldoc.perl.org/perlfork

As we now have a real tester with results, it might be prudent to set all *_fork defaults as 0 on Windows.
Comment 6 RvdH 2022-09-15 07:44:37 UTC
(In reply to Henrik Krohns from comment #5)
> The fork() limitations are well documented for Windows:
> https://perldoc.perl.org/perlfork
> 
> As we now have a real tester with results, it might be prudent to set all
> *_fork defaults as 0 on Windows.

Real tester? :-) That is way to much credits... 

The guys at Jam don't really excel to provide updates for SpamAssassin for Windows (eg: 3.4.4 is their latest), so i grabbed their latest source and started hacking/patching their distribution. 
I noticed the executables (spamd.exe, sa-update.exe, sa-learn.exe etc) are basically wrappers for the actual perl files located in the /runtime directory of their windows build, so i updated those to reflect version 4.000000, update all the libs in the /runtime/inc/libs and installed the missing/updated perl packages. I had done the same patching for 3.4.6 earlier so i realized their was a good chance this could be done for 4.0.0 as well.


FYI, I tried to build my own Windows version, but build instructions for Windows all seem outdated, and couldn't make it work so i gave up on that.
Comment 7 Sidney Markowitz 2022-09-15 12:20:07 UTC
(In reply to Henrik Krohns from comment #5)
> The fork() limitations are well documented for Windows:
> https://perldoc.perl.org/perlfork
> 
> As we now have a real tester with results, it might be prudent to set all
> *_fork defaults as 0 on Windows.

That's just pyzor and razor2? Just a matter of

 default => am_running_on_windows()?0:1,

in Pyzor.pm and razor2.pm in the settings for *_fork?

Seems reasonable to me to get that in for 4.0.0
Comment 8 Sidney Markowitz 2022-09-15 12:25:43 UTC
(In reply to RvdH from comment #6)
> FYI, I tried to build my own Windows version, but build instructions for
> Windows all seem outdated, and couldn't make it work so i gave up on that.

We haven't had any serious Windows people for a while. I build the perl part and run the tests on Windows, but don't have any idea what is needed for spamd, spamc, and sa-update now.

If you feel like writing up a new set of instructions describing what you did, it's a wiki, so please, go for it. We would appreciate it.
Comment 9 Henrik Krohns 2022-09-15 13:09:38 UTC
(In reply to Sidney Markowitz from comment #7)
> (In reply to Henrik Krohns from comment #5)
> > The fork() limitations are well documented for Windows:
> > https://perldoc.perl.org/perlfork
> > 
> > As we now have a real tester with results, it might be prudent to set all
> > *_fork defaults as 0 on Windows.
> 
> That's just pyzor and razor2? Just a matter of
> 
>  default => am_running_on_windows()?0:1,
> 
> in Pyzor.pm and razor2.pm in the settings for *_fork?
> 
> Seems reasonable to me to get that in for 4.0.0

Yeah along with some mention in the doc. Probably safer this way, and the few windows users can always experiment enabling if wanted..
Comment 10 RvdH 2022-09-15 13:23:16 UTC
Got another error just now....

Thu Sep 15 14:45:40 2022 [-4780] info: spamd: connection from server.com [127.0.0.1]:50699 to port 783, fd 6
Thu Sep 15 14:45:40 2022 [-4780] info: spamd: processing message <AeucGVaiMo_obt6b@sendersrv.com> for (unknown):0
Thu Sep 15 14:45:40 2022 [-4780] warn: spamd: Timeout::_run: Your vendor has not defined Socket macro MSG_DONTWAIT, used at C:\\Program Files\\JAM Software\\SpamAssassin for Windows\\runtime\\inc\\lib/Mail/SpamAssassin/DnsResolver.pm line 924
Thu Sep 15 14:45:40 2022 [2260] info: prefork: child states: II

Have been running this SA 4.x instance all day on a VM, and this is the first time this error popups
Comment 11 Sidney Markowitz 2022-09-15 13:25:06 UTC
Created attachment 5819 [details]
patch to make default for pyzor_fork and razor_fork 0 on Windows. Mention in perldoc

Here's a proposed patch, ready for voting
Comment 12 Sidney Markowitz 2022-09-15 13:47:05 UTC
(In reply to RvdH from comment #10)
> Your vendor has not defined Socket macro MSG_DONTWAIT

Which version of perl are you running?
Comment 13 RvdH 2022-09-15 13:49:25 UTC
Perl 5.030000 (as that was what the orginal JAM Windows version was build with)
Comment 14 RvdH 2022-09-15 13:59:42 UTC
Hold on, think i might be responsible for that error, was testing some things Henrik says are impossible to do, see https://bz.apache.org/SpamAssassin/show_bug.cgi?id=8046
Comment 15 RvdH 2022-09-15 17:12:40 UTC
(In reply to RvdH from comment #10)
> Got another error just now....
> 
> Thu Sep 15 14:45:40 2022 [-4780] info: spamd: connection from server.com
> [127.0.0.1]:50699 to port 783, fd 6
> Thu Sep 15 14:45:40 2022 [-4780] info: spamd: processing message
> <AeucGVaiMo_obt6b@sendersrv.com> for (unknown):0
> Thu Sep 15 14:45:40 2022 [-4780] warn: spamd: Timeout::_run: Your vendor has
> not defined Socket macro MSG_DONTWAIT, used at C:\\Program Files\\JAM
> Software\\SpamAssassin for
> Windows\\runtime\\inc\\lib/Mail/SpamAssassin/DnsResolver.pm line 924
> Thu Sep 15 14:45:40 2022 [2260] info: prefork: child states: II
> 
> Have been running this SA 4.x instance all day on a VM, and this is the
> first time this error popups

No, this issue still occurs... once i restart spamd the message comes through OK

Thu Sep 15 18:21:37 2022 [6832] info: prefork: child states: II
Thu Sep 15 19:03:04 2022 [-6428] info: spamd: connection from server.com [127.0.0.1]:51107 to port 783, fd 6
Thu Sep 15 19:03:04 2022 [-6428] info: spamd: processing message <SHU55lLkY6tdov30yh9VpQPZZhdtC0GoRmjpfjos184@domain.com> for (unknown):0
Thu Sep 15 19:03:04 2022 [-6428] warn: spamd: Timeout::_run: Your vendor has not defined Socket macro MSG_DONTWAIT, used at C:\\Program Files\\JAM Software\\SpamAssassin for Windows\\runtime\\inc\\lib/Mail/SpamAssassin/DnsResolver.pm line 924
Thu Sep 15 19:03:04 2022 [6832] info: prefork: child states: II
Thu Sep 15 19:04:12 2022 [6832] info: spamd: server killed by SIGINT, shutting down
Thu Sep 15 19:04:24 2022 [3356] info: spamd: server started on IO::Socket::IP [127.0.0.1]:783 (running version 4.0.0-rc2)
Thu Sep 15 19:04:24 2022 [3356] info: spamd: server pid: 3356
Thu Sep 15 19:04:24 2022 [3356] info: spamd: server successfully spawned child process, pid -3116
Thu Sep 15 19:04:25 2022 [3356] info: spamd: server successfully spawned child process, pid -1308
Thu Sep 15 19:04:25 2022 [3356] info: prefork: child states: II
Thu Sep 15 19:04:33 2022 [-3116] info: spamd: connection from server.com [127.0.0.1]:51131 to port 783, fd 6
Thu Sep 15 19:04:33 2022 [-3116] info: spamd: processing message <SHU55lLkY6tdov30yh9VpQPZZhdtC0GoRmjpfjos184@domain.com> for (unknown):0
Thu Sep 15 19:04:34 2022 [-3116] info: spamd: identified spam (15.6/4.0) for (unknown):0 in 1.8 seconds, 2667 bytes.
Thu Sep 15 19:04:34 2022 [-3116] info: spamd: result: Y 15 - ALL_TRUSTED,BAYES_99,BAYES_999,FREEMAIL_FORGED_REPLYTO,FREEMAIL_REPLYTO_END_DIGIT,KAM_DMARC_STATUS,KAM_MARKSPAM,RAZOR2_CF_RANGE_51_100,RAZOR2_CHECK,URIBL_ABUSE_SURBL,URIBL_DBL_SPAM scantime=1.8,size=2667,user=(unknown),uid=0,required_score=4.0,rhost=server.com,raddr=127.0.0.1,rport=51131,mid=<SHU55lLkY6tdov30yh9VpQPZZhdtC0GoRmjpfjos184@domain.com>,bayes=1.000000,autolearn=spam autolearn_force=no
Thu Sep 15 19:04:34 2022 [3356] info: prefork: child states: II

I will run spamd in --debug mode on hope this error will reoccur and maybe someone here can see what is going wrong
I'll keep you posted
Comment 16 RvdH 2022-09-15 20:15:58 UTC
Appears Windows don't have MSG_DONTWAIT, so looks like a need to switch socket into non-blocking mode, example:
https://github.com/p5-RedisDB/RedisDB/blob/master/lib/RedisDB.pm#L423-L442
Comment 17 RvdH 2022-09-15 21:10:16 UTC
I'm not much of a perl coder, so if anyone can update/patch 4.0.0rc2 DnsResolver.pm (which introduced MSG_DONTWAIT, as this is not in 3.4.x) to include the workaround suggested in the RedisDB example posted here: https://bz.apache.org/SpamAssassin/show_bug.cgi?id=8044#c16 I am more than happy to test it 



@Sidney, it applies the patches described here, https://bz.apache.org/SpamAssassin/attachment.cgi?id=5819&action=diff

Seems to work OK (so far)
Comment 18 Sidney Markowitz 2022-09-15 23:32:27 UTC
Henrik, flush_responses in DnsResolver.pm is your code and I'm not that familiar with socket stuff. I have confirmed that MSG_DONTWAIT doesn't exist in Windows perl versions. As a macro, it looks like the only way to test if it exists is in an eval, e.g.

my $recvflags = 0;
eval {$recvflags = MSG_NOWAIT};

And then, I guess, like in
https://github.com/p5-RedisDB/RedisDB/blob/master/lib/RedisDB.pm#L423-L442

use something like
$self->{sock}->blocking(0) unless ($recvflags);

and then set it back later 

$self->{sock}->blocking(0\1) unless ($recvflags);

Can you do that? I don't know enough to be sure where in the code is the best place to put it without breaking flush_response.
Comment 19 Sidney Markowitz 2022-09-15 23:41:24 UTC
(In reply to RvdH from comment #17)
>I am more than happy to test it 

Ruud, could you update the wiki instructions on building spamd on Windows to include whatever you did to build it? That way I could do some testing of it too.

https://cwiki.apache.org/confluence/display/SPAMASSASSIN/SpamdOnWindows

If you don't already have edit access to the wiki, click on my name in this comment to send me an email with your wiki login name and I'll give it access. Or if that is too much, email me the instructions and I'll update the page.

Thanks
Comment 20 Sidney Markowitz 2022-09-16 01:01:22 UTC
Created attachment 5820 [details]
MSG_DONTWAIT workaround for Windows in DnsResolver

Henrik, I decided to take a shot at it anyway, but can you please look this over?

Since it should have no effect on platforms that define MSG_DONTWAIT and the existing code can't run on Windows anyway, it seems like a safe patch to include for the release if it looks ok to you.

Ruud, could you try out this patch and see how it behaves on Windows?
Comment 21 Sidney Markowitz 2022-09-16 01:12:12 UTC
Targeting for the 4.0.0 release
Comment 22 Sidney Markowitz 2022-09-16 01:55:32 UTC
Created attachment 5821 [details]
MSG_DONTWAIT workaround for Windows in DnsResolver, v2

Missed an error that generates a warning in that last patch
Comment 23 Sidney Markowitz 2022-09-16 03:35:42 UTC
And, even more mistakes... I ran tests on Windows that I thought exercised the code, then discovered that it only did enough to fid compilation errors. v3 coming up after I complete real tests on Windows.
Comment 24 Sidney Markowitz 2022-09-16 03:43:23 UTC
Created attachment 5822 [details]
MSG_DONTWAIT workaround for Windows in DnsResolver, v3

version 3, now with fewer typos!
Comment 25 RvdH 2022-09-16 07:06:47 UTC
@Sidney

As mentioned earlier in this topic i haven't been able to successfully build a Windows version myself but patched my way around it using "Jam Software SpamAssassin for Windows 3.4.4" download as base. 

https://bz.apache.org/SpamAssassin/show_bug.cgi?id=8044#c6

I can write detailed how to, but wonder if that worth mentioning on the wiki?
Comment 26 RvdH 2022-09-16 07:07:50 UTC
(In reply to Sidney Markowitz from comment #24)
> Created attachment 5822 [details]
> MSG_DONTWAIT workaround for Windows in DnsResolver, v3
> 
> version 3, now with fewer typos!

Have applied the patch and am now testing it
Comment 27 Sidney Markowitz 2022-09-16 07:19:00 UTC
(In reply to RvdH from comment #25)
> patched my way around it using "Jam Software
> SpamAssassin for Windows 3.4.4" download as base. 

Oh, so you just use their exe and substituted the current spamd perl components that it wraps around? If that's it then I guess I'll start with that and see if I can come up with an updated wrapper that works.
Comment 28 RvdH 2022-09-16 07:32:11 UTC
needed:

- SpamAssassinForWindows-v3.4.4-x64.zip
- strawberry-perl-5.30.0.1-64bit.msi


=================================================


perl -MCPAN -e shell

install Archive::Zip

force install SIDNEY/Mail-SpamAssassin-4.0.0-rc2-TRIAL.tar.gz


=================================================


Unzip SpamAssassinForWindows-v3.4.4-x64.zip into C:\SpamAssassin for example

Copy everything from C:\Strawberry\perl\site\lib into C:\SpamAssassin\Runtime\inc\lib


Patch, i used Winmerge to detect changes in sa-update, sa-learn, spamassassin in C:\Strawberry\perl\site\bin to the ones in C:\SpamAssassin\Runtime\
spamd was not in C:\Strawberry\perl\site\bin, so i simply grabbed spamd from C:\SpamAssassin\Runtime\ and replaced every instance of the word 3.004004 with 4.000000

After that run sa-update and you should be good to go
Comment 29 RvdH 2022-09-16 07:33:29 UTC
(In reply to Sidney Markowitz from comment #27)
> (In reply to RvdH from comment #25)
> > patched my way around it using "Jam Software
> > SpamAssassin for Windows 3.4.4" download as base. 
> 
> Oh, so you just use their exe and substituted the current spamd perl
> components that it wraps around? If that's it then I guess I'll start with
> that and see if I can come up with an updated wrapper that works.

Exactly, short/basic how to posted above
Comment 30 RvdH 2022-09-16 07:40:34 UTC
(In reply to RvdH from comment #29)
> (In reply to Sidney Markowitz from comment #27)
> > (In reply to RvdH from comment #25)
> > > patched my way around it using "Jam Software
> > > SpamAssassin for Windows 3.4.4" download as base. 
> > 
> > Oh, so you just use their exe and substituted the current spamd perl
> > components that it wraps around? If that's it then I guess I'll start with
> > that and see if I can come up with an updated wrapper that works.
> 
> Exactly, short/basic how to posted above

One thing i forgot to mention, i had to use rename perl530.dll in C:\SpamAssassin to perl530.bak, otherwise not all modules would show up as installed...this doesn't matter as long as it is able to use perl located in C:\Strawberry\perl
Comment 31 RvdH 2022-09-16 08:48:03 UTC
when running spamassassin --lint --debug a folder "C:\.spamassassin" is created automatically, eg:
Sep 14 23:23:52.629 [3804] dbg: config: global_state_dir set to \\.spamassassin


What is this new global_state_dir, and is there a way to control where it is created?




When running spamd.exe i can control global_state_dir location with --helper-home-dir parameter, but i can't with spamassassin.exe 

Thu Sep 15 21:46:49 2022 [-1748] dbg: config: global_state_dir set to C:\\ProgramData\\.spamassassin
Comment 32 Henrik Krohns 2022-09-16 09:47:52 UTC
(In reply to RvdH from comment #31)
> when running spamassassin --lint --debug a folder "C:\.spamassassin" is
> created automatically, eg:
> Sep 14 23:23:52.629 [3804] dbg: config: global_state_dir set to
> \\.spamassassin
> 
> 
> What is this new global_state_dir, and is there a way to control where it is
> created?
> 
> 
> 
> 
> When running spamd.exe i can control global_state_dir location with
> --helper-home-dir parameter, but i can't with spamassassin.exe 
> 
> Thu Sep 15 21:46:49 2022 [-1748] dbg: config: global_state_dir set to
> C:\\ProgramData\\.spamassassin

Yes helper home dir (default = user home) is used first if available.

It seems Util::portable_getpwuid sets "/" as user home on Windows. Not sure if this is the best practise, but probably better not to mess with it.

Perhaps just fix set_global_state_dir to skip the portable_getpwuid parts and let global state dir end up as LOCAL_STATE_DIR/userstate_dir.
Comment 33 Henrik Krohns 2022-09-16 09:51:30 UTC
To clarify, global state dir was created to be able to keep state for things at highest possible shared level across SA processes. Currently it's only used for dns_block_rule state files (for example URIBL_BLOCKED).
Comment 34 RvdH 2022-09-16 10:10:54 UTC
default = user home

FYI, when not specified, user home on Windows automatically uses: C:\Windows\System32\config\systemprofile

This can problematic with windows updates (i had this in the past with 3.4.x) as a Windows Feature, for Example Windows 10 22H1 > Windows 10 22H2 update overwrites this directory. I lost my bayes db, razor conf etc due to this
Comment 35 Henrik Krohns 2022-09-16 10:15:21 UTC
I see ArchiveIterator.pm has it's own workarounds

      # No $HOME set?  Try to find it, portably.
      unless ($home) {
        if (!Mail::SpamAssassin::Util::am_running_on_windows()) {
          $home = (Mail::SpamAssassin::Util::portable_getpwuid($<))[7];
        } else {
          my $vol = $ENV{'HOMEDRIVE'} || 'C:';
          my $dir = $ENV{'HOMEPATH'} || '\\';
          $home = File::Spec->catpath($vol, $dir, '');
        }

Looks perhaps more like that portable_getpwuid itself should implement something like this.

Sorry this bug starts to get messy with multiple problems and patches. Hopefully Sidney or someone can sort these out to maybe own bugs for easier voting.
Comment 36 RvdH 2022-09-16 10:17:25 UTC
(In reply to RvdH from comment #34)
> default = user home
> 
> FYI, when not specified, user home on Windows automatically uses:
> C:\Windows\System32\config\systemprofile
> 
> This can problematic with windows updates (i had this in the past with
> 3.4.x) as a Windows Feature, for Example Windows 10 22H1 > Windows 10 22H2
> update overwrites this directory. I lost my bayes db, razor conf etc due to
> this


Addendum, when spamd.exe is ran as a service as "Local System"
Comment 37 RvdH 2022-09-16 10:25:39 UTC
(In reply to Henrik Krohns from comment #35)
> Sorry this bug starts to get messy with multiple problems and patches.
> Hopefully Sidney or someone can sort these out to maybe own bugs for easier
> voting.

Yes, sorry for that... i just posted them errors here as/when they occurred as i noticed you guys seem to be preparing for the 4.0.0 milestone release...

That was the sole reason i gave 4.0.0-rc2 a testrun on a VM, mainly because i am aware there won't be many Windows user in the hope i could catch the biggest errors before the 4.0.0 final release.

FYI, i think we are doing quite nicely and it runs pretty stable, not seen a MSG_DONTWAIT error once i patched DnsResolver.pm
Comment 38 Henrik Krohns 2022-09-16 10:39:20 UTC
(In reply to Sidney Markowitz from comment #24)
> Created attachment 5822 [details]
> MSG_DONTWAIT workaround for Windows in DnsResolver, v3
> 
> version 3, now with fewer typos!

I think the logic has bug..

$self->{sock}->blocking(0) unless(RECV_FLAGS);
..
$self->{sock}->blocking(1) if(RECV_FLAGS);

Both should be unless(RECV_FLAGS) so the blocking is correctly unset and set?

$self->{sock}->blocking(0) unless(RECV_FLAGS);
..
$self->{sock}->blocking(1) unless(RECV_FLAGS);
Comment 39 RvdH 2022-09-16 11:08:05 UTC
(In reply to Henrik Krohns from comment #35)
> I see ArchiveIterator.pm has it's own workarounds
> 
>       # No $HOME set?  Try to find it, portably.
>       unless ($home) {
>         if (!Mail::SpamAssassin::Util::am_running_on_windows()) {
>           $home = (Mail::SpamAssassin::Util::portable_getpwuid($<))[7];
>         } else {
>           my $vol = $ENV{'HOMEDRIVE'} || 'C:';
>           my $dir = $ENV{'HOMEPATH'} || '\\';
>           $home = File::Spec->catpath($vol, $dir, '');
>         }
> 
> Looks perhaps more like that portable_getpwuid itself should implement
> something like this.
> 
> Sorry this bug starts to get messy with multiple problems and patches.
> Hopefully Sidney or someone can sort these out to maybe own bugs for easier
> voting.

That else statement is specifically for Windows? 
ALLUSERSAPPDATA seems more appropriate, https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables

> The file-system directory that contains application data for all users. A typical > path Windows is C:\ProgramData.

my $vol = $ENV{'HOMEDRIVE'} || 'C:';
my $dir = $ENV{'ALLUSERSAPPDATA'} || '\\';
$home = File::Spec->catpath($vol, $dir, '');
Comment 40 RvdH 2022-09-16 11:13:56 UTC
(In reply to RvdH from comment #39)
> (In reply to Henrik Krohns from comment #35)
> > I see ArchiveIterator.pm has it's own workarounds
> > 
> >       # No $HOME set?  Try to find it, portably.
> >       unless ($home) {
> >         if (!Mail::SpamAssassin::Util::am_running_on_windows()) {
> >           $home = (Mail::SpamAssassin::Util::portable_getpwuid($<))[7];
> >         } else {
> >           my $vol = $ENV{'HOMEDRIVE'} || 'C:';
> >           my $dir = $ENV{'HOMEPATH'} || '\\';
> >           $home = File::Spec->catpath($vol, $dir, '');
> >         }
> > 
> > Looks perhaps more like that portable_getpwuid itself should implement
> > something like this.
> > 
> > Sorry this bug starts to get messy with multiple problems and patches.
> > Hopefully Sidney or someone can sort these out to maybe own bugs for easier
> > voting.
> 
> That else statement is specifically for Windows? 
> ALLUSERSAPPDATA seems more appropriate,
> https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-
> environment-variables
> 
> > The file-system directory that contains application data for all users. A typical > path Windows is C:\ProgramData.
> 
> my $vol = $ENV{'HOMEDRIVE'} || 'C:';
> my $dir = $ENV{'ALLUSERSAPPDATA'} || '\\';
> $home = File::Spec->catpath($vol, $dir, '');

For global_state_dir that is :-)
Comment 41 Henrik Krohns 2022-09-16 11:21:22 UTC
(In reply to RvdH from comment #40)
> For global_state_dir that is :-)

Yes portable_getpwuid should not return home for all users.

There is no ALLUSERSAPPDATA set on my Windows.

I do have ALLUSERSPROFILE=C:\ProgramData, maybe use that inside set_global_state_dir? Should I'm not sure what benefits this would bring over just using LOCAL_STATE_DIR.
Comment 42 RvdH 2022-09-16 11:24:38 UTC
(In reply to Henrik Krohns from comment #41)
> (In reply to RvdH from comment #40)
> > For global_state_dir that is :-)
> 
> Yes portable_getpwuid should not return home for all users.
> 
> There is no ALLUSERSAPPDATA set on my Windows.
> 
> I do have ALLUSERSPROFILE=C:\ProgramData, maybe use that inside
> set_global_state_dir? Should I'm not sure what benefits this would bring
> over just using LOCAL_STATE_DIR.

Oops, should have checked that first, i simply trusted/expected the microsoft documentation to be accurate
Comment 43 RvdH 2022-09-16 11:30:52 UTC
(In reply to RvdH from comment #42)
> (In reply to Henrik Krohns from comment #41)
> > (In reply to RvdH from comment #40)
> > > For global_state_dir that is :-)
> > 
> > Yes portable_getpwuid should not return home for all users.
> > 
> > There is no ALLUSERSAPPDATA set on my Windows.
> > 
> > I do have ALLUSERSPROFILE=C:\ProgramData, maybe use that inside
> > set_global_state_dir? Should I'm not sure what benefits this would bring
> > over just using LOCAL_STATE_DIR.
> 
> Oops, should have checked that first, i simply trusted/expected the
> microsoft documentation to be accurate

cd %ALLUSERSPROFILE%
C:\ProgramData>

Tested on Windows 10, Windows 11, Windows Server 2019 and Windows Server 2022

Not saying you must use ALLUSERSPROFILE, if you prefer LOCAL_STATE_DIR that is fine with me, the only issue i had is the creation of C:\.SpamAssassin somehow irritated me :)
Comment 44 Sidney Markowitz 2022-09-16 15:01:02 UTC
(In reply to Henrik Krohns from comment #38)
> > version 3, now with fewer typos!
> 
> I think the logic has bug..
..
> Both should be unless(RECV_FLAGS) so the blocking is correctly unset and set?

Yes, well one typo is still fewer than three :)

And you are correct, this bug is a mess, but it is a useful mess.
I'll go ahead and open two new bugs, one for the no fork on windows patch and one for the DnsResolver on Windows issue so they can be cleanly voted on.

I'll leave this one open for any remaining discussion on building the Windows version.
Comment 45 Sidney Markowitz 2022-09-16 15:59:10 UTC
I've created bug 8047 "MSG_DONTWAIT error in DnsResolver on Windows" with v4 corrected patch ready for voting.

And bug 8048 "Make default setting for *_fork config options 0 on Windows" with the patch there, also ready for voting.

Regarding building spamc and spamd on Windows, it turns out that no patches are necessary, we didn't let the bits rot as much as I thought we had after all.

Now that Strawberry Perl bundles gmake and puts it in the command line, all you have to do on Windows with Strawberry Perl and the free version of Visual Studio installed is to open a Visual Studio command prompt for native 32 or 64 bit build as appropriate, and in that command shell in the SpamAssassin source directory run
  perl Makeilfile.PL
answer yes to building spamc and spamd when it prompts you
then run
  gmake
  gmake install

I think this will install everything into the default perl location, which is usually \Strawberry. I happen to have set up local::lib and everything ended up in my \Users\sidney\perl5 directory, I think as a result of that. You could probably use the prefix options to Makefile.PL to have things end up elsewhere, but you may need to adjust PATH environment variable if you do that.

To run spamd, just open an ordinary cmd shell and run it from the command line without the -d option, leaving it running in that window.

You can run spamc from another cmd window.

Setting up a wrapper to run spamd as a service is left as an exercise for the reader, who if one exists who does it is invited to write up how on the wiki.
Comment 46 RvdH 2022-09-16 17:05:22 UTC
Ah, that explains...I tried to build with nmake like the wiki said, I will try your build instructions tomorrow (if I have the time)

JAM package also has executables for sa-learn and  sa-update, how did they build those?

And is is it worth to also have sa-compile as executable? (JAM also lacks this)
Comment 47 Sidney Markowitz 2022-09-16 17:36:13 UTC
(In reply to RvdH from comment #46)
 And is is it worth to also have sa-compile as executable? (JAM also lacks
> this)

All the executables except spamc are perl scripts, which on Unix and macOS the command shell recognizes as executables that are run by launching perl. cmd.exe doesn't do that, so the makefile packages them up as bat files that have batch commands that invoke perl in a way that reads the perl script that follows in the very same bat file. So spamd ends up as spamd.bat.

As a result only spamc requires Visual Studio to build, and other than spamc.exe you don't need exe files since you have the bat files.

sa-compile is another issue, as it requires that you install re2c which is a program that converts regular expressions to c, then you need a C compiler to compile the results, and then the resulting executables have to be run. I haven't tried getting all that working under Windows, so I don't know how much of it, if anything, has been implemented to work in Windows. Since the purpose is only to get the rules to run faster than if they were run in pure perl, with no change in functionality, it might not even be worth the effort to get it working in Windows.
Comment 48 RvdH 2022-09-16 19:42:56 UTC
Mmmmm, OK
Although executables are preferred, especially for spamd.exe to be able to make it run like a service using something like nssm, https://nssm.cc/usage

How did the people at JAM Software create those executables? They supply executables for spamd.exe, spamc.exe, spamassassin.exe, sa-learn.exe and sa-update.exe...or are these just executable launchers/wrappers for the perl files? (I think so, otherwise my manual updating to 4.0.0 should not had worked)

FYI, Your build instructions worked fine, using gmake
Comment 49 Loren Wilton 2022-09-16 19:58:35 UTC
(In reply to Sidney Markowitz from comment #45)
> To run spamd, just open an ordinary cmd shell and run it from the command
> line without the -d option, leaving it running in that window.

A perhaps cleaner way to do this is to create a shortcut to spamd and place it in the user's "Startup" folder. The user must log on before spamd will start this way, so it isn't as good as a system service. But it is a lot simpler.

An alternate way is the Windows process scheduler. You can schedule things to start when the user logs in, among many other options. This is simple enough to do if you are familiar with the Process scheduler interface, and a royal pain otherwise.

A third alternative is to use the command prompt and "start spamd". This will spawn off a separate shell for spamd, leaving the original command prompt usable. (Type "help start" at a command prompt to see all the possible options.)

All of these methods allow passing parameters to spamd, and setting the home directory for spamd.
Comment 50 RvdH 2022-09-16 20:16:35 UTC
(In reply to RvdH from comment #48)
> Mmmmm, OK
> Although executables are preferred, especially for spamd.exe to be able to
> make it run like a service using something like nssm, https://nssm.cc/usage
> 
> How did the people at JAM Software create those executables? They supply
> executables for spamd.exe, spamc.exe, spamassassin.exe, sa-learn.exe and
> sa-update.exe...or are these just executable launchers/wrappers for the perl
> files? (I think so, otherwise my manual updating to 4.0.0 should not had
> worked)
> 
> FYI, Your build instructions worked fine, using gmake

Replying to myself :)

spamd.exe, spamassassin.exe, sa-learn.exe and sa-update.exe are just wrappers/launchers, all are exactly 31KB big.

If i look inside those executables, i see references to DynaLoader::boot_DynaLoader.Win32CORE and x86_64-posix-seh, Built by strawberryperl.com project) 8.3.0.... rings any bell?
Comment 51 Sidney Markowitz 2022-09-17 01:18:25 UTC
(In reply to Loren Wilton from comment #49)
> All of these methods allow passing parameters to spamd, and setting the home
> directory for spamd.

I'll include all these suggestions in the wiki page I'll eventually edit, and leave it up to people who know what they are doing on Windows to set up their machines to their liking, or perhaps to edit the wiki with more details.
Comment 52 RvdH 2022-09-17 19:23:56 UTC
(In reply to Henrik Krohns from comment #41)
> (In reply to RvdH from comment #40)
> > For global_state_dir that is :-)
> 
> Yes portable_getpwuid should not return home for all users.
> 
> There is no ALLUSERSAPPDATA set on my Windows.
> 
> I do have ALLUSERSPROFILE=C:\ProgramData, maybe use that inside
> set_global_state_dir? Should I'm not sure what benefits this would bring
> over just using LOCAL_STATE_DIR.

Henrik are going to make a separate bug concerning the global_state_dir on Windows?
Comment 53 Henrik Krohns 2022-09-18 12:01:08 UTC
(In reply to RvdH from comment #52)
> Henrik are going to make a separate bug concerning the global_state_dir on
> Windows?

Bug #8050
Comment 54 Sidney Markowitz 2022-09-18 23:42:35 UTC
All actual issues in this bug have been split into separate ones, so I'm closing this one as "MOVED". I'll be updating the wiki pages regarding SpamAssassin on Windows with information from the comments here, but that doesn't require an open bug.
Comment 55 RvdH 2022-09-19 11:12:59 UTC
Can i still ask questions when possible issues with 4.0.0-rc2 arise on Windows?

When running with --debug  is see a line, like:
Mon Sep 19 11:55:18 2022 [4276] dbg: eval: failed to locate the triplets.txt file


Mon Sep 19 11:55:18 2022 [4276] dbg: plugin: Mail::SpamAssassin::Plugin::Check=HASH(0x3abe6e8) implements 'compile_now_start', priority 0
Mon Sep 19 11:55:18 2022 [4276] dbg: plugin: Mail::SpamAssassin::Plugin::HeaderEval=HASH(0x4af1e48) implements 'compile_now_start', priority 0
Mon Sep 19 11:55:18 2022 [4276] dbg: eval: failed to locate the triplets.txt file
Mon Sep 19 11:55:18 2022 [4276] dbg: config: time limit 300.0 s


What is this triplets.txt file? It is not included anywhere....
Comment 56 Henrik Krohns 2022-09-19 11:44:50 UTC
(In reply to RvdH from comment #55)
> Can i still ask questions when possible issues with 4.0.0-rc2 arise on
> Windows?
> 
> When running with --debug  is see a line, like:
> Mon Sep 19 11:55:18 2022 [4276] dbg: eval: failed to locate the triplets.txt
> file
> 
> 
> Mon Sep 19 11:55:18 2022 [4276] dbg: plugin:
> Mail::SpamAssassin::Plugin::Check=HASH(0x3abe6e8) implements
> 'compile_now_start', priority 0
> Mon Sep 19 11:55:18 2022 [4276] dbg: plugin:
> Mail::SpamAssassin::Plugin::HeaderEval=HASH(0x4af1e48) implements
> 'compile_now_start', priority 0
> Mon Sep 19 11:55:18 2022 [4276] dbg: eval: failed to locate the triplets.txt
> file
> Mon Sep 19 11:55:18 2022 [4276] dbg: config: time limit 300.0 s
> 
> 
> What is this triplets.txt file? It is not included anywhere....

Bug 8051
Comment 57 RvdH 2022-09-23 12:17:31 UTC
No crash but something i noticed as soon as i turned off --debug logging

warn: plugin: eval failed: __alarm__ignore__(532/::PerMsgStatus::check/2063)


Fri Sep 23 13:29:23 2022 [-4728] info: spamd: connection from mail.mydomain.nl [127.0.0.1]:52315 to port 783, fd 6
Fri Sep 23 13:29:23 2022 [-4728] info: spamd: processing message <NM621B8F142047F72B4ecg_mkt_prod6@email.marktplaats.nl> for (unknown):0
Fri Sep 23 13:39:25 2022 [-4728] warn: plugin: eval failed: __alarm__ignore__(532/::PerMsgStatus::check/2063)
Fri Sep 23 13:39:25 2022 [-4728] info: check: exceeded time limit in pms check
Fri Sep 23 13:39:25 2022 [-4728] info: spamd: clean message (0.1/4.0) for (unknown):0 in 602.6 seconds, 40618 bytes.
Fri Sep 23 13:39:25 2022 [-4728] info: spamd: result: .  0 - DKIM_INVALID,DKIM_SIGNED,KAM_DMARC_STATUS,SPF_HELO_NONE,URIBL_AMI_WHITE scantime=602.6,size=40618,user=(unknown),uid=0,required_score=4.0,rhost=mail.mydomain.nl,raddr=127.0.0.1,rport=52315,mid=<NM621B8F142047F72B4ecg_mkt_prod6@email.marktplaats.nl>,autolearn=unavailable
Fri Sep 23 13:39:25 2022 [3924] info: prefork: child states: II
Fri Sep 23 13:43:56 2022 [-4728] info: spamd: connection from mail.mydomain.nl [127.0.0.1]:52366 to port 783, fd 6
Fri Sep 23 13:43:56 2022 [-4728] info: spamd: processing message <c14a11f1789229bfcbab72348a94ba8b@2.teaburnr.org> for (unknown):0
Fri Sep 23 13:48:59 2022 [-4728] info: check: exceeded time limit, skipping further tests
Fri Sep 23 13:48:59 2022 [-4728] warn: plugin: eval failed: __alarm__ignore__(571/::PerMsgStatus::check/2063)
Fri Sep 23 13:48:59 2022 [-4728] info: spamd: identified spam (15.9/4.0) for (unknown):0 in 302.4 seconds, 10864 bytes.
Fri Sep 23 13:48:59 2022 [-4728] info: spamd: result: Y 15 - DKIM_ADSP_NXDOMAIN,KAM_DMARC_STATUS,RCVD_IN_AMI_BLACK,RCVD_IN_HOSTKARMA_BL,RCVD_IN_PSBL,RCVD_IN_SPAMRATS_SPAM,RCVD_IN_VALIDITY_RPBL,SPF_HELO_NONE,TIME_LIMIT_EXCEEDED,URIBL_AMI_DBLACK,URIBL_DBL_SPAM scantime=302.4,size=10864,user=(unknown),uid=0,required_score=4.0,rhost=mail.mydomain.nl,raddr=127.0.0.1,rport=52366,mid=<c14a11f1789229bfcbab72348a94ba8b@2.teaburnr.org>,autolearn=unavailable
Comment 58 Bill Cole 2022-09-26 16:17:47 UTC
(In reply to RvdH from comment #57)
> No crash but something i noticed as soon as i turned off --debug logging
> 
> warn: plugin: eval failed: __alarm__ignore__(532/::PerMsgStatus::check/2063)

Entirely unrelated, apparently some sort of hang when scanning, most likely a local config error. Take it to the SA Users mailing list for help.
Comment 59 RvdH 2022-09-26 19:30:34 UTC
(In reply to Bill Cole from comment #58)
> (In reply to RvdH from comment #57)
> > No crash but something i noticed as soon as i turned off --debug logging
> > 
> > warn: plugin: eval failed: __alarm__ignore__(532/::PerMsgStatus::check/2063)
> 
> Entirely unrelated, apparently some sort of hang when scanning, most likely
> a local config error. Take it to the SA Users mailing list for help.

Sorry yeah your absolutely right forgot to reply here, it turned out being something with this VM resuming from sleep and is unrelated to SA