2010/3/4 Javier Pimás <[email protected]> > Also I have the theory that the problem may be related to some > -fomit-frame-pointer hidden in some place that forces code to use references > relative to esp instead of ebp.
Ah, that's *very* important. The plugin must *not* be built with -fomi-frame-pointer. In fact it needs -fno-omit-frame-pointer adding to Makefile.inc et al to ensure it always includes the frame pointer. > > > On Fri, Mar 5, 2010 at 1:20 AM, Javier Pimás > <[email protected]>wrote: > >> Wiiiiiii. All tests passing now!! >> >> You were right, this func had so many variables that gcc was reserving >> some local space to do some intermediate calculations. >> >> To make the story short defining >> # define STACK_ALIGN_BYTES 16 >> solved it. >> >> After a lot of debugging I discovered that alloca was aligning the stack, >> allocating more space than necesary, and placing the args not starting from >> esp but from esp plus some offset. Adding getsp(argvec) to move argvec to >> the top of the stack didn't solve the problem because the code that pushes >> the args also overwrites it (don't know why, it's like alloca augmented the >> frame in the middle?). >> >> So, that define fixed everything, and >> >> #if __APPLE__ && __MACH__ && __i386__ >> # define STACK_ALIGN_BYTES 16 >> #endif >> >> should be changed accordingly (to something I don't know what). In my case >> I'm using gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1. >> >> Thanks for all the help! >> >> Regards, >> Javier. >> >> >> >> On Wed, Mar 3, 2010 at 2:36 PM, Javier Pimás >> <[email protected]>wrote: >> >>> Exactly, that's what confuses me most! The function doesn't even have >>> locals: >>> >>> EXPORT(LONGLONG) ffiTestLongLong10a2(char c1, char c2, char c3, char c4, >>> char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG >>> i2) { >>> return c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+i1 + i2; >>> } >>> >>> I'm quite sure it's substracting because I see the memory contents, and >>> the disassembly is this (notice how it accumulates the result in edx): >>> >>> 0x75d32725 <ffiTestLongLong10a2+308>: movsbl -0x1c(%ebp),%edx >>> 0x75d32729 <ffiTestLongLong10a2+312>: movsbl -0x20(%ebp),%eax >>> 0x75d3272d <ffiTestLongLong10a2+316>: add %eax,%edx >>> 0x75d3272f <ffiTestLongLong10a2+318>: movsbl -0x24(%ebp),%eax >>> 0x75d32733 <ffiTestLongLong10a2+322>: add %eax,%edx >>> 0x75d32735 <ffiTestLongLong10a2+324>: movsbl -0x28(%ebp),%eax >>> 0x75d32739 <ffiTestLongLong10a2+328>: add %eax,%edx >>> 0x75d3273b <ffiTestLongLong10a2+330>: movsbl -0x2c(%ebp),%eax >>> 0x75d3273f <ffiTestLongLong10a2+334>: add %eax,%edx >>> 0x75d32741 <ffiTestLongLong10a2+336>: movsbl -0x30(%ebp),%eax >>> 0x75d32745 <ffiTestLongLong10a2+340>: add %eax,%edx >>> 0x75d32747 <ffiTestLongLong10a2+342>: movsbl -0x34(%ebp),%eax >>> 0x75d3274b <ffiTestLongLong10a2+346>: add %eax,%edx >>> 0x75d3274d <ffiTestLongLong10a2+348>: movsbl -0x38(%ebp),%eax >>> 0x75d32751 <ffiTestLongLong10a2+352>: add %eax,%edx >>> 0x75d32753 <ffiTestLongLong10a2+354>: movsbl -0x3c(%ebp),%eax >>> 0x75d32757 <ffiTestLongLong10a2+358>: add %eax,%edx >>> 0x75d32759 <ffiTestLongLong10a2+360>: movsbl -0x40(%ebp),%eax >>> 0x75d3275d <ffiTestLongLong10a2+364>: lea (%edx,%eax,1),%eax >>> 0x75d32760 <ffiTestLongLong10a2+367>: mov %eax,%edx >>> 0x75d32762 <ffiTestLongLong10a2+369>: sar $0x1f,%edx >>> 0x75d32765 <ffiTestLongLong10a2+372>: add -0x48(%ebp),%eax >>> 0x75d32768 <ffiTestLongLong10a2+375>: adc -0x44(%ebp),%edx >>> 0x75d3276b <ffiTestLongLong10a2+378>: add -0x50(%ebp),%eax >>> 0x75d3276e <ffiTestLongLong10a2+381>: adc -0x4c(%ebp),%edx >>> 0x75d32771 <ffiTestLongLong10a2+384>: add $0xbc,%esp >>> 0x75d32777 <ffiTestLongLong10a2+390>: pop %ebx >>> 0x75d32778 <ffiTestLongLong10a2+391>: pop %esi >>> 0x75d32779 <ffiTestLongLong10a2+392>: pop %edi >>> 0x75d3277a <ffiTestLongLong10a2+393>: pop %ebp >>> 0x75d3277b <ffiTestLongLong10a2+394>: ret >>> >>> This is really weird! Why could gcc compiled it flipped? I'll continue >>> looking. >>> >>> Regards, >>> Javier. >>> >>> 2010/3/3 Eliot Miranda <[email protected]> >>> >>> >>>> >>>> 2010/3/3 Javier Pimás <[email protected]> >>>> >>>> Ok, this is way nicer. The line that was missing and that seems to solve >>>>> all this is >>>>> >>>>> self initializeSpecialObjectIndices. >>>>> >>>>> which I think should be placed in Alien>>#initialize just before >>>>> >>>>> self ensureInSpecialObjectsArray. >>>>> >>>>> but then I don't know why it should ensure anything that is done just >>>>> before. >>>>> >>>>> With that I it's really close to work. After a few hours I understood >>>>> the way tests are done. In Alien plugin you integrated a couple of >>>>> exported >>>>> functions (ffiTest*), which you then call in the tests. These funcs do >>>>> simple stuff like adding and returning the result, so you can compare, am >>>>> I >>>>> right? >>>>> >>>>> Then I realized that (at least in linux) the tests won't work if you >>>>> compile as internal (there won't be a .so, so you won't be able to load >>>>> the >>>>> C test functions!). >>>>> >>>>> Now with the small fix I added, and compiling as external, I can see >>>>> that it's actually almost almost working, buuuut I get these test results: >>>>> 36 run, 17 passed, 19 failures, 0 errors (had to remove >>>>> testCallingSquenceString because it crashed the VM). Notice that before I >>>>> got 20 errors and 0 failures. This is because the results are wrong. >>>>> >>>>> >>>>> I debugged the code with ddd to see what's happening, and I can see >>>>> that everything is going nice before the actual function call, that is >>>>> done >>>>> in dabusiness.h. >>>>> >>>>> funcAlien = interpreterProxy->stackValue(funcOffset); >>>>> f = *(void **)startOfParameterData(funcAlien); >>>>> >>>>> #if STACK_ALIGN_BYTES (in my compiled code it is'nt defined, should >>>>> it?) >>>>> /* cut stack back to start of aligned args */ >>>>> setsp(argstart); >>>>> #endif >>>>> r = f(); >>>>> >>>>> I took as example test #ffiTestLongLong10a2:, which calls >>>>> ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, >>>>> char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2). >>>>> >>>>> dabusiness.h allocated 56 bytes in argvec (10*4 for chars + 2*8 for >>>>> longlong), which then fills correctly (ddd says 1 2 3 4 5 6 7 8 9 10 11 0 >>>>> 12 >>>>> 0). I have to admit that I don't fully understand whats happening with the >>>>> stack then, but ffiTestLongLong10a2 gets its arguments wrong. I'm thinking >>>>> of a calling convention problem. Here it's why: >>>>> >>>>> In some run I have: &argvec[0] is pos 0aa0 (this is actually direction >>>>> inside the stack, near it's top). Just before assembly CALL >>>>> ffiTestLongLong10a2 I have ebp=0b68, and after the call it is pushed and >>>>> replaced with esp, which is 0a88. Then, we have, args at 0aa0, 0aa4, ..., >>>>> and current stack frame starting at 0a88 and going lower, 0a84, etc. That >>>>> may be ok, but when I look into the ffiTestLongLong10a2 assembly it is >>>>> trying to find the arguments by *substracting* to ebp (arg1 in ebp-1c, 2nd >>>>> in ebp-20, ...) when it should adding, looking in greater positions >>>>> (previous stack frame, arg1 is in ebp+18). This has to be some simple >>>>> calling convention stuff, but I don't know how to solve it, any ideas?. >>>>> >>>> >>>> Subtracting from ebp is for accessing locals, adding to ebp for >>>> accessing arguments. Are you sure you're not misinterpreting a local >>>> access >>>> as an argument access? >>>> >>>> >>>> >>>>> Thanks for reading, >>>>> Javier. >>>>> >>>>> >>>>> On Mon, Mar 1, 2010 at 9:05 PM, John M McIntosh < >>>>> [email protected]> wrote: >>>>> >>>>>> It would be missing, propose a change set. >>>>>> >>>>>> I would think people usually don't use VMMaker images as their daily >>>>>> work image. >>>>>> >>>>>> So take image, load vmaker, load vmaker stuff for alien, make alien >>>>>> plugin. >>>>>> >>>>>> got to my work image that doesn't have vmmaker in it, >>>>>> load alien support stuf, you don't need the alien-vmmaker-support >>>>>> btw. >>>>>> run tests. >>>>>> >>>>>> >>>>>> >>>>>> On 2010-03-01, at 3:36 PM, Javier Pimás wrote: >>>>>> >>>>>> Hi, I'm still trying to advance with this. Don't know what caused the >>>>>> ObjectMemory classPools but it seems to be away now, maybe I did some >>>>>> mistake last time. >>>>>> >>>>>> The thing is that now I have in ObjectMemory classPools all the >>>>>> original ones plus 4 new elements, which I think were added with this >>>>>> Alien-VMMaker-Support override: >>>>>> >>>>>> ObjectMemory>>#initialize >>>>>> initialize >>>>>> #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector >>>>>> #SelectorAttemptToAssign) >>>>>> do: [:c | >>>>>> [ObjectMemory addClassVarName: c] ifError: []]. >>>>>> >>>>>> the thing is that it never assigns them any value, so my theory is >>>>>> that there's some code missing? Then in Interpreter it happens something >>>>>> quite similar. Interpreter>>#initialize does this: >>>>>> >>>>>> ... >>>>>> >>>>>> #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs >>>>>> #PrimErrBadReceiver #PrimErrGenericFailure #PrimErrInappropriate >>>>>> #PrimErrNoCMemory #PrimErrNoMemory #PrimErrNoModification >>>>>> #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr ) >>>>>> do: [:c | >>>>>> [Interpreter addClassVarName: c] ifError: []]. >>>>>> >>>>>> #(#primFailCode) >>>>>> do: [:i | [Interpreter addInstVarName: i] ifError: []]. >>>>>> >>>>>> ... >>>>>> >>>>>> but then never calls initializePrimitiveErrorCodes, which would set >>>>>> the vars to a meaningfull value. >>>>>> >>>>>> >>>>>> In conclusion, the question would be, where is this missing >>>>>> initialization code? >>>>>> >>>>>> Hope you can help, thanks! >>>>>> >>>>>> Javier. >>>>>> >>>>>> On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> >>>>>>>> On 2010-02-22, at 6:48 PM, Javier Pimás wrote: >>>>>>>> >>>>>>>> Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are >>>>>>>> the results: >>>>>>>> >>>>>>>> 37 run, 17 passed, 0 failures, 20 errors. >>>>>>>> >>>>>>>> TestCallingSequenceChar10Long2 >>>>>>>> TestCallingSequenceChar2LongLong2 >>>>>>>> TestCallingSequenceChar8Long2 >>>>>>>> TestCallingSequenceChar9Long2 >>>>>>>> TestCallingSequenceCharLongLong2 >>>>>>>> TestCallingSequenceChars >>>>>>>> TestCallingSequenceDoubles14 >>>>>>>> TestCallingSequenceDoubles2 >>>>>>>> TestCallingSequenceFloats13 >>>>>>>> TestCallingSequenceFloats14 >>>>>>>> TestCallingSequenceFloats2 >>>>>>>> TestCallingSequenceFloats2WithInteger >>>>>>>> TestCallingSequenceFloats2WithInteger2 >>>>>>>> TestCallingSequenceFloats7 >>>>>>>> TestCallingSequenceInt >>>>>>>> TestCallingSequenceInt8 >>>>>>>> TestCallingSequenceIntWithFloatArgs >>>>>>>> TestCallingSequenceLongLong2 >>>>>>>> TestCallingSequenceShort >>>>>>>> TestCallingSequenceString >>>>>>>> >>>>>>>> >>>>>>>> Oh look SUnits, great stuff (*cough* well I wrote most of them). >>>>>>>> >>>>>>>> >>>>>>> Cool, this is really really useful (although I sometimes find wrting >>>>>>> tests boring ;) ). >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> It is failing in places where it does primLoadLibrary: 'IA32ABI'. >>>>>>>> Why should it try to load itself, if it's compiled as an internal >>>>>>>> plugin? I >>>>>>>> compiled it as external too but didn't work either. >>>>>>>> >>>>>>>> >>>>>>>> Well it compiled, but that doesn't mean it works. In fact the error >>>>>>>> means the plugin code is never loaded, or is callable. >>>>>>>> Now one thing to consider is that the plugin load fails, because it >>>>>>>> can't find it. (external usage). >>>>>>>> Or because (internal and external plugin) the VM Version and the >>>>>>>> plugin version don't match. >>>>>>>> >>>>>>>> Look for your definition of >>>>>>>> #define VM_PROXY_MINOR 8 >>>>>>>> >>>>>>>> It should be 8 or higher for compiling BOTH the VM and the Plugin. >>>>>>>> Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is >>>>>>>> mass confusion about which header is being used? >>>>>>>> >>>>>>>> If for example your VM say it's a VM_PROXY_MINOR of 7, then it >>>>>>>> won't work with a plugin compiled with VM_PROXY_MINOR = 8. >>>>>>>> It silently fails... Well actually it gives the primLoadLibrary >>>>>>>> failure, but good luck in guessing why... >>>>>>>> >>>>>>> >>>>>>> Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't >>>>>>> have I? It wouldn't compile if I didn't and its sets it to 8. Is it >>>>>>> defined >>>>>>> in any other place? >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Other question, can classic FFI and Alien live nicely together (I >>>>>>>> mean have x plugin use classic FFI while y uses Alien)? >>>>>>>> >>>>>>>> >>>>>>>> yes. >>>>>>>> >>>>>>>> One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You >>>>>>>> can't have both in, right? >>>>>>>> >>>>>>>> >>>>>>>> One is a subclass of the other. I use the IA32ABIPluginAttic one. >>>>>>>> >>>>>>> >>>>>>> Ok, what is the difference between them? a performance issue? >>>>>>> everything works the same I choose one or the other? >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Syntax highligthing is broken for Alien primitive methods like >>>>>>>> these: >>>>>>>> >>>>>>>> <primitive: 'primUnsignedShortAtPut' error: errorCode module: >>>>>>>> 'IA32ABI'> >>>>>>>> >>>>>>>> Lastly, as I said when I loaded Alien Core the first time, I got >>>>>>>> this error while loading it: >>>>>>>> >>>>>>>> Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong". >>>>>>>> >>>>>>>> What should I do about that? ignore it? >>>>>>>> >>>>>>>> >>>>>>>> Well it seems to be related to >>>>>>>> >>>>>>>> ((Smalltalk includesKey: #ObjectMemory) >>>>>>>> and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien >>>>>>>> ifAbsent: []) ~~ (index - 1)]) ifTrue: >>>>>>>> [self error: 'index probably wrong']. >>>>>>>> >>>>>>>> Usually people don't have ObjectMemory loaded in their image, and >>>>>>>> I"m not sure what it is check for. >>>>>>>> Why don't you try it in a regular Pharo image versus your VMMaker >>>>>>>> image. >>>>>>>> >>>>>>>> >>>>>>> In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When >>>>>>> I load VMMaker it's downloaded from monticello, but obviously, >>>>>>> #ClassAlien >>>>>>> isn't defined inside >>>>>>> >>>>>>> (Smalltalk at: #ObjectMemory) classPool >>>>>>> >>>>>>> Interestingly, after load alien, #ClassAlien gets added as a key, but >>>>>>> all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, >>>>>>> like >>>>>>> this: >>>>>>> >>>>>>> (Smalltalk at: #ObjectMemory) classPool inspect: >>>>>>> >>>>>>> - size : 119 >>>>>>> [#AllButHashBits] : nil >>>>>>> [#AllButMarkBit] : nil >>>>>>> [#AllButMarkBitAndTypeMask] : nil >>>>>>> [#AllButRootBit] : nil >>>>>>> [#AllButTypeMask] : nil >>>>>>> ... >>>>>>> [#ClassAlien] : nil >>>>>>> ... >>>>>>> >>>>>>> >>>>>>> Any ideas? >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Javier Pimás >>>>>>> Ciudad de Buenos Aires >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Javier Pimás >>>>>> Ciudad de Buenos Aires >>>>>> >>>>>> >>>>>> -- >>>>>> >>>>>> =========================================================================== >>>>>> John M. McIntosh <[email protected]> Twitter: >>>>>> squeaker68882 >>>>>> Corporate Smalltalk Consulting Ltd. >>>>>> http://www.smalltalkconsulting.com >>>>>> >>>>>> =========================================================================== >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> Javier Pimás >>>>> Ciudad de Buenos Aires >>>>> >>>>> _______________________________________________ >>>>> Pharo-project mailing list >>>>> [email protected] >>>>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >>>>> >>>> >>>> >>>> _______________________________________________ >>>> Pharo-project mailing list >>>> [email protected] >>>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >>>> >>> >>> >>> >>> -- >>> Javier Pimás >>> Ciudad de Buenos Aires >>> >> >> >> >> -- >> Javier Pimás >> Ciudad de Buenos Aires >> > > > > -- > Javier Pimás > Ciudad de Buenos Aires > > _______________________________________________ > Pharo-project mailing list > [email protected] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >
_______________________________________________ Pharo-project mailing list [email protected] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
