The MASM Forum

General => The Workshop => Topic started by: MtheK on August 08, 2015, 06:53:24 AM

Title: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 08, 2015, 06:53:24 AM
WARNING: this is rather long-winded...

  It appears that the "force-killer" has expanded and now screws over
programs during normal running (ie: not just during shutdown):

http://masm32.com/board/index.php?topic=2546.0

  What is happening is that I am getting an RC=0 from SOME of my MASM
console programs. This drove me CRAZY!! Why would some fail and some
work? Specifically, if I pass, say, an RC=100 back to the OS (in my
case, program CHECKSHU), the .BAT sees %errorlevel% as a 0 (proven
w/ECHOs) instead of what I passed. BUT, merely REMOVING 'user32.dll'
from my .exe (in my case, cmt'ing GetSystemMetrics as I did B 4), and
VOILA! My return code is now being passed correctly!

  As no one has ever explained what the H*$& does this during
shutdown, I can only assume that it's been taken further, for
whatever reason, in Win10 (maybe Win8?).

  Unfortunately, it's not just 'user32.dll'. Back then, I found a few
WINAPI commands that are affected, but, perhaps, there are MANY more.
My REGTODAY and SLEEP does not have 'user32.dll' yet are still
getting an RC=0, while DSNTODAY,etc work properly, so there are
probably more WINAPI commands that are causing this. 
BEEP also fails, but that's 1 of the 4 I found B 4 w/'user32.dll'.

  My "fix#1" is to assume the middle-man role, a la what I did
conceptually in the mainframe a long time ago in a galaxy far far
away; B 4 the screwed-over program ends, it writes EAX, which has the
RC, to a ".txt" file, re-loads EAX, then ends.  The next statement in
the .BAT checks for an RC=0 and if found, I assume this is Win10 and
it runs my new program, UNITVIO, which merely reads the file and
loads EAX from it (or RC=2,etc from this program), then ends.
Without this force-killer reference ('user32.dll'), the .BAT now sees
the TRUE RC that my original program passed.

  So, the key is to ensure 'user32,dll' does not statically or
dynamically (my TESTFK now gets this same S$^@) reference 'user32.dll'.
The rest of the .BAT then runs as expected w/the TRUE RC that my
program passed to the OS and, a la Win7, all is well.

  All my .BATs re-act the same way in that, for me, an RC=0 IS AN
ERROR! I do this because I have gotton RC=0 when the msg

'The process cannot access the file because it is being used by another process.'

occurs and the RC is a 0 even tho it failed! So I always make sure my
programs NEVER pass a 0. If I have to, I "convert" my RC to a 0 in
the .BAT if others are expecting a 0.

  BTW, lest you think you are safe since you don't use .BATs, think
again! For 'INVOKE CreateProcess' and 'INVOKE GetExitCodeProcess',
the latter also returns 0 !!!! So, "fix#2"; the same concept for this
too; all my callees have to save the RC to a file so the parent can
get it.

  I mention this so others don't have to spend DAYS AND DAYS AND DAYS
trying to figure out what they are doing "wrong" in their programs!!!

  Avoid Win10 if this is an issue for you until/unless it is fixed,
or come up with your own DIY to "fix" it as I did. The mainframe
would have been so easy just via a JCL DD UNIT=VIO...oh well.

  Perhaps someone could write a quickie MASM 32bit console program
to set EAX to other than 0 (a la mainframes' IEFBR14), then RET
and/or 'INVOKE ExitThread' and/or 'INVOKE ExitProcess', thru a
simple .BAT which basically just does:

BEEP.exe
set BEEPrc=%errorlevel%
echo  %~n0 %date% %time% 1=%errorlevel%,%BEEPrc% >>BEEPX.txt

(add flavor as desired)...

then add 'INVOKE GetSystemMetrics' in a dummy routine (don't run
it, just have it imbedded, so the .exe gets 'user32.dll'),
then rinse and repeat. Does ERRORLEVEL then become a 0, not what
you set? In a nutshell, that's what I'm getting...perhaps a
doubly-linked list gone awry...        :)
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: sinsi on August 08, 2015, 10:31:14 AM
How are you passing the return code from your exe, and how are you testing errorlevel in the bat?
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 08, 2015, 11:24:58 AM
  As shown above for BEEP:
       MOV   EAX,nnn
       RET
  As shown above in SET for the .bat
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 08, 2015, 11:43:28 AM
  From a previous PUSH WORD ML problem, a handful of my programs save ESP
at startup and check it B 4 the RET. Tho BEEP doesn't have it, I added it to test:

        .CODE

;*   This is where DOS gives us control.
mainCRTStartup:

         MOV   ESPSAVE,ESP

and at the end:

.if esp == ESPSAVE
;
.else
         INT   3
.endif

  It does not crash. If I remove the .else, then it crashes w/this:

BEEP Fri 08/07/2015 19:35:13.58 error -2147483645; 80000003h ANY(!!!) INT3 CAUSES THIS???!!!

This shows that ESP is the same as when I came in, so I'm not branching
to some unknown code.
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 08, 2015, 11:58:50 AM
  It crashed where I expected it to:

FAULTING_IP:
BEEP!mainCRTStartup+730 [BEEP.ASM @ 286]
00401730 cc              int     3

            .if esp == ESPSAVE
00000728  3B 25 00000A2C R *       cmp    esp, ESPSAVE
0000072E  75 01      *       jne    @C0067
00000730  CC                  INT   3
            .endif

and my EAX is correct:

0:000> .frame /r f
0f 0012ff94 77b8b429 BEEP!mainCRTStartup+0x730 [BEEP.ASM @ 286]
eax=00000064 ebx=7ffd7000 ecx=a6ec61ca edx=77b76344 esi=00000000 edi=00000000
eip=00401730 esp=0012ff8c ebp=0012ff94 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
BEEP!mainCRTStartup+0x730:
00401730 cc              int     3

in my case, rc=100 which, for me, means all is OK.

Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: hutch-- on August 08, 2015, 12:51:00 PM
Why not try and do it the right way with ExitProcess() ?
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 15, 2015, 08:29:58 AM
  ExitProcess is un-acceptable, hardly "right", and most certainly
when SetConsoleCtrlHandler is necessary. I can't have my main, or
ANY, thread taking out ANY of my other threads, and ESPECIALLY my
abend thread, as that is stable, controls cleanup, and keeps the
force-killer at bay for up to 5 (WTK) seconds during shutdown,etc.

  I've used RET since MASM611 and have NEVER had a problem w/it until
now. Mainframe programmers are encouraged to use something similar in
"good" programs; this technique has worked for almost a half-century,
and I will NOT deviate from a proven method.

  Let's agree to dis-agree.

  Anyway, this is what I found in testing:


. ExitProcess does work, but, as I said, is NOT an option


. ExitThread also gets a fake rc=0 (dwExitCode), seemingly
contradicting the WINAPI doc and ExitProcess (assuming I'm the last
thread):

dwExitCode [in]
The exit code for the thread.
If the thread is the last thread in the process when this function is
called, the thread's process is also terminated.

except this addition:
Thread Exit Convention
Note that by convention, threads that exit normally return an exit
code of 0. Craig Anderson 6/7/2007

  Not quite sure what that means since, when I exit gracefully in
Win7 (via RET; also tested ExitThread which works (see below)), my
RC is passed correctly. It's the same in Win10, but ONLY when NO
"user32.dll" is in it ?!

  Furthermore, nowhere in this doc does it say that the return code
will NOT be honored, and even FAKED(!), under Win10, when the
executable contains "user32.dll", when returning to the OS.


. RET gets a fake rc=0 (which started all this)


  And now the last 2 require my own DIY fix. When abending, the
parent(s) USUALLY get killed within THOUSANDths of a second anyway
and so USUALLY get no chance to deal w/it; only the program can
(except Ctl-C/N; good for testing all this).

---

  All this proves that, on Win10 (at least above Win7), if a program
has a "user32.dll" in its' .exe, static or NOW dynamic, when exiting
"gracefully", its' return code is NOT HONORED and, worse, FAKED with
an rc=0!

  I now print the GetVersionEx results in all my 4 "failing" programs
to show that, whenever an rc=0 occurs, this will indicate it can't be
trusted due to Win10! Even if it stops filling in 6.2, even if the RC
is not 0, my default will be 0.0 which would then indicate that
GetVersionEx failed to work (maybe Win11?).

  Interesting that GetVersionEx may now be "obsolete", in spite of
the many people who complained about losing it. I did test that it
does return 6.2, but w/nothing to counter with (I was hoping to use
that to know when to replace the RET w/ExitThread), all I can say is
the OS is not "good".  I had to laugh when they suggested to test for
the feature itself; how exactly do you test if RET/ExitThread to the
OS works like it's supposed to?

  On the plus side, my code can remain OS-independent as my DIY fix
now is forced to control the return code to the OS properly. No
stupid WINAPI cmd required to exit to the OS, either when called as a
sub-routine or when running stand-alone.

  Finally, in WinDbg, when I reach my RET, doing 't 999999' ends up
w/this:


eax=00000064 ebx=00403a9f ecx=54d4fad5 edx=77526344 esi=00000000 edi=00000000
eip=00401a59 esp=0012ff8c ebp=0012ff94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
BEEP!mainCRTStartup+0xa59:
00401a59 c3              ret
0:000>
eax=00000064 ebx=00403a9f ecx=54d4fad5 edx=77526344 esi=00000000 edi=00000000
eip=77251114 esp=0012ff90 ebp=0012ff94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
kernel32!BaseThreadInitThunk+0xe:
77251114 50              push    eax
...
eax=00000172 ebx=00000064 ecx=77543afc edx=7ffe0300 esi=775b8380 edi=775b8340
eip=77525b7a esp=0012ff58 ebp=0012ff70 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwTerminateProcess+0xa:
77525b7a ff12            call    dword ptr [edx]      ds:0023:7ffe0300={ntdll!KiFastSystemCall (77526340)}
eax=00000172 ebx=00000064 ecx=77543afc edx=7ffe0300 esi=775b8380 edi=775b8340
eip=77526340 esp=0012ff54 ebp=0012ff70 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall:
77526340 8bd4            mov     edx,esp
eax=00000172 ebx=00000064 ecx=77543afc edx=0012ff54 esi=775b8380 edi=775b8340
eip=77526342 esp=0012ff54 ebp=0012ff70 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall+0x2:
77526342 0f34            sysenter
eax=00000172 ebx=00000064 ecx=77543afc edx=0012ff54 esi=775b8380 edi=775b8340
eip=77526344 esp=0012ff54 ebp=0012ff70 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCallRet:
77526344 c3              ret
0:000> t
       ^ No runnable debuggees error in 't'


and ends up the same when I replace my RET w/an ExitThread, tho I'm
not quite sure how my EAX is saved, or where, tho, using 'j' on 't',
I see that it's also POP'd to EBX from the stack (12FED8) somewhere
B 4 the end of this (ntdll!_SEH_epilog4+0xe):


eax=00000064 ebx=00403a9f ecx=51ce7d69 edx=77526344 esi=00000000 edi=00000000
eip=00401a59 esp=0012ff8c ebp=0012ff94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
BEEP!mainCRTStartup+0xa59:
00401a59 50              push    eax
0:000> t
eax=00000064 ebx=00403a9f ecx=51ce7d69 edx=77526344 esi=00000000 edi=00000000
eip=00401a80 esp=0012ff84 ebp=0012ff94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
BEEP!ExitThread:
00401a80 ff251c204000    jmp     dword ptr [BEEP!_imp__ExitThread (0040201c)] ds:0023:0040201c={ntdll!RtlExitUserThread (77510689)}
...
eax=00000172 ebx=00000064 ecx=77543afc edx=7ffe0300 esi=775b8380 edi=775b8340
eip=77525b7a esp=0012ff54 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwTerminateProcess+0xa:
77525b7a ff12            call    dword ptr [edx]      ds:0023:7ffe0300={ntdll!KiFastSystemCall (77526340)}
eax=00000172 ebx=00000064 ecx=77543afc edx=7ffe0300 esi=775b8380 edi=775b8340
eip=77526340 esp=0012ff50 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall:
77526340 8bd4            mov     edx,esp
eax=00000172 ebx=00000064 ecx=77543afc edx=0012ff50 esi=775b8380 edi=775b8340
eip=77526342 esp=0012ff50 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall+0x2:
77526342 0f34            sysenter
eax=00000172 ebx=00000064 ecx=77543afc edx=0012ff50 esi=775b8380 edi=775b8340
eip=77526344 esp=0012ff50 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCallRet:
77526344 c3              ret
0:000> t
       ^ No runnable debuggees error in 't'


and, tho I can't use it, it also ends up the same when I replace
my RET w/an ExitProcess:


eax=00000064 ebx=00403a9f ecx=b9bcf230 edx=77b36344 esi=00000000 edi=00000000
eip=00401a59 esp=0012ff8c ebp=0012ff94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
BEEP!mainCRTStartup+0xa59:
00401a59 50              push    eax
0:000> t
eax=00000064 ebx=00403a9f ecx=b9bcf230 edx=77b36344 esi=00000000 edi=00000000
eip=00401a80 esp=0012ff84 ebp=0012ff94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
BEEP!ExitProcess:
00401a80 ff251c204000    jmp     dword ptr [BEEP!_imp__ExitProcess (0040201c)] ds:0023:0040201c=765d2a6f
eax=00000064 ebx=00403a9f ecx=b9bcf230 edx=77b36344 esi=00000000 edi=00000000
eip=765d2a6f esp=0012ff84 ebp=0012ff94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
kernel32!FlsFree+0xb:
765d2a6f 8bc0            mov     eax,eax
...
eax=00000172 ebx=00000064 ecx=77b53afc edx=7ffe0300 esi=77bc8380 edi=77bc8340
eip=77b35b7a esp=0012ff54 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwTerminateProcess+0xa:
77b35b7a ff12            call    dword ptr [edx]      ds:0023:7ffe0300={ntdll!KiFastSystemCall (77b36340)}
eax=00000172 ebx=00000064 ecx=77b53afc edx=7ffe0300 esi=77bc8380 edi=77bc8340
eip=77b36340 esp=0012ff50 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall:
77b36340 8bd4            mov     edx,esp
eax=00000172 ebx=00000064 ecx=77b53afc edx=0012ff50 esi=77bc8380 edi=77bc8340
eip=77b36342 esp=0012ff50 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall+0x2:
77b36342 0f34            sysenter
eax=00000172 ebx=00000064 ecx=77b53afc edx=0012ff50 esi=77bc8380 edi=77bc8340
eip=77b36344 esp=0012ff50 ebp=0012ff6c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCallRet:
77b36344 c3              ret
0:000> t
       ^ No runnable debuggees error in 't'


I think EBX s/b my passed return code (100). The bottom line is
that all 3 produce the same result in Win7 32bit, which is what
I think it should do. I wonder what Win10 will show? I suspect
it might be a 0 for the 1st 2?

  Perhaps someone is willing to test this w/their own sample
program w/"user32.dll", assuming, of course, that you have a
debugger on it that works...

  Cheers.


Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: sinsi on August 15, 2015, 08:50:53 AM
ExitProcess expects the return code to be on the stack, not in EAX.

;invoke ExitProcess,eax
    push eax
    call ExitProcess
;[ESP+0]=return address
;[ESP+4]=return code


By using RET, your return address could be anything

    mov eax,code
    ret   ;should really be RET 16 for winmain

With ExitProcess you will be exiting to a known spot, with RET it's not guaranteed - maybe that's why the return code is OK sometimes, just by a fluke.
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: rrr314159 on August 15, 2015, 09:00:14 AM
Quote from: MtheK... this technique has worked for almost a half-century, and I will NOT deviate from a proven method.

- Spoken like a true Conservative! ... but as a general rule the statement is very suspect. Slide rules worked great for more than 50 years; why are you using a computer? Admittedly, cars can be trouble, but you must get tired of cleaning up after the horse .. ? Isn't your wife sick of washing clothes in the stream by pounding them with rocks (which worked for 50,000 years, not just 50) - when all her friends use washing machines? etc, insert your own joke here ... :biggrin:
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: qWord on August 15, 2015, 09:22:57 AM
might be interesting: http://blogs.msdn.com/b/oldnewthing/archive/2011/05/25/10168020.aspx.
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: jj2007 on August 15, 2015, 05:30:47 PM
Quote from: qWord on August 15, 2015, 09:22:57 AM
might be interesting: http://blogs.msdn.com/b/oldnewthing/archive/2011/05/25/10168020.aspx.

Nice. C coders discover RawEntryPoint aka start:  :biggrin:
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 16, 2015, 03:26:40 AM
  So if I've just been "lucky" this whole time w/RET,
shouldn't ExitThread work? The doc seems to indicate
it should...
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 16, 2015, 03:55:43 AM
  Also, the 1st thing that is done by my RET is:

kernel32!BaseThreadInitThunk+0xe:
77251114 50              push    eax

so this shows I'm returning correctly, and EAX goes
on the stack. Besides, I usually ensure that ESP is
the same as when I entered...
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 17, 2015, 06:22:01 AM
  Interesting. I tried 'RET 16' and it seems to work in Win7.
What's the purpose of discarding 4 DWORDs from the stack?
Is that in that C++ link? I don't do this when doing my own CALLs?

  From the stack, it seems to get rid of this:
ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])

  A 't 999999' ends up the same way, w/EBX containing the RC.

  So perhaps you're saying that this double underscore thing
