[py-dev] error building greenlets
Alain Poirier
alain.poirier at net-ng.com
Sun Aug 28 15:08:56 CEST 2005
Hi Armin,
> On Wed, Aug 24, 2005 at 11:31:57PM +0200, Alain Poirier wrote:
> > A code compiled with the -fPIC option must preserve the ebx register.
>
> Indeed.
>
> > So, if it's noted as "clobbered", the new versions of gcc emit an error.
>
> This implication is not clear to me. The goal of the "clobbered" is
> precisely to force gcc to save the register to the stack and restore it.
> The fact that newer versions of gcc doesn't like 'ebx' in the clobbered
> list any more is an annoyance.
From the gcc doc (and the tests I did), I understand that the clobbered
list only indicate to the compiler what registers are used into the
function, but not to save them.
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.3
> > A 'push ebx' / 'pop ebx' pair need to be added into the slp_switch
> > function of switch_x86_unix.h
>
> Can you show the precise patch? I guess that you have in mind a "push
> ebx" in the first __asm__ line, and a "pop ebx" in the last one.
Yes
> This might be doing the trick but it looks very fragile (i.e. depending on
> the exact way gcc generates code).
In theorie, we need to save "ebx" which is a bit annoying because the C
macro SLP_SAVE_STATE do some 'return' and, in these cases, as ebx is not
popped => crash.
So we could change the 'return' by a 'goto end, in greenlet.c :
#define SLP_SAVE_STATE(stackref, stsizediff) \
stackref += STACK_MAGIC; \
if (slp_save_state((char*)stackref)) { r = -1; goto end; } \
if (!PyGreen_ACTIVE(ts_target)) { r = 1; goto end; } \
stsizediff = ts_target->stack_start - (char*)stackref
In switch_x86_unix.h (and 'end: ...' needed for all the other
architectures :( :
static int
slp_switch(void)
{
register int *stackref, stsizediff;
int r;
__asm__ volatile ("" : : : "esi", "edi");
__asm__ ("push %ebx");
__asm__ ("movl %%esp, %0" : "=g" (stackref));
{
SLP_SAVE_STATE(stackref, stsizediff);
__asm__ volatile (
"addl %0, %%esp\n"
"addl %0, %%ebp\n"
:
: "r" (stsizediff)
);
SLP_RESTORE_STATE();
r = 0;
}
end:
__asm__ ("pop %ebx");
return r;
__asm__ volatile ("" : : : "esi", "edi");
}
But,
> Now, I don't expect the value of the PIC register "ebx" to actually
> change during the program execution, so that it will have the same value
> in all greenlets at any time. If so, we don't actually have to save and
> restore it. Just removing the "ebx" in the two clobbered lists should
> be enough.
Right. As the "ebx" register is not modified by the asm of slp_switch, it
stays constant. So, in practice, remove "ebx" from the clobbered list is
enough and the simplest solution :)
> This is the conclusion to which I came some time ago already, but the
> problem with it is to detect if the code is indeed being compiled with
> -fPIC or not. If not, the "ebx" in the clobbered is essential. Any
> clue?
Hmm, I don't see why "ebx" in the clobbered is essential for a code compiled
without -fPIC ?
Amicalement,
Alain
More information about the Pytest-dev
mailing list