jcurl / RJCP.DLL.SerialPortStream

SerialPortStream is an independent implementation of System.IO.Ports.SerialPort and SerialStream for better reliability and maintainability. Default branch is 2.x and now has support for Mono with help of a C library.
Microsoft Public License
624 stars 197 forks source link

segmentation fault on dotnetcore docker on ubuntu #80

Closed baywet closed 5 years ago

baywet commented 5 years ago

I'm currently trying to make the following scenario work:

When my container I get a segmentation fault on line SerialPortStream.GetPortNames(); Here is my dockerfile

FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get -y install cmake build-essential
RUN git clone https://github.com/jcurl/serialportstream.git
RUN cd serialportstream/dll/serialunix && ./build.sh
COPY ./myproject/ ./myproject/
RUN dotnet restore ./myproject/myproject.csproj

# Copy everything else and build
COPY . ./
RUN dotnet publish ./myproject/myproject.csproj -c Release -o out --no-restore

# Build runtime image
FROM microsoft/dotnet:2.1-runtime-alpine
WORKDIR /myproject
COPY --from=build-env /app/myproject/out .
COPY --from=build-env /app/serialportstream/dll/serialunix .
# COPY ./libs ./bin
ENV "LD_LIBRARY_PATH"="/mypoject/bin/usr/local/lib"
ENV "LD_DEBUG"="all"
ENTRYPOINT ["dotnet", "myproject.dll"]

content of the main method

Console.WriteLine("before ports");
var ports = SerialPortStream.GetPortNames();
Console.WriteLine("after ports");
docker build .
docker run -it --entrypoint /bin/sh <imageid>
dotnet myproject.dll

output

before port
Segmentation fault

I was wondering what I might be missing at this point?

jcurl commented 5 years ago

Hello, and thankyou for the problem report. The failure could be within the native library (libnserial.so). Do you have a core dump? I expect the problem to be part of the native compilation. I would also need the config.h file also, which describes how CMake compiled the program.

Are you using HEAD? There was a recent bugfix when searching for libraries on Linux through an incorrect usage of arrays/pointers shown here: https://github.com/jcurl/SerialPortStream/commit/11518d242092c77e4eb12ddb43c5520f8e22b62b

So please ensure you're using at least that commit (not yet released, hope to do so soon)

jcurl commented 5 years ago

It could also be helpful if you could run the unit test cases with gtest, especially the test case SerialPortList. That exercises this function which appears to be crashing.

baywet commented 5 years ago

Hey, Thanks for the quick answer. Here are all the files you requested (maybe a bit more), hopefully that helps. Something I'm not clear on: do I need to build the dotnet part (SerialPortStream) in the scenario I'm describing or using the latest nugget is fine? build.zip

baywet commented 5 years ago

As for the unit tests, I'm not very familiar with gtest, looked it up online and couldn't figure it out quickly. Do you mind sharing with me the command I need to run? If you can't that's ok, I'll do more research on my end. Thanks!

jcurl commented 5 years ago

Sure. you need to install libgtest on Ubuntu (apt install libgtest-dev). Then when you run build.sh it should see that gtest is there and compile the test suite.

Then it's a matter of going into the build artifacts and then running the test from there (unittests folder).

There are some specific gtest commands to run only that unit test, if you need it I can do it over the weekend.

baywet commented 5 years ago

Thanks for the additional information. Here is the result when I run sudo ./build.sh > ~/Desktop/build.log Let me know if you need anything else. build.log

jcurl commented 5 years ago

Thanks. The default tests run as part of build.sh do not run the test that I'm interested in. After building, you need to:

cd build/libnserial/comptest
./nserialporttest

Then it should crash, or pass.

when doing the tests, you do not need to recompile the .NET libraries.

If the test crashes, it would be helpful to get a copy of the binaries you compiled, along with the core dump. Then I can look into it via GDB.

baywet commented 5 years ago

Thanks for the follow up. Reading this: it says I need 2 serial ports to run the unit tests properly, which I don't have at the moment (I'll get some more on Tuesday or Wednesday. I hope it doesn't impact what you wanted to test at the moment? The test passed, please find attached the output of the console. Let me know if you need anything else and thanks again for your help! test.log

jcurl commented 5 years ago

The link is in general true, you need two serial ports. The specific test case nserialporttest doesn't need two ports, it just checks the API to get the list of ports (it never calls serial_open which would need a specific port).

The test case log is correct, it shows no available serial ports.. Is this true? Are the permissions correct in ls -l /dev/tty* so your user is in the correct group?

I would have hoped that if it crashes in your .NET program, it would crash here too where it's simpler to get a dump of what crashed.

alternatively, you can provide me the core dump and a copy of the libnserial.so binary (compiled with debug information, which is there if you used the build.sh script to compile) and a link to the commit you compiled against (so I can configure source level debugging).

baywet commented 5 years ago

Thanks for the follow up. In our environments we have multiple machines: machines that are used to build everything (code, images…) and machines that run the solution. Only the later one have the serial ports but they don't have any build tools installed at the moment. I could maybe try to install those build tools and run the tests there if it's necessary. In terms of binaries, is that what you're looking for or do you need something else? https://github.com/jcurl/SerialPortStream/files/2610715/build.zip

jcurl commented 5 years ago

Hello, you don't need build tools where the problem is occurring. All you need to provide are: 1) The core dump that is generated by the segmentation fault. I can use the core dump hopefully to get a backtrace when it crashes inside the method to get the list of ports 2) The libnserial.so binary that was used to cause the crash with debug symbols (usually compiled with GCC -g) 3) The name of the commit so I can check out the correct sources that match with the debugging information inside the libnserial.so binary you provide.

Generating the core dump might require a change on your linux system so that it is locally stored, and the ulimit option (on Linux) needs to be given to allow core dumps.

baywet commented 5 years ago

Thanks for the follow up and sorry for the huge delay in the response. We had to switch priorities around for strategic reasons. Because of other technical reasons, we decided to implement communication between our devices and edge another way. Closing.