is somehow interfering w/this on Win10, but only w/"user32.dll"?
I can try a 'RET 16' on Win10 in BEEP and see if I get the rc=0...
thankx sinsi...
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 22, 2015, 01:28:33 AM
  Unfortunately, 'RET 16' made no difference; I still get the fake rc=0.

  I also can't find any commonality in the WINAPI cmds of the 3.5 that
"failed" (the same program "failed" 1 time, but worked other times?!)
and the 9.5 that didn't. First, the cmd had to be in all that "failed",
assuming that it caused the failure (if more than 1, this won't find it).
Second, if that cmd was in any of the others that worked, then it can't(?)
be that cmd causing the "failure". I used the "failed" BEEP as a base.

Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: adeyblue on August 22, 2015, 02:48:54 AM
If ExitProcess isn't used, the exit code of the process is the exit code of the last thread to exit. If you're not creating a thread yourself, then probably one of the functions you call is now creating one or starting the threadpool in Win10 when it didn't in previous versions.

That you sometimes get the return value you expect and sometimes don't suggests a race condition between which thread exits last.
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: qWord on August 22, 2015, 03:59:52 AM
Quote from: adeyblue on August 22, 2015, 02:48:54 AM
If ExitProcess isn't used, the exit code of the process is the exit code of the last thread to exit.
any reference for that?
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: Donkey on August 22, 2015, 04:37:17 AM
Interesting problem. Since you're using batch commands the break in the code was most likely at Vista when the way a bat file executes code was changed. I seem to remember that Microsoft was beginning to have executables called from a batch file run in a separate cmd window. Could be that the exit code you're getting is linked to that change. It's been a while since I've even considered using batch files, sloppy things at best, unreliable at worst so I can't be sure, just seem to remember Raymond Chen mentioning it in his blog once long ago.
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 24, 2015, 09:11:02 AM
  Hhhmmm, adeyblue may be on to something.  I think I found the
problem. Of a total of 28 programs, 7 "failed". I noticed that, of
those latter, there was always a long delay.  For BEEP, after it
played the sound, it took about 30sec B 4 the DOS Prompt appeared; in
Win7, it's immediately after. For SLEEP, I noticed that a requested
60sec wait was taking about 90sec.  So, I snap-dumped them both after
waiting a few seconds, and found they were waiting on this:

ntdll!ZwWaitForWorkViaWorkerFactory+0xa

I have no idea what this is, nor what to do about it. None of my
thread(s) were there, tho, when I snapped a normal DSNTODAY run,
my stack entry was not there either:


00000000`0009e5f8 00000000`57e24880 : 000033ee`6519aa07 00000000`0019ea88 000033ee`6519aa17 00000000`00000000 : ntdll!ZwQueryDirectoryFile+0xa
I think this is my FindNextFile.


yet I was able to display my fields which showed I was probably a
third into the run. However, if my own code was running, it shows
up!? To test that, I just JMP'd to the location of that JMP to put it
in a loop; in that case, it showed up? This was B 4 any call to any
WINAPI cmd:


0019ff94 7786a064 7ffde000 273dfc08 00000000 DSNTODAY!mainCRTStartup [DSNTODAY.ASM @ 1695]
0:000:x86> .frame /r 0
eax=0b9a197b ebx=7ffde000 ecx=00401000 edx=00000061 esi=00401000 edi=00401000
                                               / <== there it is
eip=00401000 esp=0019ff84 ebp=0019ff94 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
DSNTODAY!mainCRTStartup:
00401000 90              nop

FAULTING_SOURCE_CODE:
  1692: mainCRTStartup:
  1693: ;       .STARTUP                   ; prime regs properly
  1694:
> 1695:          NOP                       ; x'90'
  1696:
  1697:
  1698:          MOV   EDX,97
  1699:          JMP   mainCRTStartup


  Anyway, from BEEP:


0:000> !uniqstack -v
Processing 3 threads, please wait

.  0  Id: 1894.5fc Suspend: 0 Teb: 00000000`7ffd8000 Unfrozen
      Start: ntdll_77310000!TppWorkerThread (00000000`773445b0)
      Priority: 0  Priority class: 32  Affinity: ff
