1. ver 4.0 c_func problem on WIN98

Calling a machine code function using c_func with SVN 1705 on WIN98 works properly.

Calling a machine code function using c_func with ANY SVN after SVN 1705 RETURNS ZERO using the exact same code.

SVN 1705 error dump said...
    name = {115's',116't',114'r',116't',111'o',107'k',95'_'} 
    p = {22315904,21900200}        -- calling parameters 
    r = 22315904                   -- returned value 
    d = { 
          36'$',                   -- routine id 
          20820768,                -- machine address 
          {33554436,33554436},     -- C_ULONG, C_ULONG 
          33554436,                -- returns C_ULONG   
          -13                      -- special meaning to my code 
        } 
 
-- Note: other confusing code removed here. 
 
-- THIS is where call took place  
C:\WMOTOR\INCLUDE\motor.e:2449	if d[4] then 
C:\WMOTOR\INCLUDE\motor.e:2450	r = c_func(d[1],p) 
C:\WMOTOR\INCLUDE\motor.e:2454	return r 
 
1958 error dump said...
program aborted  
    name = {115's',116't',114'r',116't',111'o',107'k',95'_'} 
    p = {23511640,24122848}        -- calling parameters   
    r = 0                 -- NOTE RETURNED VALUE IS ZERO ! 
    d = { 
          36'$',                -- routine id 
          6587648,              -- machine address 
          {33554436,33554436},  -- C_ULONG, C_ULONG 
          33554436,             -- returns C_ULONG 
          -13                   -- special meaning to my code 
 
        } 
-- Note: other confusing code removed here. 
 
-- THIS is where call took place  
C:\wmotor\include\motor.e:2449	if d[4] then 
C:\wmotor\include\motor.e:2450	r = c_func(d[1],p) 
C:\wmotor\include\motor.e:2454	return r 
 
new topic     » topic index » view message » categorize

2. Re: ver 4.0 c_func problem on WIN98

Bernie,

Is this still a problem in recent copies of Euphoria? We are up to 1971 now.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

3. Re: ver 4.0 c_func problem on WIN98

jeremy said...

Bernie,

Is this still a problem in recent copies of Euphoria? We are up to 1971 now.

Jeremy

Yes

I have tried every new update that has been added to the trunk.

I have been trying to find the problem with no luck.

