andreas-kupries / critcl

Critcl lets you easily embed C code in Tcl. Online documentation at
http://andreas-kupries.github.io/critcl
Other
71 stars 19 forks source link

critcl 3.1.7 and 3.1.6 behave differently when used scripted and interactively respectively #26

Closed wtschueller closed 11 years ago

wtschueller commented 11 years ago

If I call the attached script using tclsh test.tcl I will get the error

Error in startup script

invalid command name "triple" while executing "triple 123" invoked from within "puts "three times 123 is [triple 123]"" (file "D:\Temp\critcl\test.tcl" line 8)

OK

There are linker errors about "...undefined reference to `tclStubsPtr'...".

However, if I start the tclsh interactively and copy and paste the contents of test.tcl then it will work as expected.

critcl 3.1.3 works as expected in both cases. I have ActiveState Tcl 8.5.12 and installed critcl via teacup. I have Mingw 4.6.2 in Win2k.

wtschueller commented 11 years ago

The report was send via e-mail first, and Andreas Kupries replied:

I suspect this was introduced by the bugfix for https://github.com/andreas-kupries/critcl/issues/21

as it is the only thing where I fiddled with the Tcl stubs parts of critcl recently. And it was first in the 3.1.6 release.

It is unclear why script vs interactive should be different. In both cases it should be the mode "compile & run". I will investigate further when I am back home.

It might be useful to check if the "critcl" application is affected. It should not be, for that was the case I tested with while working on the changes for #21.

andreas-kupries commented 11 years ago

Crud. Trying to reproduce the issue here I fail. As in, the system works fine.

I tried to be as near to your system as was possible. I have AT 8.5.12. I removed my local development versions of critcl, and the even older critcl 2. Installed critcl from teapot, it is 3.1.7. My system however is linux. My gcc is 4.5.2

I modified your test.tcl a bit, to show more information. You can see this script at the end of this comment. Note that I did this only after reproduction of your issue failed, so this should not be the cause of my builds being successful.

Looking at the data you supplied in the original zip file I noticed several interesting (weird?) things.

The v317script/v317.log seems to contain the log data of two builds. First one having the linker trouble, and a second which looks ok. Did you by chance try multiple times and did not clean the .cache directory ?

I notice that both builds use the same compiler (a mingw gcc I guess), and all options are the same. This should not be the trouble then. The md5sums in the name of the generated .c file are different, indicating different input, i.e different C code, and/or flags. Comparing the two generated .c files one difference is glaring. The 'script' generated variant is missing all the C code for the triple procedure, both user and generated support code. This is not something you can get by uncommenting the cproc in the .tcl file. Because in that case [triple] will not be registered with the auto_loader at all, and simply fail as unknown when invoked, without trying to invoke anything critcl-related.

That is a weirdness I will not be looking into now. It is definitely something I can't replicate here.

But now I was able to replicate one difference between script and interactive. (Saw that there was a stubs code difference, and tried the interactive approach here too). Interactive generates the stubs code, and script does not, and that has to be a #21 difference. Apparently , for interactive, does run a different code path where it still generates it.

And I suspect that the 'script' results works for me because of the gcc version 4.5.2 relatively recent, or simply because the linker works different for linux/elf than windows/COFF (I think it is COFF).

I will look into that.

Lastly, the modified test script I use.

# Clear old build state
file delete -force .cache

puts ===================================================
puts "\t[info nameofexecutable] [info patchlevel]"
puts "\tcritcl [package require critcl] = [package ifneeded critcl [package present critcl]]"
puts ===================================================

::critcl::cache .cache
::critcl::config force 1
::critcl::config keepsrc 1
critcl::cproc triple {int i} int {
   return i * 3;    /* this is C code */
}

parray auto_index *triple*

puts "three times 123 is [triple 123]"
exit
andreas-kupries commented 11 years ago

Tobias, please get the head of critcl/master from github, install it, and try if it fixes your problem.

wtschueller commented 11 years ago

Installed https://github.com/andreas-kupries/critcl/archive/896de233960f67c95d4cc3f0acf1699ecf41d64b.zip. Works as expected.

Also installed https://github.com/andreas-kupries/critcl/archive/7377798b4fe6d93c06e2129dbdc9257d13bd5493.zip and verified that that one still fails.

Issue resolved for me.

Some though about your investigations above.

I double checked the cache: there are two builds issued for a single run of the test script. They are only 3 seconds away.

The second run generates a dll, but I am not able to load it somehow. I get % load 317_scripted/v317_c34d5acf7d3383e4e2127b483b19367a.dll couldn't find procedure V_Init

my compiler is indeed MinGW: gcc --version gcc (GCC) 4.6.2

However, if there is wrongly generated c-code, then I will expect the issue in the generator.

Anyway, it works for me now. Thank your!

andreas-kupries commented 11 years ago

Glad to hear this. Closing.