Child-SP          RetAddr           : Args to Child                                                           : Call Site
00000000`002bea78 00000000`7474833e : 00000000`003ef70c 00000000`00000000 00000000`003efbf4 00000000`00000000 : ntdll!ZwWaitForWorkViaWorkerFactory+0xa
00000000`002bea80 00000000`74747d35 : 00000000`00000000 00000000`7ffd8000 00000000`74748220 00000000`7ffda000 : wow64!whNtWaitForWorkViaWorkerFactory+0x11e
00000000`002beb10 00000000`74731927 : 00000023`77378cac 00000000`00000023 00000000`00574f10 00000000`003efff0 : wow64!Wow64SystemServiceEx+0x175
00000000`002bf3d0 00000000`7474df82 : 00000000`005746a8 00000000`00000000 00000000`00000000 00000000`7ffdf000 : wow64cpu!TurboDispatchJumpAddressEnd+0xb
00000000`002bf480 00000000`7474dea7 : 00000000`00000000 00000000`002bf4d0 00000000`00000000 00000000`002bf820 : wow64!RunCpuSimulation+0x22
00000000`002bf4b0 00007ff9`778efce3 : 00000000`00000000 00000000`7474dd30 00000000`00000000 00000000`00000000 : wow64!Wow64LdrpInitialize+0x177
00000000`002bf750 00007ff9`778efb7e : 00000000`002bf820 00000000`00000000 00000000`7ffdf000 00000000`00000000 : ntdll!_LdrpInitialize+0x10f
00000000`002bf7d0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

Total threads: 3
Duplicate callstacks: 2 (windbg thread #s follow):
1, 2


so this apparently controls the return code since it's (probably) the
last one. I assume some timeout expired and it decided to over-ride,
not save, etc my return code and then supplied the fake rc=0.

---

  On a side note, maybe related, my TESTFK failed to get this command
to work:

         MOV   WAITKILL,77
         INVOKE SystemParametersInfo,
               SPI_GETWAITTOKILLTIMEOUT,     ; x'007A'
               0,
               OFFSET WAITKILL,
               0
         MOV   WTFEAXRC,EAX

which I do dynamically via LoadLibrary/GetProcAddress in a separate
thread since, otherwise, it causes the force-killer to not honor my
allowed shutdown time ("user32.dll") in Win7.  I forced a crash
(INT3) after this call if WAITKILL stayed a 77, and the 'Return
Value' (EAX) is this:

0040c738 02 00 00 c0  = x'C0000002'.

I had to save it in my own DWORD since the stupid WER dump doesn't
seem to show my program on the separate threads' stack (as above):


0:001> !uniqstack -v
Processing 5 threads, please wait

.  0  Id: 14e0.1ce8 Suspend: 0 Teb: 7ffdd000 Unfrozen
      Start: TESTFK!mainCRTStartup (00401000)
00000000                               .CODE
      Priority: 0  Priority class: 32  Affinity: ff
ChildEBP RetAddr  Args to Child
0019ff00 754a13c8 00000000 0019ff44 7b901358 ntdll!ZwDelayExecution+0xc (FPO: [2,0,0])
0019ff68 754a131f 0000000f 00000000 0019ff94 KERNELBASE!SleepEx+0x98 (FPO: [SEH])
0019ff78 00402b45 0000000f 76133744 7ffde000 KERNELBASE!Sleep+0xf (FPO: [Non-Fpo])
0019ff94 7786a064 7ffde000 10d154d3 00000000 TESTFK!mainCRTStartup+0x1b45 [TESTFK.ASM @ 1371]
00001B40  E8 00000000 E   *        call   Sleep
00001B45  EB EA                         JMP   WAITFORIT

0019ffdc 7786a02f ffffffff 7788d7b7 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [Non-Fpo])
0019ffec 00000000 00401000 7ffde000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

.  1  Id: 14e0.d2c Suspend: 0 Teb: 7ffda000 Unfrozen
      Start: TESTFK!mainCRTStartup+0x7519 (00408519)
00007519 LOADAPIX:
      Priority: 0  Priority class: 32  Affinity: ff
ChildEBP RetAddr  Args to Child
0070f358 00000000 77878e8c 778307f8 ffffffff ntdll!ZwGetContextThread+0xc (FPO: [2,0,0])
### WHERE IS MY ENTRY???


### funny that this next is almost what's in BEEP and SLEEP (32bit only?) ###
.  2  Id: 14e0.dc0 Suspend: 0 Teb: 7ffd7000 Unfrozen
      Start: ntdll!TppWorkerThread (778445b0)
      Priority: 0  Priority class: 32  Affinity: ff
ChildEBP RetAddr  Args to Child
0084fdc8 77844836 0000008c 001cf6e0 00000010 ntdll!ZwWaitForWorkViaWorkerFactory+0xc (FPO: [5,0,0])
0084ff80 76133744 001c7c30 76133720 da04c2a6 ntdll!TppWorkerThread+0x286 (FPO: [Non-Fpo])
0084ff94 7786a064 001c7c30 104c54d3 00000000 kernel32!BaseThreadInitThunk+0x24 (FPO: [Non-Fpo])
0084ffdc 7786a02f ffffffff 7788d7b7 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [Non-Fpo])
0084ffec 00000000 778445b0 001c7c30 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

Total threads: 5
Duplicate callstacks: 2 (windbg thread #s follow):
3, 4


yet '!analyze -v' pinpoints my INT3 and knows my stack entry,
but no regs, so I'm obviously OS-aware somehow:


LAST_CONTROL_TRANSFER:  from 76133744 to 00409141

STACK_TEXT:
0070ff80 76133744 0040b000 76133720 daf0c2a6 TESTFK!mainCRTStartup+0x8141 [TESTFK.ASM @ 2695]
0070ff94 7786a064 0040b000 10b854d3 00000000 kernel32!BaseThreadInitThunk+0x24
0070ffdc 7786a02f ffffffff 7788d7b7 00000000 ntdll!__RtlUserThreadStart+0x2f
0070ffec 00000000 00408519 0040b000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND:  ~1s; .ecxr ; kb

FOLLOWUP_IP:
TESTFK!mainCRTStartup+8141 [TESTFK.ASM @ 2695]
00409141 cc              int     3

FAULTING_SOURCE_CODE:
ABENDRC EQU 3221225474   ; DWORD won't work??? C0000002h
  2691: ;  .if WAITKILL == 77           ; if field not populated...
  2692:          MOV   EAX,ABENDRC
  2693:   .if eax == WTFEAXRC           ;* THIS VIOLATES DOC!!!?? Only rc=0 says error !!!??
  2694: ;*
> 2695:          INT  3
  2696:   .endif

APIADDR4A
0040c43c 60 08 26 75   =   x'75260860' = EBX
WTFEAXRC
0040c738 02 00 00 c0       (EAX immediately after 'call EBX')
WAITKILL
0040c720 4d 00 00 00       (same as what I set it to B 4 call)
WAITKILLRC
0040c72c 00 00 00 00       (from GetLastError anyway)


and so I can't do '.frame /r' to see my regs as I can in Win7!?
Trying .frame "raw" but nothing yet...

This seemingly contradicts the WINAPI doc that says an error gets
eax=0 and you must do GetLastError (I did so anyway, but that was
a 0).  Since EAX is not a 0 (I get a '1' in Win7), my WAITKILL
DWORD should contain the value, but it doesn't (it has 5000 in Win7).
The 2 other requests also failed to update my fields:

SPI_GETWAITTOKILLSERVICETIMEOUT
SPI_GETHUNGAPPTIMEOUT

but I didn't check EAX on those; it's probably the same.

---

Strange...


Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 24, 2015, 11:50:56 AM
  This smells of a problem like when the mainframe went from 24bit to
31bit addressing. Many app programmers used the top byte for flags,
so when they loaded up all 4 bytes into a register, if that top byte
wasn't 0, it would abend w/an S0C4, which, basically, is a virtual
address w/no valid segment/page table entry, because it was trying to
address, say, x'27xxxxxx' instead of x'00xxxxxx'.

  Perhaps this x'C0000002' is an S0C4 because OS code (ie: sysenter)
isn't clearing the top half of a 64bit register.  Perhaps that's why
my TESTFK cmds fail and are being covered up. Perhaps the same for
that "factory" thread; if its' ECB (mainframe speak again: an Event
Control Block; if bit x'80' isn't a 1, the OS won't run the code)
isn't POSTed, it'll wait forever (tho, even here, some 30sec timeout
must eventually end it and then sets the fake rc=0)...

Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 25, 2015, 04:25:08 AM
...and I'll state the obvious, in case it's not obvious;
IF the address IS valid, but NOT yours, you've just clobbered
someone else's data! That was fun back then!
That's a DATA INTEGRITY CORRUPTION!

  Since this seems to be in 'sysenter' code (Win7):


detail here:

eax=0000007a ebx=0040c710 ecx=ffffffff edx=006e0174 esi=0000007a edi=00000000
eip=76957e21 esp=0012fa10 ebp=0012ff24 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000287
USER32!RealSystemParametersInfoA+0x4f9:
76957e21 e80f700000      call    USER32!NtUserSystemParametersInfo (7695ee35)

eax=0000007a ebx=0040c710 ecx=ffffffff edx=006e0174 esi=0000007a edi=00000000
eip=7695ee35 esp=0012fa0c ebp=0012ff24 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000287
USER32!NtUserSystemParametersInfo:
7695ee35 b853120000      mov     eax,1253h

eax=00001253 ebx=0040c710 ecx=ffffffff edx=006e0174 esi=0000007a edi=00000000
eip=7695ee3a esp=0012fa0c ebp=0012ff24 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000287
USER32!NtUserSystemParametersInfo+0x5:
7695ee3a ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)

eax=00001253 ebx=0040c710 ecx=ffffffff edx=7ffe0300 esi=0000007a edi=00000000
eip=7695ee3f esp=0012fa0c ebp=0012ff24 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000287
USER32!NtUserSystemParametersInfo+0xa:
7695ee3f ff12            call    dword ptr [edx]      ds:0023:7ffe0300={ntdll!KiFastSystemCall (776d6340)}
                                             / <== OFFSET (1st 4 bytes) = 7ffe0300 40 63 6d 77      == /

eax=00001253 ebx=0040c710 ecx=ffffffff edx=7ffe0300 esi=0000007a edi=00000000
eip=776d6340 esp=0012fa08 ebp=0012ff24 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000287
ntdll!KiFastSystemCall:
776d6340 8bd4            mov     edx,esp

##### WAITKILL WAS CHG'D HERE:

eax=00001253 ebx=0040c710 ecx=ffffffff edx=0012fa08 esi=0000007a edi=00000000
eip=776d6342 esp=0012fa08 ebp=0012ff24 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000287
ntdll!KiFastSystemCall+0x2:
776d6342 0f34            sysenter
                            / <== not traceable (a la SVC?)

0012f9e8 9c 00 00 00 48 fb 12 00 34 fb 12 00 24 fa 12 00 be 56 75 77 00  ....H...4...$....Vuw.
0012f9fd 00 6e 00 00 00 00 00 1a 02 00 00  41 ee 95 76 26 7e 95 76 7a 00  .n.........A..v&~.vz.
0012fa12 00 00 00 00 00 00 10 c7 40 00 00 00 00 00 00 00 00 00 00 00 00  ........@............
0012fa27 00 90 7e 95 76 38 01 6e 00 26 5f 75 77 d7 d6 b8 77 00 00 00 00  ..~.v8.n.&_uw...w....
0012fa3c 00 00 00 00 00 00 6e 00 bc 2d 6e 00 00 00 00 00 00 00 00 00 4c  ......n..-n.........L

.  0  Id: 1438.13a0 Suspend: 1 Teb: 7ffdf000 Unfrozen
      Start: TESTFK!mainCRTStartup (00401000)
      Priority: 0  Priority class: 32  Affinity: 3
ChildEBP RetAddr  Args to Child
0012fa08 76957e26 0000007a 00000000 0040c710 USER32!NtUserSystemParametersInfo+0xc (FPO: [4,0,0])
0012ff24 76957ed0 0000007a 00000000 0040c710 USER32!RealSystemParametersInfoA+0x4fe (FPO: [Non-Fpo])
0012ff6c 00408bbb 0000007a 00000000 0040c710 USER32!SystemParametersInfoA+0x57 (FPO: [Non-Fpo])
0012ff84 00402637 772e1114 7ffd8000 0012ffd4 TESTFK!mainCRTStartup+0x7bbb [TESTFK.ASM @ 2727]
0012ff94 776eb429 7ffd8000 77b8d36f 00000000 TESTFK!mainCRTStartup+0x1637 [TESTFK.ASM @ 1282]
0012ffd4 776eb3fc 00401000 7ffd8000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
0012ffec 00000000 00401000 7ffd8000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

Total threads: 1


who knows if that address is restricted to just a single process?
Perhaps OSs' own storage could be wiped out (say, MY MISSING STACK
ENTRY)? And who knows where that missing bit (the POSTed ECB) went?
Didn't the Tron guy meet a free "bit"? OK, I'm stretching, but the
possibility is NOT ZERO if this is what's happening...

Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 29, 2015, 06:50:28 AM
  Hhhmmm...it looks like hutchs' suggestion is good after all,
just w/a slight twist. I combined the best of both worlds.
Let's call it a "conditional ExitProcess"! ON CONDITION OF WIN10!

  In my ABENDXIT thread, just B 4 I decide
"to RET or not; that is the question" (also ExitThread), I count the
# of threads in my process; in Win7, it's a 1 (myself); all my other
threads have already cleaned up and RET'd by this time.  So, if the
# of threads is > 1, I do the ExitProcess over ExitThread (only ABENDXIT
uses this over RET).  Now, the 30-second hang at EOJ is gone, and my DIY
"fix" in the .BAT did NOT detect a fake rc=0, as my correct RC was
detected by the .BAT properly.

  These are my results of my tests. Basically, it shows the TOD and
the # of threads in my process; the hex stuff I didn't show here:

Win7:

2015/08/28 10:43:02.377  0000000001
2015/08/28 10:43:02.392  0000000002
2015/08/28 10:43:03.422  0000000002
...
2015/08/28 10:43:13.328  0000000002
2015/08/28 10:43:14.358  0000000002
then Ctl-C ...
2015/08/28 10:43:15.793  0000000001


Win10:

2015/08/28 12:02:31.687  0000000001
2015/08/28 12:02:31.734  0000000002
2015/08/28 12:02:32.796  0000000005
... (snap dump also taken)
2015/08/28 12:02:48.792  0000000005
2015/08/28 12:02:49.854  0000000005
then Ctl-C ...
2015/08/28 12:02:51.618  0000000004


  For each:

. the 1st record is the initial call to get this #, in my main
thread, B 4 I did any of these weird-ass whatevers that is causing
this Win10 problem.  Obviously, a 1 means I'm the only thread, so
these "factory" things aren't there yet.

. the 2nd record is when I set up and run my next thread to get
this #, that runs every second (a "heartbeat" if you will); this
is its' initial call. A 2 says my main thread exists, and this new
thread of mine exists. Again, this is B 4 the weird-ass whatevers.

. the 3rd record is when the %&^@ hits the fan, but only for Win10!
Somewhere within that heartbeat, probably, these are those "factory"
threads from using these weird-ass whatevers.  They remain until
shutdown, or 60 SECONDS (see below!).

. the last record is from my new code that implements the
"conditional ExitProcess". I have my own 1-second built-in lag from
the Ctl-C,etc (true shutdown can get 5) in this program.  For Win7,
1 means me (ABENDXIT) only. For Win10, that 4 means there are 3
"factory" threads. What I get is the start address of each thread
(ABENDXIT + "foreign"), and the ones that aren't mine are the same
(x'778445b0'); they are what the equivalent snap dump below shows.


  GET THIS!!! These "factory" threads apparently hang around for
60 seconds, then go away:


2015/08/28 11:49:03.086  0000000001
2015/08/28 11:49:03.133  0000000002
2015/08/28 11:49:04.194  0000000005
...
2015/08/28 11:50:02.488  0000000005
2015/08/28 11:50:03.550  0000000002
...
2015/08/28 11:51:02.871  0000000002
2015/08/28 11:51:04.539  0000000001


so perhaps some registry setting can turn this off ("timeout=0"?),

but if I snap it within 60 seconds after using these weird-ass
whatevers, then it matches my count:


Debug session time: Fri Aug 28 12:02:45.000 2015

0:000> !uniqstack -v
Processing 5 threads, please wait

.  0  Id: 1240.2bc0 Suspend: 0 Teb: 00000000`7ffdb000 Unfrozen
      Start: TESTFK!mainCRTStartup (00000000`00401000)
00000000         .CODE
      Priority: 0  Priority class: 32  Affinity: ff
Child-SP          RetAddr           : Args to Child                                                           : Call Site
00000000`0009efd8 00000000`57e11d3d : 00000023`77878f2c 00000000`57e20023 00000000`00000001 00000000`0019fff0 : wow64cpu!CpupSyscallStub+0x2
00000000`0009efe0 00000000`57e2df82 : 00000000`7ffde000 00000000`0009f820 00000000`00000000 00000000`00252398 : wow64cpu!Thunk2ArgNSpNSpReloadState+0xc
00000000`0009f090 00000000`57e2dea7 : 00000000`00000000 00000000`0009f0e0 00000000`00000000 00000000`0009f820 : wow64!RunCpuSimulation+0x22
00000000`0009f0c0 00007ffa`359e05d7 : 00000000`004000c0 00000000`57e2dd30 00000000`7ffdf000 00000000`00000000 : wow64!Wow64LdrpInitialize+0x177
00000000`0009f360 00007ffa`359d4047 : 00000000`00000000 00007ffa`359ddead 00000000`00000001 00000000`00000000 : ntdll!LdrpInitializeProcess+0x17c3
00000000`0009f750 00007ffa`3598fb7e : 00000000`0009f820 00000000`00000000 00000000`7ffdf000 00000000`00000000 : ntdll!_LdrpInitialize+0x44473
00000000`0009f7d0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

.  1  Id: 1240.18a4 Suspend: 0 Teb: 00000000`7ffd8000 Unfrozen
      Start: TESTFK!mainCRTStartup+0xa6b1 (00000000`0040b6b1)