Also If you click open euiw.exe on WIN98 the window just flashes open and immediately closes ( which doesn't happen on XP ) so there is no way a user can read the help options. euid.exe stays open.

new topic     » goto parent     » topic index » view message » categorize

4. Re: ver 4.0 c_func problem on WIN98

bernie said...

If you click open euiw.exe on WIN98 the window just flashes open and immediately closes ( which doesn't happen on XP )

On XP, do you see the message "(press any key and window will close ...)" at the end of the help text?

On WIN98, does the wait_key() function work for you?

new topic     » goto parent     » topic index » view message » categorize

5. Re: ver 4.0 c_func problem on WIN98

bernie said...
    d = { 
          36'$',                   -- routine id 
          20820768,                -- machine address 
        } 
 
r = c_func(d[1],p) 
 

looks to me that should be either call_func(d[1]) or c_func(d[2])...

new topic     » goto parent     » topic index » view message » categorize

6. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...
bernie said...

If you click open euiw.exe on WIN98 the window just flashes open and immediately closes ( which doesn't happen on XP )

On XP, do you see the message "(press any key and window will close ...)" at the end of the help text?

On WIN98, does the wait_key() function work for you?

Yes XP works correctly derek. It displays the options and press key etc.

I am just clicking on euiw.exe file not a program so
the wait_key would not have anything to do with it.

ON WIN98 window just flashs open and closes immediately

On SVN 1705 the window displays


Euphoria Interpreter 4.0.0 development for 32-bit Windows. SVN Revision 1705 Using Managed Memory Copyright (c) Rapid Deployment Software 2008 See http://www.RapidEuphoria.com/License.txt

file name to execute?

new topic     » goto parent     » topic index » view message » categorize

7. Re: ver 4.0 c_func problem on WIN98

bernie said...

I am just clicking on euiw.exe file not a program so the wait_key would not have anything to do with it.

How do you suppose the interpreter knows when you've pressed a key, and it can continue? Technically, it uses get(0), not wait_key() (see Cleanup() in error.e for details).

Matt

new topic     » goto parent     » topic index » view message » categorize

8. Re: ver 4.0 c_func problem on WIN98

bernie said...
DerekParnell said...
bernie said...

If you click open euiw.exe on WIN98 the window just flashes open and immediately closes ( which doesn't happen on XP )

On XP, do you see the message "(press any key and window will close ...)" at the end of the help text?

On WIN98, does the wait_key() function work for you?

Yes XP works correctly derek. It displays the options and press key etc.

I am just clicking on euiw.exe file not a program so
the wait_key would not have anything to do with it.

Please humor me ... does the wait_key() function work for you in WIN98?

I ask this because the way the help text is supposed to work is that if the program running contains "euiw" in its name, the message "(press any key and window will close ...)" is displayed and wait_key() is called. The window is then closed after you press any key. As this is working for XP, it should also be working for WIN98.

Here is a simple test program for you to see if wait_key() is working in WIN98...

-- waiting.ex -- 
include std/console.e 
puts(1, "Waiting ...\n") 
wait_key() 

This should display a new console window with "Waiting ..." in it and just sit there until you press one of the keyboard keys.

Can you try this test program on your WIN98system and let me know what happens?

If this works as expected, can you also try this following test program ...

-- waiting2.ex -- 
include std/console.e 
any_key("Still Waiting ...\n") 
new topic     » goto parent     » topic index » view message » categorize

9. Re: ver 4.0 c_func problem on WIN98

jeremy said...

Bernie,

Is this still a problem in recent copies of Euphoria? We are up to 1971 now.

Jeremy

I did not test 1971, but I did test eui - 1787 with managed mem - on w98. Here is the output:

1 

And here is the source code:

include std/dll.e 
include std/machine.e 
 
sequence mcode 
mcode = { 
#55, 
#89, 
#E5, 
#B8, 
#01, 
#00, 
#00, 
#00, 
#C9, 
#C3 
} 
 
object x, addr 
addr = allocate(20) 
poke(addr, mcode) 
x = define_c_func("", {'+', addr}, {}, C_INT) 
? c_func(x, {}) 

For those who are curious, here is how I got the machine code (from the assembly dump):

(gdb) x/9ib 0x08048334 
0x8048334 <g>:  push   ebp 
0x8048335 <g+1>:        mov    ebp,esp 
0x8048337 <g+3>:        mov    eax,0x1 
0x804833c <g+8>:        leave 
0x804833d <g+9>:        ret 
0x804833e <main>:       lea    ecx,[esp+4] 
0x8048342 <main+4>:     and    esp,0xfffffff0 
0x8048345 <main+7>:     push   DWORD PTR [ecx-4] 
0x8048348 <main+10>:    push   ebp 
(gdb) x/10xb 0x08048334 
0x8048334 <g>:  0x55    0x89    0xe5    0xb8    0x01    0x00    0x00    0x00 
0x804833c <g+8>:        0xc9    0xc3 

And here is the original C source code:

int g() { 
	return 1; 
} 
 
int main() 
{ 
	return g(); 
} 
new topic     » goto parent     » topic index » view message » categorize

10. Re: ver 4.0 c_func problem on WIN98

mattlewis said...

How do you suppose the interpreter knows when you've pressed a key, and it can continue? Technically, it uses get(0), not wait_key() (see Cleanup() in error.e for details).

Matt, the relevant code can be found in main.e ...

	if src_file = -2 then	 
		-- No source supplied on command line 
		show_usage() 
		if find("WIN32_GUI", OpDefines) then 
			any_key("(press any key and window will close ...)", STDERR) 
		end if 
		Cleanup(1) 
	end if 
new topic     » goto parent     » topic index » view message » categorize

11. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...
-- waiting.ex -- 
include std/console.e 
puts(1, "Waiting ...\n") 
wait_key() 

This should display a new console window with "Waiting ..." in it and just sit there until you press one of the keyboard keys.

Can you try this test program on your WIN98system and let me know what happens?

If this works as expected, can you also try this following test program ...

Yes the first test works

new topic     » goto parent     » topic index » view message » categorize

12. Re: ver 4.0 c_func problem on WIN98

bernie said...
DerekParnell said...
-- waiting.ex -- 
include std/console.e 
puts(1, "Waiting ...\n") 
wait_key() 

This should display a new console window with "Waiting ..." in it and just sit there until you press one of the keyboard keys.

Can you try this test program on your WIN98system and let me know what happens?

If this works as expected, can you also try this following test program ...

Yes the first test works

And the second test ???

Also, what happens when instead of clicking on the euiw.exe file name, you start a DOS console and type in "euiw"?

new topic     » goto parent     » topic index » view message » categorize

13. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...
bernie said...
DerekParnell said...
-- waiting.ex -- 
include std/console.e 
puts(1, "Waiting ...\n") 
wait_key() 

This should display a new console window with "Waiting ..." in it and just sit there until you press one of the keyboard keys.

Can you try this test program on your WIN98system and let me know what happens?

If this works as expected, can you also try this following test program ...

Yes the first test works

And the second test ???

Also, what happens when instead of clicking on the euiw.exe file name, you start a DOS console and type in "euiw"?

FIRST test with .EX file Opens full screen hitting key shrinks to window but have to close by [x] in top right corner

FIRST test with .EXW file Opens window hitting key closes window

SECOND test with .EX file Opens full screen hitting key shrinks to window but have to close by [x] in top right corner

SECOND test with .EXW file Opens window hitting key closes window

new topic     » goto parent     » topic index » view message » categorize

14. Re: ver 4.0 c_func problem on WIN98

I just tested 1971 and I have identical results.

jimcbrown said...
jeremy said...

Bernie,

Is this still a problem in recent copies of Euphoria? We are up to 1971 now.

Jeremy

I did not test 1971, but I did test eui - 1787 with managed mem - on w98. Here is the output:

1 

And here is the source code:

include std/dll.e 
include std/machine.e 
 
sequence mcode 
mcode = { 
#55, 
#89, 
#E5, 
#B8, 
#01, 
#00, 
#00, 
#00, 
#C9, 
#C3 
} 
 
object x, addr 
addr = allocate(20) 
poke(addr, mcode) 
x = define_c_func("", {'+', addr}, {}, C_INT) 
? c_func(x, {}) 

For those who are curious, here is how I got the machine code (from the assembly dump):

(gdb) x/9ib 0x08048334 
0x8048334 <g>:  push   ebp 
0x8048335 <g+1>:        mov    ebp,esp 
0x8048337 <g+3>:        mov    eax,0x1 
0x804833c <g+8>:        leave 
0x804833d <g+9>:        ret 
0x804833e <main>:       lea    ecx,[esp+4] 
0x8048342 <main+4>:     and    esp,0xfffffff0 
0x8048345 <main+7>:     push   DWORD PTR [ecx-4] 
0x8048348 <main+10>:    push   ebp 
(gdb) x/10xb 0x08048334 
0x8048334 <g>:  0x55    0x89    0xe5    0xb8    0x01    0x00    0x00    0x00 
0x804833c <g+8>:        0xc9    0xc3 

And here is the original C source code:

int g() { 
	return 1; 
} 
 
int main() 
{ 
	return g(); 
} 
new topic     » goto parent     » topic index » view message » categorize

15. Re: ver 4.0 c_func problem on WIN98

I just tested 1971 with a slightly different machine code:

Here is the output with eui:

9 

And here is the source code:

include std/dll.e 
include std/machine.e 
 
sequence mcode2 
mcode2 = { 
#55, 
#89, 
#E5, 
#8B, 
#45, 
#08, 
#C9, 
#C3 
} 
 
object x, addr 
addr = allocate(20) 
poke(addr, mcode2) 
x = define_c_func("", {'+', addr}, {C_INT}, C_INT) 
? c_func(x, {9}) 

euiw doesn't work, the window flashes and then immediately disappears, despite the fact that it is being run from a DOS Command Prompt (thus from another console window).

new topic     » goto parent     » topic index » view message » categorize

16. Re: ver 4.0 c_func problem on WIN98

jimcbrown said...

euiw doesn't work, the window flashes and then immediately disappears, despite the fact that it is being run from a DOS Command Prompt (thus from another console window).

This is to be expected. That is how euiw is designed to work. If you need to see the console output of a program run with euiw, you must manually pause the console before the application closes.

For example ...

? c_func(x, {9}) 
ifdef WIN32_GUI then -- thus running under euiw.exe 
  wait_key() 
end ifdef 
 
new topic     » goto parent     » topic index » view message » categorize

17. Re: ver 4.0 c_func problem on WIN98

bernie said...
DerekParnell said...

And the second test ???

Also, what happens when instead of clicking on the euiw.exe file name, you start a DOS console and type in "euiw"?

FIRST test with .EX file Opens full screen hitting key shrinks to window but have to close by [x] in top right corner

FIRST test with .EXW file Opens window hitting key closes window

SECOND test with .EX file Opens full screen hitting key shrinks to window but have to close by [x] in top right corner

SECOND test with .EXW file Opens window hitting key closes window

I see. Well it appears that you have ".EX" associated with euid.exe and ".EXW" associated with euiw.exe. This is normal and not the issue.

It also appears that clicking on the ".EXW" file, which invokes euiw.exe, has no problems with running wait_key(). This is good.

Now, can you please open a DOS console and type in "euiw" instead of clicking on "euiw.exe" file name. Remember that the wait_key() is only used after the help text if Euphoria sees "euiw" somewhere in the name of the file that is running Euphoria. If you have renamed "euiw.exe" to something else it defintely won't work as expected, but I'm pretty sure you haven't done that. What I'm trying to test now is to see if Windows 98 treats invoking the program from the command line any differently than invoking it by clicking on the file name.

It should be the same, but it won't hurt to test it out.

So all you have to do for this next test, is ...

  1. start a new DOS console.
  2. Type in "euiw" and press the Enter key.

If this does not wait (just flashes a new console) then I'm out of ideas for now, except to say why the heck are you still using WIN98??? blink

new topic     » goto parent     » topic index » view message » categorize

18. Re: ver 4.0 c_func problem on WIN98

jimcbrown said...

I just tested 1971 with a slightly different machine code:

Here is the output with eui:

9 

And here is the source code:

include std/dll.e 
include std/machine.e 
 
sequence mcode2 
mcode2 = { 
#55, 
#89, 
#E5, 
#8B, 
#45, 
#08, 
#C9, 
#C3 
} 
 
object x, addr 
addr = allocate(20) 
poke(addr, mcode2) 
x = define_c_func("", {'+', addr}, {C_INT}, C_INT) 
? c_func(x, {9}) 

euiw doesn't work, the window flashes and then immediately disappears, despite the fact that it is being run from a DOS Command Prompt (thus from another console window).

Thanks Jim:

I tried your code and it works ok on my system.

My code is much more involved than that; its assembler nested into euphoria functions that is dynamically translated into machine code. Thats why I can't just post a simple example to show the problem.

new topic     » goto parent     » topic index » view message » categorize

19. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...

Now, can you please open a DOS console and type in "euiw" instead of clicking on "euiw.exe" file name. Remember that the wait_key() is only used after the help text if Euphoria sees "euiw" somewhere in the name of the file that is running Euphoria. If you have renamed "euiw.exe" to something else it defintely won't work as expected, but I'm pretty sure you haven't done that. What I'm trying to test now is to see if Windows 98 treats invoking the program from the command line any differently than invoking it by clicking on the file name.

It should be the same, but it won't hurt to test it out.

So all you have to do for this next test, is ...

  1. start a new DOS console.
  2. Type in "euiw" and press the Enter key.

If this does not wait (just flashes a new console) then I'm out of ideas for now, except to say why the heck are you still using WIN98??? blink

I can confirm that on w98 using 1971 with managed mem, running the above steps causes euiw to quickly dump the help screen on a new console window and then quickly disappear. If my box was faster I suspect I'd have only seen a flash.

euiw does not wait.

new topic     » goto parent     » topic index » view message » categorize

20. Re: ver 4.0 c_func problem on WIN98

jimcbrown said...

I can confirm that on w98 using 1971 with managed mem, running the above steps causes euiw to quickly dump the help screen on a new console window and then quickly disappear. If my box was faster I suspect I'd have only seen a flash.

euiw does not wait.

By any chance is "euiw.exe" in upper case in WIN98? On my system, XP, it is in lowercase but EUID.EXE is in upper case. I was just wondering if on WIN98 the file name is EUIW.EXE and not euiw.exe? I can quickly fix this in Euphoria if this is the issue.

new topic     » goto parent     » topic index » view message » categorize

21. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...
bernie said...
DerekParnell said...

And the second test ???

Also, what happens when instead of clicking on the euiw.exe file name, you start a DOS console and type in "euiw"?

FIRST test with .EX file Opens full screen hitting key shrinks to window but have to close by [x] in top right corner

FIRST test with .EXW file Opens window hitting key closes window

SECOND test with .EX file Opens full screen hitting key shrinks to window but have to close by [x] in top right corner

SECOND test with .EXW file Opens window hitting key closes window

I see. Well it appears that you have ".EX" associated with euid.exe and ".EXW" associated with euiw.exe. This is normal and not the issue.

It also appears that clicking on the ".EXW" file, which invokes euiw.exe, has no problems with running wait_key(). This is good.

Now, can you please open a DOS console and type in "euiw" instead of clicking on "euiw.exe" file name. Remember that the wait_key() is only used after the help text if Euphoria sees "euiw" somewhere in the name of the file that is running Euphoria. If you have renamed "euiw.exe" to something else it defintely won't work as expected, but I'm pretty sure you haven't done that. What I'm trying to test now is to see if Windows 98 treats invoking the program from the command line any differently than invoking it by clicking on the file name.

It should be the same, but it won't hurt to test it out.

So all you have to do for this next test, is ...

  1. start a new DOS console.
  2. Type in "euiw" and press the Enter key.

If this does not wait (just flashes a new console) then I'm out of ideas for now, except to say why the heck are you still using WIN98??? blink

When I type in euiw in a DOS window a second window pops open and immediately closes in a flash leaving just the DOS window open.

First I have to support my wife's WIN98 dos games and someone has to make sure ver 4.0 works on WIN98.

new topic     » goto parent     » topic index » view message » categorize

22. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...
jimcbrown said...

I can confirm that on w98 using 1971 with managed mem, running the above steps causes euiw to quickly dump the help screen on a new console window and then quickly disappear. If my box was faster I suspect I'd have only seen a flash.

euiw does not wait.

By any chance is "euiw.exe" in upper case in WIN98? On my system, XP, it is in lowercase but EUID.EXE is in upper case. I was just wondering if on WIN98 the file name is EUIW.EXE and not euiw.exe? I can quickly fix this in Euphoria if this is the issue.

command_line() reports EUIW.EXE (despite the fact that "dir" and explorer show it in lower case).

new topic     » goto parent     » topic index » view message » categorize

23. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...
jimcbrown said...

euiw doesn't work, the window flashes and then immediately disappears, despite the fact that it is being run from a DOS Command Prompt (thus from another console window).

This is to be expected. That is how euiw is designed to work. If you need to see the console output of a program run with euiw, you must manually pause the console before the application closes.

For example ...

? c_func(x, {9}) 
ifdef WIN32_GUI then -- thus running under euiw.exe 
  wait_key() 
end ifdef 
 

This does not work, it acts as if WIN32_GUI is not defined for euiw.

Futhermore, when running either euiw or eui from explorer, I get the flash. eui does not wait for a keypress either, if it has its own console window.

new topic     » goto parent     » topic index » view message » categorize

24. Re: ver 4.0 c_func problem on WIN98

bernie said...

Thanks Jim:

I tried your code and it works ok on my system.

My code is much more involved than that; its assembler nested into euphoria functions that is dynamically translated into machine code. Thats why I can't just post a simple example to show the problem.

Without an example that demonstrates the problem, it will be very difficult to track down this bug. (Even a very complex example is better than no example.)

new topic     » goto parent     » topic index » view message » categorize

25. Re: ver 4.0 c_func problem on WIN98

jimcbrown said...

This does not work, it acts as if WIN32_GUI is not defined for euiw.

Ok! I see the problem and have just uploaded the fix. The problem was that when setting WIN32_GUI define, it only checked for lowercase "euiw". Obviously this is not correct because Windows uses case-insensitive file names.

jimcbrown said...

Futhermore, when running either euiw or eui from explorer, I get the flash.

I assume you mean that when clicking on the eui.exe file name, it just flashes and does not keep a console opened. This is the expected behaviour as it assumes that the operating system has opened a console/shell for it to use. By clicking, Windows does open a console/shell and when the application closes, then Windows closes the console down.

jimcbrown said...

eui does not wait for a keypress either, if it has its own console window.

If you saying that if you manually open a console, then type in "eui", that the 'press a key' message does not appear, then this is the expected behaviour. This is because eui assumes that the console is already open and will stay open after the application ends. In other words, it assumes that it will be run from a command line prompt.

new topic     » goto parent     » topic index » view message » categorize

26. Re: ver 4.0 c_func problem on WIN98

DerekParnell said...
jimcbrown said...

This does not work, it acts as if WIN32_GUI is not defined for euiw.

Ok! I see the problem and have just uploaded the fix. The problem was that when setting WIN32_GUI define, it only checked for lowercase "euiw". Obviously this is not correct because Windows uses case-insensitive file names.

Great, thanks for the prompt response!

DerekParnell said...
jimcbrown said...

Futhermore, when running either euiw or eui from explorer, I get the flash.

I assume you mean that when clicking on the eui.exe file name, it just flashes and does not keep a console opened. This is the expected behaviour as it assumes that the operating system has opened a console/shell for it to use. By clicking, Windows does open a console/shell and when the application closes, then Windows closes the console down.

jimcbrown said...

eui does not wait for a keypress either, if it has its own console window.

If you saying that if you manually open a console, then type in "eui", that the 'press a key' message does not appear, then this is the expected behaviour. This is because eui assumes that the console is already open and will stay open after the application ends. In other words, it assumes that it will be run from a command line prompt.

Understood. So the only bug left now is to find out why bernie's code always returns 0 while my machine code appears to work without issue.

new topic     » goto parent     » topic index » view message » categorize

27. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

This is a program that works on SVN 1705 on WIN98
BUT FAILS on later SVN's for example SVN 1971 on WIN98.

The program parses tokens out of string s.

If the first token returns ZERO then all you will see on the screen is "That's All Folks!"

If the program WORKS it will print a token and pause until you press a key for next token.

It will do this until it sees no more tokens and then print "That's All Folks!"

include std\machine.e 
include std\dll.e 
include std\sequence.e 
 
constant mcode = allocate(253) 
poke(mcode, { 
    -- strlen_: @ ;---------- @ 
    #FC,                    --     cld            ; clear the direction flag 
    #8B,#7C,#24,#04,        -- mov edi, [esp+4]   ; offset of str parameter 
    #31,#C0,                -- xor eax, eax       ; set al to contain zero 
    #83,#C9,#FF,            -- or ecx, -1         ; set counter to #FFFFFFFF 
    #F2,#AE,                -- repne scasb        ; scan for zero termination 
    #F7,#D1,                -- not ecx            ; invert ecx to get the count 
    #49,                    -- dec ecx            ; subtract 1 from the ecx ( null termination ) 
    #89,#C8,                -- mov eax, ecx       ; Return ecx ( the length ) 
    #C2,#04,#00,            -- ret 4              ; ret 4 adjust the stack 
    -- strspn_: @ ;---------- @ 
    #FC,                    --     cld 
    #31,#C0,                -- xor eax, eax 
    #8B,#4C,#24,#04,        -- mov ecx, [esp+4] 
    #EB,#13,                -- jmp ssp004 
			    -- ssp001: 
    #41,                    --     inc ecx 
    #8B,#7C,#24,#08,        -- mov edi, [esp+8] 
			    -- ssp002: 
    #8A,#37,                --     mov dh, [edi] 
    #08,#F6,                -- or dh, dh 
    #74,#0E,                -- jz ssp005 
    #38,#F2,                -- cmp dl, dh 
    #74,#03,                -- je ssp003 
    #47,                    -- inc edi 
    #EB,#F3,                -- jmp ssp002 
			    -- ssp003: 
    #40,                    --     inc eax 
			    -- ssp004: 
    #8A,#11,                --     mov dl, [ecx] 
    #08,#D2,                -- or dl, dl 
    #75,#E7,                -- jnz ssp001 
			    -- ssp005: 
    #C2,#08,#00,            --     ret 8            ; ret 8 
    -- strpbrk_: @ ;--------- 
    #FC,                    --     cld                ; 
    #8B,#44,#24,#04,        -- mov eax, [esp+4]   ; 
    #EB,#12,                -- jmp sb004          ; 
			    -- sb001:                 ; 
    #8B,#4C,#24,#08,        --     mov ecx, [esp+8]   ; 
			    -- sb002:                 ; 
    #8A,#31,                --     mov dh, [ecx]      ; 
    #08,#F6,                -- or dh, dh          ; 
    #74,#07,                -- jz sb003           ; 
    #38,#F2,                -- cmp dl, dh         ; 
    #74,#0C,                -- je sb005           ; 
    #41,                    -- inc ecx            ; 
    #EB,#F3,                -- jmp sb002          ; 
			    -- sb003:                 ; 
    #40,                    --     inc eax            ; 
			    -- sb004:                 ; 
    #8A,#10,                --     mov dl, [eax]      ; 
    #08,#D2,                -- or dl, dl          ; 
    #75,#E8,                -- jnz sb001          ; 
    #31,#C0,                -- xor eax, eax       ; 
			    -- sb005:                 ; 
    #C2,#08,#00,            --     ret 8              ; ret 8 
    -- strtok_: @ ;----------- 
    #8B,#74,#24,#04,        --     mov esi, [esp+4]   ; get buffer 
    #85,#F6,                -- test esi esi       ; first call ? 
    #74,#06,                -- jz nexttok         ; no 
    #89,#35,#A1,#AD,#D1,#83,-- mov [@ptr], esi    ; save buffer 
			    -- nexttok:               ; 
    #8B,#7C,#24,#08,        --     mov edi, [esp+8]   ; yes get delimit 
    #8B,#35,#A1,#AD,#D1,#83,-- mov esi, [@ptr]    ; get current ptr 
    #83,#FE,#00,            -- cmp esi, 0         ; 
    #74,#77,                -- je endtok          ; bail out 
    #57,                    -- push edi           ; delimit 
    #56,                    -- push esi           ; buffer 
    #E8,#93,#FF,#FF,#FF,    -- call near strspn_  ; find start of token 
    #01,#05,#A1,#AD,#D1,#83,-- add [@ptr], eax    ; goto first token 
    #8B,#7C,#24,#08,        -- mov edi, [esp+8]   ; get delimit 
    #8B,#35,#A1,#AD,#D1,#83,-- mov esi, [@ptr]    ; get current ptr 
    #83,#FE,#00,            -- cmp esi, 0         ; 
    #74,#5B,                -- je endtok          ; bail out 
    #83,#3E,#00,            -- cmp [esi], 0       ; pointing to zero ? 
    #74,#56,                -- je endtok          ; bail out 
    #57,                    -- push edi           ; delimit 
    #56,                    -- push esi           ; buffer 
    #E8,#97,#FF,#FF,#FF,    -- call near strpbrk_ ; find the end of the token 
    #8B,#35,#A1,#AD,#D1,#83,-- mov esi, [@ptr]    ; get current ptr 
    #39,#F0,                -- cmp eax, esi       ; 
    #74,#45,                -- je endtok          ; 
    #83,#F8,#00,            -- cmp eax, 0         ; 
    #74,#1A,                -- je exact           ; 
    #A3,#A1,#AD,#D1,#83,    -- mov [@ptr], eax    ; 
    #89,#C7,                -- mov edi, eax       ; 
    #B8,#00,#00,#00,#00,    -- mov eax, 0         ; 
    #88,#07,                -- mov [edi], al      ; 
    #89,#F0,                -- mov eax, esi       ; 
    #83,#05,#A1,#AD,#D1,#83,#01,-- add [@ptr], 1      ; 
    #C2,#08,#00,            -- ret 8              ; 
			    -- exact:                 ; 
    #8B,#35,#A1,#AD,#D1,#83,--     mov esi, [@ptr]    ; get current ptr 
    #56,                    -- push esi           ; 
    #E8,#29,#FF,#FF,#FF,    -- call near strlen_  ; 
    #83,#F8,#00,            -- cmp eax, 0         ; 
    #75,#02,                -- jne lasttok        ; 
    #EB,#13,                -- jmp endtok         ; 
			    -- lasttok:               ; 
    #B9,#00,#00,#00,#00,    --     mov ecx, 0         ; 
    #A1,#A1,#AD,#D1,#83,    -- mov eax, [@ptr]    ; get current ptr 
    #89,#0D,#A1,#AD,#D1,#83,-- mov [@ptr], ecx    ; block next call 
    #C2,#08,#00,            -- ret 8              ; 
			    -- endtok:                ; 
    #B8,#00,#00,#00,#00,    --     mov eax, 0         ; 
    #C2,#08,#00,            -- ret  8             ; 
    #00,#00,#00,#00})       -- ptr: dd 0              ; (249) 
poke4(mcode + 103, mcode + 249) -- @ptr 
poke4(mcode + 113, mcode + 249) -- @ptr 
poke4(mcode + 131, mcode + 249) -- @ptr 
poke4(mcode + 141, mcode + 249) -- @ptr 
poke4(mcode + 164, mcode + 249) -- @ptr 
poke4(mcode + 178, mcode + 249) -- @ptr 
poke4(mcode + 195, mcode + 249) -- @ptr 
poke4(mcode + 205, mcode + 249) -- @ptr 
poke4(mcode + 228, mcode + 249) -- @ptr 
poke4(mcode + 234, mcode + 249) -- @ptr 
 
integer rid = define_c_func("", mcode+93, {C_ULONG,C_ULONG}, C_ULONG) 
 
sequence s = "Thisqxzzw::q is: qaq z \"test\" of xxbernie'sx zzcode "  -- parse string 
atom tok, b = allocate_string(s), d = allocate_string("qxz w:\"") 
 
tok = c_func(rid,{b,d}) -- strtok get token 
 
while tok do 
 
puts(1,peek_string(tok)&"\n") -- display the token 
if getc(0) then end if  -- pause 
tok = c_func(rid,{0,d}) -- strtok get another token 
 
end while 
 
-- IF THIS IS THE ONLY THING THAT PRINTS THE ABOVE TOK RETURNED ZERO !!! 
puts(1,"That's All Folks!\n") 
if getc(0) then end if  -- pause 
 
new topic     » goto parent     » topic index » view message » categorize

28. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

This is a program that works on SVN 1705 on WIN98
BUT FAILS on later SVN's for example SVN 1971 on WIN98.

The program parses tokens out of string s.

If the first token returns ZERO then all you will see on the screen is "That's All Folks!"

If the program WORKS it will print a token and pause until you press a key for next token.

It will do this until it sees no more tokens and then print "That's All Folks!"

I am able to confirm the following:

The code works fine on Linux, with or without a '+'. (Looking at the source, it seems Linux just uses CDECL no matter what.)

The code works fine on w98 when using mingw eui.exe and STDCALL.

The code causes a machine level exception on w98 when using mingw eui.exe and CDECL.

The code does not crash, but the first token returns 0 on w98 when using watcom eui.exe, with or without a '+'. (Looking at the source, it seems Watcom also uses CDECL no matter what.)

I believe the issue is not in the machine code itself, nor in call_c()'s preamble to calling the machine code, but how we handle the return value from the function in be_callc.c's call_c() function.

new topic     » goto parent     » topic index » view message » categorize

29. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jimcbrown said...
bernie said...

This is a program that works on SVN 1705 on WIN98
BUT FAILS on later SVN's for example SVN 1971 on WIN98.

The program parses tokens out of string s.

If the first token returns ZERO then all you will see on the screen is "That's All Folks!"

If the program WORKS it will print a token and pause until you press a key for next token.

It will do this until it sees no more tokens and then print "That's All Folks!"

I am able to confirm the following:

The code works fine on Linux, with or without a '+'. (Looking at the source, it seems Linux just uses CDECL no matter what.)

The code works fine on w98 when using mingw eui.exe and STDCALL.

The code causes a machine level exception on w98 when using mingw eui.exe and CDECL.

The code does not crash, but the first token returns 0 on w98 when using watcom eui.exe, with or without a '+'. (Looking at the source, it seems Watcom also uses CDECL no matter what.)

I believe the issue is not in the machine code itself, nor in call_c()'s preamble to calling the machine code, but how we handle the return value from the function in be_callc.c's call_c() function.

Jim I built all my binaries on XP using OpenWatcom Ver 1.8.

The program should run on any Euphoria binary no matter what compiler the binary was built with.

As far as the calling convention if I am calling my own internal code in my program I am controlling what I do to the stack so that should not matter.

new topic     » goto parent     » topic index » view message » categorize

30. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

Jim I built all my binaries on XP using OpenWatcom Ver 1.8.

Can you confirm that the code works correctly on XP? Even if called with '+' ?

bernie said...

The program should run on any Euphoria binary no matter what compiler the binary was built with.

Agreed. This is a bug of eui.exe/euiw.exe

bernie said...

As far as the calling convention if I am calling my own internal code in my program I am controlling what I do to the stack so that should not matter.

This is wrong.

You call

tok = c_func(rid, {b,d})

So we need to know the correct calling convention to pass the arguments (b and d) onto the stack to the machine code, and then we need to know the convention again to obtain the correct return value.

Thus, for the call to rid to be successful, the calling convention is important. You can't just assume that c_func() will magically know the right thing to do.

However,

1. The default calling convetion on Windows is STDCALL (and '+' means CDECL). 2. Your machine code appears to be using STDCALL, if i understand the assembly languge correctly.

Therefore, this example should have worked on w98.

new topic     » goto parent     » topic index » view message » categorize

31. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

I added some debug code to call_c() (nothing but printf()s) and suddenly the code is working correctly.

This sounds like an optimization bug.

new topic     » goto parent     » topic index » view message » categorize

32. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jimcbrown said...

I added some debug code to call_c() (nothing but printf()s) and suddenly the code is working correctly.

This sounds like an optimization bug.

If you are unable to use patch, the entire file (source/be_callc.c) is available at http://euphoria.pastey.net/112882

But, as you can see from the diff, the only changes required to make it work are 3 printf() statements.

--- ../feu3/source/be_callc.c   2009-04-08 14:04:05.000000000 -0400 
+++ /tmp/fl/eu40/source/be_callc9.c     2009-04-22 23:26:38.000000000 -0400 
@@ -118,6 +118,7 @@ 
        if (IS_ATOM(arg_list)) { 
                RTFatal("c_proc/c_func: argument list must be a sequence"); 
        } 
+        printf("ha! %d\n", proc_index); 
 
        arg_list_ptr = SEQ_PTR(arg_list); 
        next_arg_ptr = arg_list_ptr->base + arg_list_ptr->length; 
@@ -277,11 +278,13 @@ 
 #if defined(EWINDOWS) && !defined(EWATCOM) 
                if (cdecl_call) { 
                        iresult = (*((int (  __cdecl *)())int_proc_address))(); 
+                        printf("iresult cdecl %d %d %d %x\n", iresult, proc_ind 
ex, func, return_type); 
                        pop(); 
                } 
                else 
 #endif 
                        iresult = (*((int (__stdcall *)())int_proc_address))(); 
+                        printf("iresult stdcall %d %d %d %x\n", iresult, proc_i 
ndex, func, return_type); 
 #ifdef EUNIX 
                pop(); 
 #endif 
new topic     » goto parent     » topic index » view message » categorize

33. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jimcbrown said...

This is wrong.

You call

tok = c_func(rid, {b,d})

So we need to know the correct calling convention to pass the arguments (b and d) onto the stack to the machine code, and then we need to know the convention again to obtain the correct return value.

Thus, for the call to rid to be successful, the calling convention is important. You can't just assume that c_func() will magically know the right thing to do.

However,

1. The default calling convetion on Windows is STDCALL (and '+' means CDECL). 2. Your machine code appears to be using STDCALL, if i understand the assembly languge correctly.

Therefore, this example should have worked on w98.

What I meant is I know when I am calling windows code or my code so I have control over cleaning stack when its neccesary.

The only difference between CDECL and STDCALL is:

  • CDECL
  • CDECL calling convention the following holds:
  • Arguments are passed on the stack in Right-to-Left order, and return values are passed in eax.
  • The calling function cleans the stack. This allows CDECL functions to have variable-length argument lists (aka variadic functions). For this reason the number of arguments is not appended to the name of the function by the compiler, and the assembler and the linker are therefore unable to determine if an incorrect number of arguments is used.
  • STDCALL
  • STDCALL passes arguments right-to-left, and returns the value in eax. (The Microsoft documentation erroneously claims that arguments are passed left-to-right, but this is not the case.)
  • The called function cleans the stack, unlike CDECL. This means that STDCALL doesn't allow variable-length argument lists.

These are quotes from this web page: http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Convention_Examples

new topic     » goto parent     » topic index » view message » categorize

34. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

What I meant is I know when I am calling windows code or my code so I have control over cleaning stack when its neccesary.

Ok, I understand now. You are correct, Bernie.

Can you look at my previous post and confirm if the patch (of printf()s ) makes the machine code call work correctly on w98?

new topic     » goto parent     » topic index » view message » categorize

35. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

I copied the file that you posted and then replaced the file in SVN1973 with your file I ran it compiled it with Watcom .

I then took the binaries That were just compiled and placed them in the bin and then tried to used them to see if I could build the binaries again and Watcom goes into a loop printing

ha! 35 iresult stdcall ... over and over again.

I often build binaries this way to check their integrity. I don't think that your patch is a safe one.

I'll try them after one build just to see if we are on the right path.

new topic     » goto parent     » topic index » view message » categorize

36. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

I copied the file that you posted and then replaced the file in SVN1973 with your file I ran it compiled it with Watcom .

I then took the binaries That were just compiled and placed them in the bin and then tried to used them to see if I could build the binaries again and Watcom goes into a loop printing

ha! 35 iresult stdcall ... over and over again.

I often build binaries this way to check their integrity. I don't think that your patch is a safe one.

I'll try them after one build just to see if we are on the right path.

That is the debug code ... but even with the extra junk I was able to run your example and saw that it corrected the problem. (This patch isn't a real fix of course, because of the extra junk.)

new topic     » goto parent     » topic index » view message » categorize

37. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

Jim:

As far as I can tell that should fix everything. Let me know when you get the new files ready.

Thanks very much.

I am going to call it a night.

new topic     » goto parent     » topic index » view message » categorize

38. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jimcbrown said...

I added some debug code to call_c() (nothing but printf()s) and suddenly the code is working correctly.

This sounds like an optimization bug.

I've had similar problems, I get a machine crash here or there, add a ? 0 and everything works. I try to reduce the program to a small test case and fail every time. It seems that if that happens, I just continue programming and the problem goes away itself. I've never had a good test case, maybe this is one Matt can track down?

Jeremy

new topic     » goto parent     » topic index » view message » categorize

39. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jeremy said...
jimcbrown said...

I added some debug code to call_c() (nothing but printf()s) and suddenly the code is working correctly.

This sounds like an optimization bug.

I've had similar problems, I get a machine crash here or there, add a ? 0 and everything works. I try to reduce the program to a small test case and fail every time. It seems that if that happens, I just continue programming and the problem goes away itself. I've never had a good test case, maybe this is one Matt can track down?

Jeremy

Well, this is in be_callc.c (100% C code, aside from a few asm macros), so it is either a) a bug in Watcom or b) expected behavior because we are telling Watcom to be overly aggressive in its optimizations.

new topic     » goto parent     » topic index » view message » categorize

40. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jeremy said...
jimcbrown said...

I added some debug code to call_c() (nothing but printf()s) and suddenly the code is working correctly.

This sounds like an optimization bug.

I've had similar problems, I get a machine crash here or there, add a ? 0 and everything works. I try to reduce the program to a small test case and fail every time. It seems that if that happens, I just continue programming and the problem goes away itself. I've never had a good test case, maybe this is one Matt can track down?

This is gonna be a fun bug. The code works correctly for me on XP when I build a debug version of eui.exe, but it displays the reported behavior when built in release mode.

Matt

new topic     » goto parent     » topic index » view message » categorize

41. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

mattlewis said...

This is gonna be a fun bug. The code works correctly for me on XP when I build a debug version of eui.exe, but it displays the reported behavior when built in release mode.

Matt

I was able to get an acceptable patch by changing the printfs into snprintfs.

The nature of the bug makes me think that Watcom is optimizing the value of iresult or return_type away.

new topic     » goto parent     » topic index » view message » categorize

42. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jimcbrown said...
mattlewis said...

This is gonna be a fun bug. The code works correctly for me on XP when I build a debug version of eui.exe, but it displays the reported behavior when built in release mode.

Matt

I was able to get an acceptable patch by changing the printfs into snprintfs.

The nature of the bug makes me think that Watcom is optimizing the value of iresult or return_type away.

It's not optimizing it away, but during the call, the value is changed. I put printfs around the call, and found that return_value was changing. This definitely seems like a Watcom bug. When I added printfs that took a reference to return_value, the problem went away.

Also, moving the declaration for the function pointer to be the last declared variable corrected the problem. I'm not sure what the proper fix might bedoes this cause other problems? We should probably take a look at the generated assembly to see what it's doing.

Sounds like something that should be submitted to OpenWatcom as a bug report.

Matt

new topic     » goto parent     » topic index » view message » categorize

43. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

In my opinion the problem acts like a memory problem.

The reason I think that is the problem goes away as Jim says when you add something or change something the problem goes away.

I suspect that it then moves code to different offset in memory.

This problem popup around time that Jeremy was change the binary names. At that time Jeremy started creating binaries that were crashing or building garbled up.

Jermey then fixed the problem at that time and there was a decision make binaries with the default using manage memory.

Are we sure that the code that is being built now is always laying on 4 byte boundaries as it was designed to work in 3.11 or has some bug been introduced during major changes in memory management.

new topic     » goto parent     » topic index » view message » categorize

44. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

I don't believe that managed memory has changed at all since i last touched it, over a thousand revisions ago.

The change to make managed memory default was a change in the makefile only, but no code changes.

bernie said...

In my opinion the problem acts like a memory problem.

The reason I think that is the problem goes away as Jim says when you add something or change something the problem goes away.

I suspect that it then moves code to different offset in memory.

This problem popup around time that Jeremy was change the binary names. At that time Jeremy started creating binaries that were crashing or building garbled up.

Jermey then fixed the problem at that time and there was a decision make binaries with the default using manage memory.

Are we sure that the code that is being built now is always laying on 4 byte boundaries as it was designed to work in 3.11 or has some bug been introduced during major changes in memory management.

new topic     » goto parent     » topic index » view message » categorize

45. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

I just built the binaries SVN1973 using be_callc.c file
from EU ver 3.11 source and those binaries work ok.

new topic     » goto parent     » topic index » view message » categorize

46. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

mattlewis said...

We should probably take a look at the generated assembly to see what it's doing.

I added a couple of printf statements:

	printf("1: return_type %8x %8x\n", return_type, int_proc_address ); 
	iresult = (*((int (__stdcall *)())int_proc_address))(); 
	printf("2: return_type %8x %8x\n", return_type, int_proc_address ); 

When calling Bernie's procedure, here's what we get:

1: return_type  2000004   ad7545 
2: return_type   b01ea8   ad7545 

So it's clear that return_type is changing. Looking at the assembly for the printf and the call:

printf("1: return_type %8x %8x\n", return_type, int_proc_address ); 
0378    8B 45 E8                  mov         eax,dword ptr -0x18[ebp] 
037B    50                        push        eax 
037C    56                        push        esi 
037D    68 AB 01 00 00            push        offset L$58 
0382    E8 00 00 00 00            call        printf_ 
 
iresult = (*((int (__stdcall *)())int_proc_address))(); 
0387    83 C4 0C                  add         esp,0x0000000c 
038A    8B 5D E8                  mov         ebx,dword ptr -0x18[ebp] 
038D    FF 55 E8                  call        dword ptr -0x18[ebp] 
 
printf("2: return_type %8x %8x\n", return_type, int_proc_address ); 
0390    53                        push        ebx 
0391    56                        push        esi 
0392    68 C4 01 00 00            push        offset L$59 
0397    89 C2                     mov         edx,eax 
0399    89 C1                     mov         ecx,eax 
039B    E8 00 00 00 00            call        printf_ 
It looks like return_type is being stored in esi. I notice that Bernie's code modifies esi. I'm not sure whose responsibility it is to restore esi, but the problem appears to be that Watcom thinks that it's Bernie's job to restore any registers. That also helps explain why, when I took the address of return_type, it started working againbecause Watcom stopped putting return_type in a register that gets clobbered.

Matt

new topic     » goto parent     » topic index » view message » categorize

47. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

mattlewis said...
mattlewis said...

We should probably take a look at the generated assembly to see what it's doing.

I added a couple of printf statements:

	printf("1: return_type %8x %8x\n", return_type, int_proc_address ); 
	iresult = (*((int (__stdcall *)())int_proc_address))(); 
	printf("2: return_type %8x %8x\n", return_type, int_proc_address ); 

When calling Bernie's procedure, here's what we get:

1: return_type  2000004   ad7545 
2: return_type   b01ea8   ad7545 

So it's clear that return_type is changing. Looking at the assembly for the printf and the call:

printf("1: return_type %8x %8x\n", return_type, int_proc_address ); 
0378    8B 45 E8                  mov         eax,dword ptr -0x18[ebp] 
037B    50                        push        eax 
037C    56                        push        esi 
037D    68 AB 01 00 00            push        offset L$58 
0382    E8 00 00 00 00            call        printf_ 
 
iresult = (*((int (__stdcall *)())int_proc_address))(); 
0387    83 C4 0C                  add         esp,0x0000000c 
038A    8B 5D E8                  mov         ebx,dword ptr -0x18[ebp] 
038D    FF 55 E8                  call        dword ptr -0x18[ebp] 
 
printf("2: return_type %8x %8x\n", return_type, int_proc_address ); 
0390    53                        push        ebx 
0391    56                        push        esi 
0392    68 C4 01 00 00            push        offset L$59 
0397    89 C2                     mov         edx,eax 
0399    89 C1                     mov         ecx,eax 
039B    E8 00 00 00 00            call        printf_ 
It looks like return_type is being stored in esi. I notice that Bernie's code modifies esi. I'm not sure whose responsibility it is to restore esi, but the problem appears to be that Watcom thinks that it's Bernie's job to restore any registers. That also helps explain why, when I took the address of return_type, it started working againbecause Watcom stopped putting return_type in a register that gets clobbered.

Matt

Matt:

My code does not have any thing to do with changing the return type.

If you will note that the return type is set up in the define_c_func by a C_ULONG which is NOT controlled by my program code but internally by Euphoria.

No matter what is done to the ESI register internally in my code; it should not effect the external Euphoria code.

The return VALUE will on each pass; return a different pointer. The only thing that I am storing in my is the program is at ptr: dd 0 location in my code which keeps the pointer for the next pass.

new topic     » goto parent     » topic index » view message » categorize

48. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...
mattlewis said...

It looks like return_type is being stored in esi. I notice that Bernie's code modifies esi. I'm not sure whose responsibility it is to restore esi, but the problem appears to be that Watcom thinks that it's Bernie's job to restore any registers. That also helps explain why, when I took the address of return_type, it started working againbecause Watcom stopped putting return_type in a register that gets clobbered.

My code does not have any thing to do with changing the return type.

If you will note that the return type is set up in the define_c_func by a C_ULONG which is NOT controlled by my program code but internally by Euphoria.

No matter what is done to the ESI register internally in my code; it should not effect the external Euphoria code.

The return VALUE will on each pass; return a different pointer. The only thing that I am storing in my is the program is at ptr: dd 0 location in my code which keeps the pointer for the next pass.

Bernie,

Please re-read what I wrote. Your code changes esi. Watcom is storing the variable return_type in esi. Therefore, as far as the call_c code is concerned, your code is changing return_type.

See, for example (from your code):

    #8B,#35,#A1,#AD,#D1,#83,-- mov esi, [@ptr]    ; get current ptr  

Matt

new topic     » goto parent     » topic index » view message » categorize

49. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

My code does not have any thing to do with changing the return type.

Not the return type, but (the C variable that is internal to Euphoria) return_type.

bernie said...

If you will note that the return type is set up in the define_c_func by a C_ULONG which is NOT controlled by my program code but internally by Euphoria.

This information (the C_ULONG) is stored in return_type, however, so if return_type gets changed then the information is lost. Watcom makes the return_type variable the same as the ESI register.

bernie said...

No matter what is done to the ESI register internally in my code; it should not effect the external Euphoria code.

What Matt is saying is that your machine code is clobbering a register.

If you saved all registers before your machine code starts and then restored all registers before your machine code returns, that would fix the bug.

Now the question is, is the bug Watcom's fault or not? In other words, should the compiler be saving and restoring registers for us or is your machine code suppose to do that? This is beyond the internals of Euphoria, but entering the realm of the internals of Watcom C, the realm of the Watcom developer team.

new topic     » goto parent     » topic index » view message » categorize

50. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

jimcbrown said...

Now the question is, is the bug Watcom's fault or not? In other words, should the compiler be saving and restoring registers for us or is your machine code suppose to do that? This is beyond the internals of Euphoria, but entering the realm of the internals of Watcom C, the realm of the Watcom developer team.

After thinking about this, I believe that it must be the called function's responsibility. If it were the calling function's responsibility, then it would have to know which registers were modified. But this clearly cannot work (just imagine how it would work with dynamic linking, or indeed any function pointer whose contents cannot be known at compile time), so it would always have to save all registers. Indeed, looking at the top and bottom of the emitted assembly code for call_c, we can see that it saves the registers that it uses:

0000                          call_c_: 
0000    51                        push        ecx 
0001    56                        push        esi 
0002    57                        push        edi 
0003    55                        push        ebp 
 
... 
 
047B    5D                        pop         ebp 
047C    5F                        pop         edi 
047D    5E                        pop         esi 
047E    59                        pop         ecx 
047F    C3                        ret 
I think that this bug in Bernie's code was previously hidden only because the compiler wasn't counting on the esi register being changed at that point in the code.

Matt

new topic     » goto parent     » topic index » view message » categorize

51. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

mattlewis said...

After thinking about this, I believe that it must be the called function's responsibility.

I believe you are correct too. If one writes a machine code function, that function should save all general registers that it uses, except eax of course, and restore them just prior to returning. The machine code function cannot know which registers are being used by the caller, so it should be cautious. The returned data is assumed to be returned in eax.

new topic     » goto parent     » topic index » view message » categorize

52. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

@DerekParnell, @MattLewis It depends on the particular register. EAX, ECX, EDX can be used without saving (maybe others too I don't remember). It is nothing specific to Watcom. Use Google to find out more. Googling is faster than thinking blink

@Bernie Why not simply rewrite the assembler parts? Poking bytes that represent machine code is not the most maintainable thing in the world, you know.

new topic     » goto parent     » topic index » view message » categorize

53. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

I have done the following :

I built SVN1975 binaries on XP for WIN98 and ran them using my assembler code.

protecting the ESI register PASSED.
not protecting the ESI FAILED.

I then built SVN1975 binaries on XP for WIN98 WITH DEBUG TURNED ON and ran them using my assembler code.

protecting the ESI register PASSED.
not protecting the ESI PASSED.

Something is different between debug be turned on and off.

new topic     » goto parent     » topic index » view message » categorize

54. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

Something is different between debug be turned on and off.

Correct. This is expected behavior, sadly.

Therefore, you will just have to always protect ESI. According to Watcom FAQ, that is what you are suppose to do.

new topic     » goto parent     » topic index » view message » categorize

55. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

Something is different between debug be turned on and off.

Yes there is, but protecting ESI is the way to go.

Here is a comment from the Watcom manual ...

Watcom said...

All used 80x86 registers must be saved on entry and restored on exit except those used to pass arguments and return values, and AX, which is considered a stratch register. Note that segment registers only have to saved and restored if you are compiling your application with the "r" option.

The argument passing registers are EAX, EBX, ECX, EDX, so it means that ESI really must be protected.

new topic     » goto parent     » topic index » view message » categorize

56. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

DerekParnell said...
bernie said...

Something is different between debug be turned on and off.

Yes there is, but protecting ESI is the way to go.

Here is a comment from the Watcom manual ...

Watcom said...

All used 80x86 registers must be saved on entry and restored on exit except those used to pass arguments and return values, and AX, which is considered a stratch register. Note that segment registers only have to saved and restored if you are compiling your application with the "r" option.

The argument passing registers are EAX, EBX, ECX, EDX, so it means that ESI really must be protected.

Then Why did my code work since euphoria version 2.2 all the way up to ver 4.0 SVN 1705 ????

new topic     » goto parent     » topic index » view message » categorize

57. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

Then Why did my code work since euphoria version 2.2 all the way up to ver 4.0 SVN 1705 ????

bernie, do you even know how to program machine code?!

new topic     » goto parent     » topic index » view message » categorize

58. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

Sorry, this was a bit harsh.

jimcbrown said...
bernie said...

Then Why did my code work since euphoria version 2.2 all the way up to ver 4.0 SVN 1705 ????

bernie, do you even know how to program machine code?!

The reason it worked before, I am guessing, is that older versions of watcom, before OpenWatcom 1.7c, were not as good at optimizing, and so did not use the ESI register. Thus, there was never a conflict.

Since debug mode turns off optimizations, ESI is also not used, and thus no conflcit.

So its only newever versions of euphoria with more aggressive openwatcom optimizations that trigger the problem.

new topic     » goto parent     » topic index » view message » categorize

59. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

Then Why did my code work since euphoria version 2.2 all the way up to ver 4.0 SVN 1705 ????

You were lucky blink

Up until now, the Watcom compiler was not using ESI for anything important, but now (at least sometimes) Watcom has decided to use the ESI register for something, and assumes you are protecting it in your routine. Why is Watcom using the ESI? ... Don't know and don't care really. It is, and that's just the end of the matter as there is nothing efficiently we can do about it.

new topic     » goto parent     » topic index » view message » categorize

60. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

DerekParnell said...
bernie said...

Then Why did my code work since euphoria version 2.2 all the way up to ver 4.0 SVN 1705 ????

You were lucky blink

Up until now, the Watcom compiler was not using ESI for anything important, but now (at least sometimes) Watcom has decided to use the ESI register for something, and assumes you are protecting it in your routine. Why is Watcom using the ESI? ... Don't know and don't care really. It is, and that's just the end of the matter as there is nothing efficiently we can do about it.

Well I guess I will have to come up with a way to protect the registers automatically because I won't be able to be sure that the end user of my code always protects the registers.

Good luck on all the other compilers you are going to support. They will probably come up with a different way of optimizing and cause you more head aches.

new topic     » goto parent     » topic index » view message » categorize

61. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

Well I guess I will have to come up with a way to protect the registers automatically because I won't be able to be sure that the end user of my code always protects the registers.

Good luck on all the other compilers you are going to support. They will probably come up with a different way of optimizing and cause you more head aches.

bernie, do you even know how to program machine code?!

new topic     » goto parent     » topic index » view message » categorize

62. Re: ver 4.0 c_func problem on WIN98 Here Is proof of the problem !

bernie said...

Well I guess I will have to come up with a way to protect the registers automatically because I won't be able to be sure that the end user of my code always protects the registers.

What are you talking about?

Does your application allow arbitary user-written machine code to be executed? This is a potentially dangerous thing to do as it promotes virus writing etc...

In any case it is a simple thing to do. You just write a wrapper around your user's (dangerous) code that effectively does this ...

  • Save all registers (except EAX - EDX)
  • Call the code written by your users.
  • Restore all saved registers
bernie said...

Good luck on all the other compilers you are going to support. They will probably come up with a different way of optimizing and cause you more head aches.

This register convention is very common, if not universal. All compilers do it this way.

The golden rule for functions being called by code generated by any compiler is ... save all registers that the function uses and restore them on exit (apart from the EAX,EBX,ECX,EDX which can contain the return value).

new topic     » goto parent     » topic index » view message » categorize

63. Machine exceptions

I have been experiencing some unexplained machine exceptions when using c_func on XP. The thread of the message below primarily concerns Win98 but I get the impression that the problem is not confined to Win98.

jeremy said...
jimcbrown said...

I added some debug code to call_c() (nothing but printf()s) and suddenly the code is working correctly.

This sounds like an optimization bug.

I've had similar problems, I get a machine crash here or there, add a ? 0 and everything works. I try to reduce the program to a small test case and fail every time. It seems that if that happens, I just continue programming and the problem goes away itself. I've never had a good test case, maybe this is one Matt can track down?

Jeremy

Has anyone had these unexplained problems with systems other than Win98?

new topic     » goto parent     » topic index » view message » categorize

64. Re: Machine exceptions

LarryMiller said...

I have been experiencing some unexplained machine exceptions when using c_func on XP. The thread of the message below primarily concerns Win98 but I get the impression that the problem is not confined to Win98.

The bug described in the thread turned out to be the result of a bug in bernie's machine code. There was no problem with c_func() on 98 or any other OS.

Note that bernie was using c_func() to call custom machine code, instead of the more usual usage to call a C function in a dll.

LarryMiller said...
jeremy said...

I've had similar problems, I get a machine crash here or there, add a ? 0 and everything works. I try to reduce the program to a small test case and fail every time. It seems that if that happens, I just continue programming and the problem goes away itself. I've never had a good test case, maybe this is one Matt can track down?

Jeremy

Has anyone had these unexplained problems with systems other than Win98?

I do not think Jeremy is talking about 98 when he describes the above issue, as he does not have a 98 system to test out on.

new topic     » goto parent     » topic index » view message » categorize

65. Re: Machine exceptions

jimcbrown said...
LarryMiller said...

I have been experiencing some unexplained machine exceptions when using c_func on XP. The thread of the message below primarily concerns Win98 but I get the impression that the problem is not confined to Win98.

The bug described in the thread turned out to be the result of a bug in bernie's machine code. There was no problem with c_func() on 98 or any other OS.

Note that bernie was using c_func() to call custom machine code, instead of the more usual usage to call a C function in a dll.

I did not mean to discourage you from reporting your bug, I was simply stating that it was unlikely to be related to bernies.

Most of the time, getting a machine-level exception is a bug in Euphoria. If in doubt, report it as a bug.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu