Beckhoff / ADS

Beckhoff protocol to communicate with TwinCAT devices.
MIT License
493 stars 194 forks source link

Uncaught exception #151

Closed Jopand closed 1 year ago

Jopand commented 2 years ago

https://github.com/Beckhoff/ADS/blob/e2bd6cb64f5f245e0fd17a0a08aad33fb0a57ef5/AdsLib/Sockets.cpp#L171

I'm making a program, that I want to be able to handle occational "hickups". If the PLC goes offline (or in config mode), this line will throw an exception. This exception is not caught, in AmsConnection::Write() (line 139), so I cannot prevent a crash. Could you please consider adding a try-catch ?

pbruenn commented 2 years ago

Are you sure you linked the right lines?

Jopand commented 2 years ago

That's whats my stacktrace tells me. In AmsConnection.cpp socket.write is called: https://github.com/Beckhoff/ADS/blob/7371018bee5c3932707fcefde1c546bdee0f3f51/AdsLib/standalone/AmsConnection.cpp#L139

The write method throws a std::runtime_error here: https://github.com/Beckhoff/ADS/blob/7371018bee5c3932707fcefde1c546bdee0f3f51/AdsLib/Sockets.cpp#L171

To reproduce it I succesfully created a connection in my linux program, rebooted the plc and then tried to write a variable on the plc

Jopand commented 2 years ago

image

pbruenn commented 2 years ago

Well, okay I am a bit surprised you get a std::runtime_error from a libc call. The idea behind exceptions in AdsLib is you can propagate the error easily to a place where you can handle it gracefully. The problem with a disconnected PLC is, you would have to terminate the AmsConnection and reconnect it again. So the exception should be caught somewhere you can call bhf::ads::DelLocalRoute()to remove the old AmsConnection and call bhf::ads::AddLocalRoute() again, to try reestablishing the TCP connection.

Jopand commented 2 years ago

I might be wrong regarding the std::runtime_error (tried to catch such an error without luck). But doing as I described will result in an inevitable crash of my application

Jopand commented 2 years ago

But how do I detect a disconnect? I see a printout: "Info: connection closed by remote"...

pbruenn commented 2 years ago

For example by catching that std::runtime_error when you attempt to write or read? e.g. in AdsParameterWriter::OnWriteparameter?

Jopand commented 2 years ago

I cannot save it: image

Jopand commented 2 years ago

Do you have a solution for this? Am I doing something wrong (so we can close the issue), or is this something you can fix?

pbruenn commented 2 years ago

Well, you throw totally unrelated things together. You start with a socket exception and now you show a symbol not found error. I really don't know how to help you. The thing about closing TCP connections is a known limitation and pretty annoying, I know. However, connection handling is out of scope for this library at the moment.

Jopand commented 2 years ago

Where do you see a symbol not found exception? I try to write a variable, that doesn't exist. It gives an error 1808, which is not a problem. Then I disconnect the plc and try the same thing again. Then it explodes and seems to be impossible to save.

Jopand commented 2 years ago

We are relying heavily on this library in my company (Marel), so if you just drop the ball here, we might have to consider other options

marcus-sonestedt commented 2 years ago

@Jopand Maybe you're getting a SIGPIPE (check the 'debug console' tab in vscode) ?

That can be handled via global signal handlers in unix, but those are far from my expertise.

I am seeing some similar things, but I don't know how much is related to your issue. I am reading/writing vars from different threads using the same AdsDevice, so I'm getting both "port 30000 already in use" and "no dispatcher found for notification" all the time.

(I am running TwinCAT in a Windows VM which works for a while, then it locks up with a lot of CPU usage and I have to hard-reset it.)

FYI @pbruenn, I just wanted to give @Jopand a tip. I'll try to figure out what I'm doing before I ask for help about it :) . (We inherited a multithreaded application that used a serial port before, but we use ADS against the new system.. )

DimitarVelickovski commented 2 years ago

Hi @Jopand, you can take a look at this thread #113. We have a similar problem reconnecting to the PLC when PLC goes in Config and then back to Run mode. The first thing we tried was catching the exceptions.

pbruenn commented 1 year ago

closed as a duplicate of https://github.com/Beckhoff/ADS/issues/113