0000A6B1 SHOWTCBX:
      Priority: 0  Priority class: 32  Affinity: ff
Child-SP          RetAddr           : Args to Child                                                           : Call Site
00000000`001ff3c8 00000000`57e11d3d : 00000023`77878cbc 00000000`00000023 00000000`0040e584 00000000`0084fff0 : wow64cpu!CpupSyscallStub+0x2
00000000`001ff3d0 00000000`57e2df82 : 00000000`0040e000 00000000`00000000 00000000`00000000 00000000`7ffdf000 : wow64cpu!Thunk2ArgNSpNSpReloadState+0xc
00000000`001ff480 00000000`57e2dea7 : 00000000`00000000 00000000`001ff4d0 00000000`00000000 00000000`001ff820 : wow64!RunCpuSimulation+0x22
00000000`001ff4b0 00007ffa`3598fce3 : 00000000`00000000 00000000`57e2dd30 00000000`00000000 00000000`00000000 : wow64!Wow64LdrpInitialize+0x177
00000000`001ff750 00007ffa`3598fb7e : 00000000`001ff820 00000000`00000000 00000000`7ffdf000 00000000`00000000 : ntdll!_LdrpInitialize+0x10f
00000000`001ff7d0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

.  2  Id: 1240.2150 Suspend: 0 Teb: 00000000`7fead000 Unfrozen
      Start: ntdll_77810000!TppWorkerThread (00000000`778445b0)
      Priority: 0  Priority class: 32  Affinity: ff
Child-SP          RetAddr           : Args to Child                                                           : Call Site
00000000`0035ea78 00000000`57e2833e : 0000014c`00010000 00000000`00000000 00000000`00a4fbf4 00000000`57e2438c : ntdll!ZwWaitForWorkViaWorkerFactory+0xa
00000000`0035ea80 00000000`57e27d35 : 00000000`00000000 00000000`7fead000 00000000`57e28220 00000000`7feaf000 : wow64!whNtWaitForWorkViaWorkerFactory+0x11e
00000000`0035eb10 00000000`57e11927 : 00000023`77878cac 00000000`00000023 00000000`00654ef0 00000000`00a4fff0 : wow64!Wow64SystemServiceEx+0x175
00000000`0035f3d0 00000000`57e2df82 : 00000000`00654788 00000000`00000000 00000000`00000000 00000000`7ffdf000 : wow64cpu!TurboDispatchJumpAddressEnd+0xb
00000000`0035f480 00000000`57e2dea7 : 00000000`00000000 00000000`0035f4d0 00000000`00000000 00000000`0035f820 : wow64!RunCpuSimulation+0x22
00000000`0035f4b0 00007ffa`3598fce3 : 00000000`00000000 00000000`57e2dd30 00000000`00000000 00000000`00000000 : wow64!Wow64LdrpInitialize+0x177
00000000`0035f750 00007ffa`3598fb7e : 00000000`0035f820 00000000`00000000 00000000`7ffdf000 00000000`00000000 : ntdll!_LdrpInitialize+0x10f
00000000`0035f7d0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

Total threads: 5
Duplicate callstacks: 2 (windbg thread #s follow):
3, 4


AND WORSE, these weird-ass whatevers REPLACED/LOST my own stacks:
.  0  Id: 1240.2bc0 Suspend: 0 Teb: 00000000`7ffdb000 Unfrozen
      Start: TESTFK!mainCRTStartup (00000000`00401000)
.  1  Id: 1240.18a4 Suspend: 0 Teb: 00000000`7ffd8000 Unfrozen
      Start: TESTFK!mainCRTStartup+0xa6b1 (00000000`0040b6b1)

