Welcome! Please see the About page for a little more info on how this works.

0 votes
in ClojureCLR by
edited ago by

EDIT: Answer is YES. Below is my long-winded exploration.

I see one of the reasons for clojure-clr-next is it will work on more platforms, is Android one of those?

I'm using Termux to operate dotnet on Android.

Both the clojure-clr global dotnet tool and locally compiled clojure-clr fail with exit code 1, no exceptions or anything. I tried dotnet-trace and it gets a partial trace, but no minidump. Puzzling as with the partial trace, the documentation indicates an expectation of a minidump, maybe there is some unmet condition to emit the minidump I'm not aware of yet (env variables for it didn't work).

In the trace here is an early line followed by some of the last lines:
`
"system.linq!System.Linq.Enumerable.SelectManyS\ingleSelectorIterator\u003cSystem.Reflection.As\sembly,System.Type\u003e.MoveNext()"

[...]
"system.collections!System.Collections.Generic.\
SortedSet\u003cSystem.Collections.Generic.KeyVa\luePair\u003cSystem.Int32,clojure.lang.CljCompi\ler.Ast.FnMethod\u003e\u003e.AddIfNotPresent(Sy\stem.Collections.Generic.KeyValuePair`2\u003cin\t,

[...last line...]
"ManagedModule!System.Buffers.SharedArrayPool\u\003cSystem.Byte\u003e.Trim()"
`

So maybe something to do with reflection, or that SharedArrayPool?

I tried inserting some logging to Clojure.Main, but nothing logged as it appears to fail before CljMain.Main() is called. Possibly fails during setting up attributes on one of the classes, in one of the Symbol.intern() or RT.var() calls or somewhere else?

Couldn't run the dotnet msbuild build.proj -t:Test -p:TestTargetFramework=net8.0, fails with:
Clojure.Main -> /data/data/com.termux/files/home/dev/clojure-clr/Clojure/Clojure.Main/bin/Debug/net8.0/Clojure.Main.dll ClojureCompileAssets = '' ClojureMainAssets = '' ClojureTestsAssets = '' /data/data/com.termux/files/home/dev/clojure-clr/Clojure/build.proj(177,5): error MSB3073: The command "dotnet run --project /data/data/com.termux/files/home/dev/clojure-clr/Clojure/Clojure.Main --framework net8.0 -c Debug -p:TargetOS=linux-bionic -p:TargetPlatform=arm64 -p:TargetFramework=net8.0 -p:TargetFrameworks='net8.0' -- run_test.clj" exited with code 1.
I had to edit build.proj a bit to get custom -p:TargetFrameworks and such to pass through, but still fails with exit code 1.

Well I'll continue poking around in this uncharted territory.

by
Turns out error is piped via mono runtime to logcat on Android:
https://gist.github.com/rene-descartes2021/22b3ceca022a3a733e9388073b1b4c37

Excerpt:
05-14 16:28:45.631 29686 29686 E mono    : Unhandled Exception:                                 
05-14 16:28:45.631 29686 29686 E mono    : System.TypeInitializationException: The type initializer for 'Clojure.CljMain' threw an exception.   
05-14 16:28:45.631 29686 29686 E mono    :  ---> System.TypeInitializationException: The type initializer for 'clojure.lang.RT' threw an exception.                                             
05-14 16:28:45.631 29686 29686 E mono    :  ---> Syntax error compiling fn* at (clojure/core.clj:400:2).                                        
05-14 16:28:45.631 29686 29686 E mono    : Token 40001d0 is not valid in the scope of module Clojure.dll. (Parameter 'metadataToken')           
05-14 16:28:45.631 29686 29686 E mono    :    --- End of inner exception stack trace ---

Looking at core.clj in that spot is the first use of PersistentTreeMap. Looking elsewhere, greping for 'Token' and 'metadata' I guess the symbol is mapped to a uint for lookup later, somewhere in the code... Maybe a rule of thumb in that uint mapping doesn't hold on linux-bionic-arm64? Will try to comprehend that code later.

Going to try to run the nunit tests next on Csharp.Tests project, test if PersistentTreeMap doesn't work or something. 'dotnet test' didn't work, trying to find a nunit dotnet tool now, maybe that will work.
by
edited by
Ok got 'dotnet test' to work for Csharp.Tests project. Had to restore again as I'd purged the NuGet cache.

Here is command and log:
$ cd Csharp.Tests
$ dotnet test --no-build -v n -f net8.0 -c Debug

Log:
https://gist.github.com/rene-descartes2021/67fa819bf6ab96097a0c0da2d83484f8

214 failed tests, most all appear to be variants of two exceptions, excerpted here:

Failed BooleanSpecPrintsTrueOnTrue [2 ms]       
Error Message:                                   
NExpect.Exceptions.UnmetExpectationException : Expected                                      
"True"                                          
but got                                         
"true"                                          
values have different casing


Failed DefaultCtorReturnsEmptyMap [< 1 ms]      
Error Message:                                   
System.TypeInitializationException : The type initializer for 'clojure.lang.PersistentTreeMap' threw an exception.                           
----> System.TypeInitializationException : The type initializer for 'clojure.lang.RT' threw an exception.                                       
----> System.ArgumentException : An item with the same key has already been added. Key: Casing

I'll try to see what I can find out. dotnet on Android uses Android's libcrypto and libssl, not the embedded ones in dotnet or whatever... Something along those lines. Maybe the difference is due to that- seems one or the other are used when hashing strings.
by
Might also be due to the use of "Mono Core" in dotnet core, i.e. dotnet compiled with --use-mono-runtime, not the full Mono framework. I see clojure-clr treats mono specially in certain contexts, maybe the test for that special treatment isn't true for mono core when it should be? Just speculating.

Tried to read the code, don't know enough to know the flow of things. Going to try to compile netcoredbg for this platform and step through the area. Seems odd it throws in .MoveNext() of an enumerator. Tried to find the throw message in mono's code, found the string, but couldn't find the point it throws it with the "Casing" printf
 arg.

I should try regression analysis too... See if the tests pass in years past.
by
Sorry "Mono Core" probably wrong term. Maybe MonoVM is right one they use, code here:
https://github.com/dotnet/runtime/tree/main/src/mono

In Clojure/Clojure/Lib/RT.cs changing condition from "Mono.Runtime" to "Mono.ValueTuple" (something I could find that exists) as a test didn't result in improvement.

Glancing in dotnet/runtime and observing the exception is thrown in .MoveNext() I think the problem is likely in dotnet code and not in clojure-clr. I can't find the "Casing" key in either though, I really need to compile netcoredbg and figure out the context better.
ago by
Ok, I looked deeper in the stack in the Casing exception and found this area, I now see where that "Casing" key comes from:
https://github.com/clojure/clojure-clr/blob/9c015d0e014aa8aa49615dd256b860db3285c306/Clojure/Clojure/Lib/RT.cs#L42-L43

If I change it to this, remove the Casing Type, the relevant tests work and I'm able to launch and use Clojure.Main:
var q = GetAllTypesInNamespace("System").Where(x => x.Name != "Casing").ToList();

If I remove everything but the Casing Type, same tests fail with the duplicate Key: Casing exceptions!
var q = GetAllTypesInNamespace("System").Where(x => x.Name == "Casing").ToList();

So... that's a head scratcher. Why does ToDictionary() fail with that "Casing" key? I tried .Equals on each element .Name on that list, and no equality.

For reference here is the .FullName on that Casing Type:
System.HexConverter+Casing

Now to look and find out how exactly the keys are being compared... might not be the default... but even when it is the only element in the list it throws!? I will try additional tests/tinkering for now.
ago by
edited ago by
Well, I'm able to get a working Clojure.Main now! So I'll mark this as solved as I think the error is not in clojure-clr but in how dotnet core I used is built (a community built, non Microsoft), or some other dotnet area error.

So I guess there is lazy evaluation going on which puzzled me earlier. I'll try to narrow down a concise reproduction using the System.HexConverter+Casing type and file an issue where appropriate. I think? Why the duplicate key error though?

**EDIT:** might be when an unhandled failure occurs it tries adding it again? Well technical detail might be for Termux the rpath isn't set right for native libraries, a limitation of building dotnet currently from what I see in issues, maybe something like that. I'd expect a symbol not found or some such in that case though, who knows. I'll just wait on those issue(s) to get fixed before diving into this again if warranted.

Please log in or register to answer this question.

...