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/