This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Cygwin.dll crash, alloca and custom stack


From: Jason FU wrote:
No, it doesn't 'work fine' under Linux. In fact it doesn't work at all,
on any platform.

My apologies for sending something that doesn't work under Linux, but I had something similar working, but I wanted to cut it down for the sake of the mailing list, and I didn't have access to a Linux machine just then to test it again.


Anyway, this similar code does work under Linux, or at least it appears to:

#include <stdio.h>
int main() {
	void * st1, *oldstack;
	st1 = (void *)malloc(5000) + 5000;
	asm("mov %%esp, %0" : "=r" (oldstack));
	asm("mov %0, %%esp" : : "r" (st1));
	a();
	asm("mov %0, %%esp" : : "r" (oldstack));
}

int a() {
	printf("hello\n");
}

This is a cut down of a more complex bit of code that does a lot of switching stacks and works fine on Linux but not cygwin.

Where on earth do you think main is going to return to after
you've discarded the old stack like that?

Yes I know I didn't restore the stack, because I wasn't trying to show what happens when main returns, I was trying to show that printf crashes way before that ever becomes an issue. I've left the stack restoring code in the above version.


The stack is for the compiler's use, keep your hands off of it!

Uh, did you ask Linus Torvalds what he thinks about that?


You just threw away the stack and jumped into space.  What did you expect
to happen?

While I don't claim to be an uber-expert in assembler, I know I didn't "jump into space". I've written task switching programs in C under DOS that switch stacks with no problem.


Christopher Faylor wrote:

I would expect that a multi-threaded linux app would not like the above.

That may well be, but I can't see why. Multiple threads generally are just saving and restoring the registers, and don't care what stack those registers point to. In the old days with user space threading, I presume the user space code would be doing what I'm trying to do and creating its own stack.


Windows stores information about the stack in offsets from the %fs register.

You may be onto something there. Maybe Windows checks with the TEB that the stack hasn't overflowed and gets confused or something. Maybe restoring the system stack before any system calls is the only work around. The following code seems to work under cygwin. That work around might be fine for what I'm doing. Will have to think about it.


#include <stdio.h>
#include <setjmp.h>

int main() {
void * st1, *oldstack;
st1 = (void *)malloc(5000) + 5000;
asm("mov %%esp, %0" : "=r" (oldstack));
asm("mov %0, %%esp" : : "r" (st1));
a(oldstack);
asm("mov %0, %%esp" : : "r" (oldstack));
fprintf(stderr, "hello2\n"); }


int a(void * oldstack) { void * savestack;
asm("mov %%esp, %0" : "=r" (savestack));
asm("mov %0, %%esp" : : "r" (oldstack));
fprintf(stderr, "hello\n"); asm("mov %%esp, %0" : "=r" (savestack));
}




--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]