which gives me my IPs in Win7, at least for debugging purposes???!!!
My WinDbg is still Win7, so not really sure what the threads/stacks
are. Perhaps they're buried somewhere, or interpreted differently,
which would mean the .dmps aren't portable across OS versions unless
some keyword or something could be used (mainframe usually can tell
the difference, but sometimes, it had to be told).

  I can't install anything on this Win10 machine, so my options are
limited to what I have available; perhaps others? If so, have fun.

  Also, this doesn't explain those SPI x'C0000002' failures.


Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on August 31, 2015, 08:10:25 AM
  It looks like, for simple programs (my BEEP), that have no other
threads of mine, I can just use GetVersionEx (or the lack of it;
Win11?) to decide whether I do a RET or an ExitProcess. For my
ABENDXIT thread, it waits for my other threads to finish (or timeout)
anyway, so it can do the same check; ExitThread (over RET for this
only) or ExitProcess. Since this now controls how I exit, maybe
counting threads isn't needed now (it was sloppy anyway; I don't
see a simple WINAPI cmd to get that for my process?), tho it did
help to nail down when those "factory" threads started, which may
be my 3 SPI "failed" INVOKEs.  Yet BEEP has no SPI calls.
I still don't know the commonality of a quarter of my programs.

  Still, for a normal application program to have to apparently do this
