On 7/3/05, Justin Haygood <[EMAIL PROTECTED]> wrote: > The conversative GC still appears to give problems, even though I > narrowed it down, getting that stackbase pointer is tricky! Even using > the register which supposedely stores it doesn't work, even tho the > crash no longer appears in collector.cpp, it now appears in value.cpp > (but i still believe it has to do with corruption caused by the GC)
When I was researching getting stack base on windows, I cobbled those 2 solution (using sources for various programs). I have no idea if they're actually correct in multi-threaded programs, all I know that in a simple test they give the same result that could be a stack base. Another option would be to disable multi-threading on win. Original JS wasn't multi-threaded, it's a fairly recent addition and I think someone mentioned on this list that multi-threading isn't needed for webcore per-se (could be wrong on that). Krzysztof Kowalczyk | http://blog.kowalczyk.info get_stack_base.cpp: #include <windows.h> #include <stdio.h> typedef struct tagXTIB { // EXCEPTION_REGISTRATION_RECORD* pvExcept; //00h Head of exception record list void * pvExcept; //00h Head of exception record list PVOID pvStackUserTop; //04 Top of user stack PVOID pvStackUserBase; //08h Base of user stack } xTib; static xTib* GetTIB() { xTib* pTib; __asm { MOV EAX , FS:[18h] MOV pTib , EAX } return pTib; } void doTib() { xTib *tib = GetTIB(); printf("stack top: 0x%lx\n", tib->pvStackUserTop); printf("stack bottom: 0x%lx\n", tib->pvStackUserTop); } NT_TIB* GetTIB2() { NT_TIB* pTib; __asm { MOV EAX , FS:[18h] MOV pTib , EAX } return pTib; } void doTib2() { NT_TIB *tib = GetTIB2(); printf("stack limit: 0x%lx\n", tib->StackLimit); printf("stack bottom: 0x%lx\n", tib->StackBase); } # define is_writable(prot) ((prot) == PAGE_READWRITE \ || (prot) == PAGE_WRITECOPY \ || (prot) == PAGE_EXECUTE_READWRITE \ || (prot) == PAGE_EXECUTE_WRITECOPY) typedef unsigned long word; typedef char * ptr_t; /* Return the number of bytes that are writable starting at p. */ /* The pointer p is assumed to be page aligned. */ /* If base is not 0, *base becomes the beginning of the */ /* allocation region containing p. */ word GC_get_writable_length(ptr_t p, ptr_t *base) { MEMORY_BASIC_INFORMATION buf; word result; word protect; result = VirtualQuery(p, &buf, sizeof(buf)); if (result != sizeof(buf)) { printf("Weird VirtualQuery result\n"); return 0; } if (base != 0) *base = (ptr_t)(buf.AllocationBase); protect = (buf.Protect & ~(PAGE_GUARD | PAGE_NOCACHE)); if (!is_writable(protect)) { return(0); } if (buf.State != MEM_COMMIT) return(0); return(buf.RegionSize); } word GC_page_size; void GC_setpagesize() { SYSTEM_INFO GC_sysinfo; GetSystemInfo(&GC_sysinfo); GC_page_size = GC_sysinfo.dwPageSize; } ptr_t GC_get_stack_base() { int dummy; /* PLTSCHEME: set page size if it's not ready (so I can use this function before a GC happens). */ if (!GC_page_size) GC_setpagesize(); ptr_t sp = (ptr_t)(&dummy); ptr_t trunc_sp = (ptr_t)((word)sp & ~(GC_page_size - 1)); word size = GC_get_writable_length(trunc_sp, 0); return(trunc_sp + size); } void doMzGc() { printf("stack base: 0x%lx\n", GC_get_stack_base()); } #if 0 ptr_t GetThreadStackBase(HANDLE hThread) CONTEXT context; LDT_ENTRY desc; void *base; DWORD size, read; NT_TIB tib; GetThreadContext(hThread, &context); GetThreadSelectorEntry(hThread, context.SegFs, &desc); base = (void*) (desc.BaseLow | desc.HighWord.Bytes.BaseMid << 16 | desc.HighWord.Bytes.BaseHi << 24); size = desc.LimitLow | desc.HighWord.Bits.LimitHi; if (desc.HighWord.Bits.Granularity) size *= 4096; else size++; ReadProcessMemory(hProcess, base, &tib, min(size, sizeof(tib)), &read); return (ptr_t)tib.StackBase; // also tib.StackLimit } #endif int main(int argc, char **argv) { printf("start\n"); printf("using TIB method\n"); doTib(); printf("using TIB2 method\n"); doTib2(); printf("using mzscheme method\n"); doMzGc(); printf("end\n"); } _______________________________________________ webkit-dev mailing list [email protected] http://www.opendarwin.org/mailman/listinfo/webkit-dev
