From: Mario Semo on
Hello,

is there any way to query the remaining stack size of a thread?

i looked at the registers in the debugger. nothing which helps me to get the
border.

i tried:

unsigned long remainingStack()
{
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
::GetThreadContext(::GetCurrentThread(), &context);
void
*base = (void *)context.Esp,
*cur = &context;
return (char*)cur - (char*)base;
}

but this returns a constant since context.Esp changes from call to call.

any ideas?


--
mit freundlichen Gr��en/best regards
mario semo


From: Skywing [MVP] on
Look at the difference between the current stack pointer and
(PNT_TIB)NtCurrentTeb()->StackLimit.

--
Ken Johnson (Skywing)
Windows SDK MVP
http://www.nynaeve.net
"Mario Semo" <mario_semo(a)Xhotmail.com> wrote in message
news:ePDk13jkHHA.4596(a)TK2MSFTNGP05.phx.gbl...
> Hello,
>
> is there any way to query the remaining stack size of a thread?
>
> i looked at the registers in the debugger. nothing which helps me to get
> the
> border.
>
> i tried:
>
> unsigned long remainingStack()
> {
> CONTEXT context;
> context.ContextFlags = CONTEXT_CONTROL;
> ::GetThreadContext(::GetCurrentThread(), &context);
> void
> *base = (void *)context.Esp,
> *cur = &context;
> return (char*)cur - (char*)base;
> }
>
> but this returns a constant since context.Esp changes from call to call.
>
> any ideas?
>
>
> --
> mit freundlichen Gr��en/best regards
> mario semo
>
>

From: Mario Semo on
Hello,

That sounds exactly for what i was looking for.

Skywing [MVP] wrote:
> Look at the difference between the current stack pointer and
> (PNT_TIB)NtCurrentTeb()->StackLimit.

except that i didnt manage it to compile:

#include <windows.h>
#include <stdio.h>

int main(int argc,char *argv[])
{
PNT_TIB lTeb = (PNT_TIB)NtCurrentTeb();
return 0;
}


cl -W4 -nologo -D__WINDOWS__ teb.c user32.lib gdi32.lib
teb.c
teb.c(4) : warning C4100: 'argv' : unreferenced formal parameter
teb.c(4) : warning C4100: 'argc' : unreferenced formal parameter
teb.c(6) : warning C4189: 'lTeb' : local variable is initialized but not
referenced
teb.obj : error LNK2001: unresolved external symbol _NtCurrentTeb
teb.exe : fatal error LNK1120: 1 unresolved externals

is there anywhere a sample on how to use it?

i found
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/NtCurrentTeb.html

that the IF in winnt.h is incorrect.
Now i changed the decl in winnt.h from/to:

/*struct _TEB * NtCurrentTeb(void);*/
NTSYSAPI struct _TEB * NTAPI NtCurrentTeb();

(and i verified that i changed it at the correct location by adding @@@ to
the line to get a compile error).

ok, now i get:

cl -W4 -nologo -D__WINDOWS__ teb.c user32.lib gdi32.lib
teb.c
teb.c(4) : warning C4100: 'argv' : unreferenced formal parameter
teb.c(4) : warning C4100: 'argc' : unreferenced formal parameter
teb.c(6) : warning C4189: 'lTeb' : local variable is initialized but not
referenced
teb.obj : error LNK2001: unresolved external symbol __imp__NtCurrentTeb@0
teb.exe : fatal error LNK1120: 1 unresolved externals


mario.


From: Skywing [MVP] on
It should expand to either a macro or an inline function depending on which
compiler and SDK versions you are using, and which processor platform you're
targetting (see winnt.h). Are you using an old SDK perhaps?

For x86, it ought to expand to one of these:

#define PcTeb 0x18

// (recent compiler version in use)

__inline struct _TEB * NtCurrentTeb( void ) { return (struct _TEB *)
(ULONG_PTR) __readfsdword (PcTeb); }

// -or-

// (old crusty compiler version in use)

__inline struct _TEB * NtCurrentTeb( void ) { __asm mov eax, fs:[PcTeb] }

...that is based on the Vista SDK headers (again, winnt.h being the relevant
one).