is pretty lousy and s/not have to be needed, just to run on Win10!!!
Am I now expected to clean up THEIR "factory" threads? I can only
imagine what my old store-bought program would do.

  At least, now, my system works almost like it does in Win7, tho I have
to ignore those SPI calls since they produce no data...

Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: jj2007 on August 31, 2015, 08:37:38 AM
Quote from: MtheK on August 31, 2015, 08:10:25 AMAm I now expected to clean up THEIR "factory" threads?

No. This is what ExitProcess was designed for.
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on September 09, 2015, 04:32:57 AM
  "designed"? That's sooooooo funny!
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: Donkey on September 09, 2015, 02:22:37 PM
Raymond Chen had this to say for all the "old fashioned model" guys who like to RET from a process.

http://blogs.msdn.com/b/oldnewthing/archive/2010/08/27/10054832.aspx
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: hutch-- on September 09, 2015, 03:03:22 PM
This discussion has made me laugh, it would not matter what you did with ancient mainframes, the termination of a running program is controlled by the operating system, not vague recollections from antiquity.

A cursory glance at the old Win32.HLP file tells you the story.

Quote
The ExitProcess function ends a process and all its threads.

VOID ExitProcess(

    UINT uExitCode    // exit code for all threads 
   );   

Parameters

uExitCode

