microsoft / vs-streamjsonrpc

The StreamJsonRpc library offers JSON-RPC 2.0 over any .NET Stream, WebSocket, or Pipe. With bonus support for request cancellation, client proxy generation, and more.
Other
756 stars 151 forks source link

Crash on Android 11 devices when throwing RemoteInvocationException #914

Closed mmoraga closed 1 year ago

mmoraga commented 1 year ago

I've only seen this on Android 11. When throwing any kind of RemoteInvocationException, dotnet will crash with:

[libc] Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xbba025e0 in tid 11214 (.NET ThreadPool), pid 11138 (android_jsonrpc)

The expected result is for jsonrpc to send a json-rpc error.

Reproduction project is here: https://github.com/mmoraga/android-jsonrpc

AArnott commented 1 year ago

The expected result is for jsonrpc to send a json-rpc error.

I imagine that's what is happening, since it is receiving that error message that leads StreamJsonRpc to throw a RemoteInvocationException in the first place.

https://github.com/microsoft/vs-streamjsonrpc/blob/3c538973e8e7e6e4efd5c76b1d731dcfbb165e9a/src/StreamJsonRpc/JsonRpc.cs#L1364-L1386

I have no idea why mono on Android would crash when we throw this custom exception type. We don't use nor officially support this library on Android. If you find the root cause and can explain the change we need to make or can send a PR, we may merge the fix. But my guess given this works everywhere else is that this is somehow a bug in mono that needs to be filed against them.

Please feel free to continue the discussion here on this issue, but I'm closing it as I don't expect anything is actionable on our end at this point.

AArnott commented 1 year ago

BTW, as you see the code snippet I referenced above is a virtual method, if you believe the crash is due to the particular type of exception thrown, you could override the method and have it return a different exception to see if that helps you workaround the problem.

mmoraga commented 1 year ago

Well, the issue is on the server side: when the server throws a RemoteInvocationException the whole .NET crashes. If you look at https://github.com/mmoraga/android-jsonrpc/blob/main/GreeterServer.cs I set the server to always throw so I could reproduce the crash. Note that the app where I spotted the issue in the first place only had a jsonrpc server running.

AArnott commented 1 year ago

Well, that's weird. StreamJsonRpc catches all exceptions thrown by the server method and translates them into a JSON-RPC error message. I don't know why mono on Android would crash instead. Sorry.

mmoraga commented 1 year ago

I guess this method is what's translating the exception to the JsonError.ErrorDetail https://github.com/microsoft/vs-streamjsonrpc/blob/3c538973e8e7e6e4efd5c76b1d731dcfbb165e9a/src/StreamJsonRpc/JsonRpc.cs#L1336 And could be something with serialisation causing the crash.

Do you have any suggestions for narrowing the issue down a bit more than that before I open an issue with dotnet? Just saying 'I throw an exception and it crashes' isn't very helpful.

AArnott commented 1 year ago

A heap dump would probably be helpful to them. And I wouldn't send it to the dotnet team unless they own mono too. I know Microsoft owns mono, but I'm not sure about the dotnet/runtime repo being the right place to file mono bugs.

If serialization were causing the crash, I expect you would just see another exception about serialization failing rather than a native crash, but I don't know. I can't really give great tips because I don't use mono.

gkarabin commented 1 year ago

@mmoraga - For what it's worth, I ran your sample app on an Android 11 device. It's not crashing for me - logcat shows the expected messaging from the client side, and the "Hello, Android!" label is present on my screen.

2025:05-24 12:22:44.017 13826 13856 I android_jsonrpc: Starting server.
2051:05-24 12:22:44.240 13826 13856 I android_jsonrpc: start listening to rpc stuff
2052:05-24 12:22:44.241 13826 13856 I android_jsonrpc: Try sending message.
2090:05-24 12:22:44.875 13826 13862 I android_jsonrpc: Error in rpc communication: StreamJsonRpc.RemoteInvocationException: Everything went unexpected.
2091:05-24 12:22:44.875 13826 13862 I android_jsonrpc:    at StreamJsonRpc.JsonRpc.<InvokeCoreAsync>d__145`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
2092:05-24 12:22:44.875 13826 13862 I android_jsonrpc:    at android_jsonrpc.MainActivity.RpcConnectionAsync()
2093:05-24 12:22:44.875 13826 13862 I android_jsonrpc: RPC server exception:
2094:05-24 12:22:44.875 13826 13862 I android_jsonrpc: StreamJsonRpc.RemoteInvocationException: Everything went unexpected.
2095:05-24 12:22:44.875 13826 13862 I android_jsonrpc:       at android_jsonrpc.GreeterServer.SayHelloAsync(String name)
2096:05-24 12:22:44.875 13826 13862 I android_jsonrpc:       at System.Reflection.MethodInvoker.InterpretedInvoke(Object obj, Span`1 args, BindingFlags invokeAttr)

I'm using version 7.0.302 of the SDK to run from the command line, on an Android 11 device:

% adb shell getprop ro.build.version.release 11

mmoraga commented 1 year ago

@gkarabin do you know which device? I haven't been able to reproduce this crash in an emulator, only on some physical android devices. The common denominator has been that they all use ARM Cortex-A53 CPUs - although that could be a red herring.

gkarabin commented 1 year ago

It’s a Honeywell CT-45. It’s using the A53 as well. I was deploying your app via the debugger (debug builds only) if that matters. (sorry, it was via command line as noted above!)

I’ll be testing on more device varieties in the coming days. If I learn anything I’ll note it.