--
Ken Johnson (Skywing)
Windows SDK MVP
http://www.nynaeve.net
"Mario Semo" <mario_semo(a)Xhotmail.com> wrote in message
news:OjV3Q0kkHHA.4772(a)TK2MSFTNGP05.phx.gbl...
> Hello,
>
> That sounds exactly for what i was looking for.
>
> Skywing [MVP] wrote:
>> Look at the difference between the current stack pointer and
>> (PNT_TIB)NtCurrentTeb()->StackLimit.
>
> except that i didnt manage it to compile:
>
> #include <windows.h>
> #include <stdio.h>
>
> int main(int argc,char *argv[])
> {
> PNT_TIB lTeb = (PNT_TIB)NtCurrentTeb();
> return 0;
> }
>
>
> cl -W4 -nologo -D__WINDOWS__ teb.c user32.lib gdi32.lib
> teb.c
> teb.c(4) : warning C4100: 'argv' : unreferenced formal parameter
> teb.c(4) : warning C4100: 'argc' : unreferenced formal parameter
> teb.c(6) : warning C4189: 'lTeb' : local variable is initialized but not
> referenced
> teb.obj : error LNK2001: unresolved external symbol _NtCurrentTeb
> teb.exe : fatal error LNK1120: 1 unresolved externals
>
> is there anywhere a sample on how to use it?
>
> i found
> http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/NtCurrentTeb.html
>
> that the IF in winnt.h is incorrect.
> Now i changed the decl in winnt.h from/to:
>
> /*struct _TEB * NtCurrentTeb(void);*/
> NTSYSAPI struct _TEB * NTAPI NtCurrentTeb();
>
> (and i verified that i changed it at the correct location by adding @@@ to
> the line to get a compile error).
>
> ok, now i get:
>
> cl -W4 -nologo -D__WINDOWS__ teb.c user32.lib gdi32.lib
> teb.c
> teb.c(4) : warning C4100: 'argv' : unreferenced formal parameter
> teb.c(4) : warning C4100: 'argc' : unreferenced formal parameter
> teb.c(6) : warning C4189: 'lTeb' : local variable is initialized but not
> referenced
> teb.obj : error LNK2001: unresolved external symbol __imp__NtCurrentTeb@0
> teb.exe : fatal error LNK1120: 1 unresolved externals
>
>
> mario.
>
>

From: Mario Semo on
Skywing [MVP] wrote:
> It should expand to either a macro or an inline function depending on
> which compiler and SDK versions you are using, and which processor
> platform you're targetting (see winnt.h). Are you using an old SDK
> perhaps?
>
> For x86, it ought to expand to one of these:
>
> #define PcTeb 0x18
>
> // (recent compiler version in use)
>
> __inline struct _TEB * NtCurrentTeb( void ) { return (struct _TEB *)
> (ULONG_PTR) __readfsdword (PcTeb); }
>
> // -or-
>
> // (old crusty compiler version in use)
>
> __inline struct _TEB * NtCurrentTeb( void ) { __asm mov eax,
> fs:[PcTeb] }
>
> ..that is based on the Vista SDK headers (again, winnt.h being the
> relevant one).
>

Ken,

i am using XP-SDK
Winnt.h says:

/*++ BUILD Version: 0082 Increment this if a change has global effects

the original decl comes from:

#if defined(_M_ALPHA)
#define NtCurrentTeb() ((struct _TEB *)_rdteb())
#else
struct _TEB * NtCurrentTeb(void);
#endif

here i tried first :

NTSYSAPI struct _TEB * NTAPI NtCurrentTeb();

and now

#define PcTeb 0x18
__inline struct _TEB * NtCurrentTeb( void ) { __asm mov eax,fs:[PcTeb] }

Is there any chance that this just checks (via StackLimit) the current
comitted stack size?

PNT_TIB lTeb = (PNT_TIB)NtCurrentTeb();
printf("%p - %p =
%u\n",(char*)lTeb->StackLimit,&lTeb,(char*)&lTeb-(char*)lTeb->StackLimit);



cl -W4 -nologo -D__WINDOWS__ -Ge -Od -Zi teb.c user32.lib gdi32.lib
/link"/stack:0x100000,0x20000"
S:\TOOLS\SAMPLES\C>teb
00110000 - 0012FF7C = 130940


S:\TOOLS\SAMPLES\C>del teb.exe

cl -W4 -nologo -D__WINDOWS__ -Ge -Od -Zi teb.c user32.lib gdi32.lib
/link"/stack:0x10000,0x2000"
0006E000 - 0006FF7C = 8060

which means (at the beginn of "main")

stacksize=1MB, commit 132K -> free is 130K
stacksize=64K, commit 8K -> free 8060 bytes

one more test: stack=65K, commit 64K --> free 64K.