Specifies the exit code for the process, and for all threads that are terminated as a result of this call. Use the GetExitCodeProcess function to retrieve the process's exit value. Use the GetExitCodeThread function to retrieve a thread's exit value.

Return Values
This function does not return a value.

Remarks
ExitProcess is the preferred method of ending a process. This function provides a clean process shutdown. This includes calling the entry-point function of all attached dynamic-link libraries (DLLs) with a value indicating that the process is detaching from the DLL. If a process terminates by calling TerminateProcess, the DLLs that the process is attached to are not notified of the process termination.

I wonder what the point is in trying to produce a deviant technique for what is a simple and tidy way to terminate a running application.
Title: Re: Win10 may suppress return codes(RC) from MASM 32bit console programs
Post by: MtheK on September 13, 2015, 06:00:05 AM
  Thanks for proving my point. W/such a blanket statement, why should
the OS ever fix their faulty code? "Oh, you have multiple, hanging
factory threads, a fake rc=0, and a 30-second lag at termination?
Oh, you don't do ExitProcess? Then it's YOUR fault for not cleaning up
the mess WE made!".  And, of course, this also explains the failure
of the 3 SPI commands, and my missing stacks, since it obviously
knows in advance that I won't be doing an ExitProcess.

  BTW, when you do your ExitProcess in your primary thread, and you
lose data from your SetConsoleCtrlHandler thread, which is the ONLY
thread that keeps the force-killer at bay during a power-off, remember
this discussion.

  I did like Chen's article, especially the "rude" part. Granted,
productional systems probably don't have much assembler, but that's
their loss.

  Seriously tho, thank you adeyblue for your suggestion, which
pointed to these "hanging system-injected" threads.

  No wonder the ancient mainframe remains vastly superior to the PC.
Thanks again for the hearty laugh!