Can't process quickfix messages written in file - quickfix

In my C++ QuickFix application, I am recording all MarketDataIncrementalRefresh messages i am getting into a file. This is being done using the following code:
void Application::onMessage(const FIX44::MarketDataIncrementalRefresh& message, const FIX::SessionID&)
{
ofstream myfile("tapedol.txt", std::ios::app);
myfile << message << endl << endl;
}
This part's working just fine. The problem occurs when I try to load the message later on.
FIX::Message msg
ifstream myfile("tapedol.txt");
getline(myfile,aux);
msg = aux;
msg.getField(55);
The program crashes every time it executes the last line. I suspect the problem is at the assignment to msg, but i'm not sure. If it is, what is the correct way to do such assignment? If not, how can I process the data within tapedol.txt, so that a message of type MarketDataIncremental refresh would be generated for each string in the file?

Your question is not complete enough to provide a full answer, but I do see one red flag:
msg.getField(55);
The Symbol field is not a top-level field of MarketDataIncrementalRefresh (it's inside the NoMDEntries repeating group), so this line will fail. I think it would raise a FieldNotFound exception.
My C++ is rusty, but you should be able to catch an exception or something that should tell you exactly what line is erroring out. Barring that, you need to open up a debugger. Just saying "it crashed" means you quit looking too soon.

Related

Boost Asio tcp::iostream construction raise an Access Violation Exception on every second use

I am trying to use the implementation of std::iostream provided by boost::asio on top of boost::asio::ip::tcp::socket. My code replicate almost line to line the example that is published in Boost Asio's documentation:
#include <iostream>
#include <stdexcept>
#include <boost/asio.hpp>
int main()
{
using boost::asio::ip::tcp;
try
{
boost::asio::io_service io_service;
tcp::endpoint endpoint(tcp::v4(), 8000);
tcp::acceptor acceptor(io_service, endpoint);
for (;;)
{
tcp::iostream stream; // <-- The exception is triggered on this line, on the second loop iteration.
boost::system::error_code error_code;
acceptor.accept(*stream.rdbuf(), error_code);
std::cout << stream.rdbuf() << std::flush;
}
}
catch (std::exception& exception)
{
std::cerr << exception.what() << std::endl;
}
return 0;
}
The only difference is the use I make of the resulting tcp::iostream: I forward everything I receive to the standard output.
When I compile this code with VisualStudio2019/toolset v142 and Boost from the NuGet boost-vc142, I get an Access Violation Exception only in the second iteration in the for loop, in the function
template <typename Service>
Service& service_registry::use_service(io_context& owner)
{
execution_context::service::key key;
init_key<Service>(key, 0);
factory_type factory = &service_registry::create<Service, io_context>;
return *static_cast<Service*>(do_use_service(key, factory, &owner));
} // <-- The debugger show the exception was raised on this line
in asio/detail/impl/service_registry.hpp. So the first iteration everything goes as planned, the connection is accepted, the data shows up on the standard output, and as soon as the stream is instanciated on the stack for the second time, the exception pops.
I don't have a high confidence in the accuracy of this location of the exception reported by the debugger. For some reason, the stack seams to be messed up and show only one frame.
If the declaration of stream is moved out of the loop, no exception is raised any more but then I need to stream.close() at the end of the loop, or nothing shows up on the standard output except the data from the first client's connection.
Basically, as soon as I try to instanciate more than one boost::asio::tcp::iostream (not necessarily at the same time), the exception is raised.
I tried the exact same code under linux (Arch linux, latest version of g++, same version of Boost) and everything works perfectly.
I could work around this issue by not using iostreams, but my idea is to feed the data received on the tcp socket to a parser which only accept implementations of std::iostream, hence I would still need to wrap asio's tcp socket in an homebrewed (and mediocre) implementation of std::iostream.
Does anybody have an idea on what's wrong with this setup, if I missed a crucial #define somewhere or anything?
Update:
Subsequent investigation show that the only situation where the access violation happens is when the executable is run from within Visual Studio (typ. from the menu Debug -> Start Debugging).
The build process seems to have no effect (calling directly cl.exe, using MSBuild, using devenv.exe).
Moreover, if the executable is run from a command prompt, and only then the debugger is attached, no access violation happens.
At this point, the issue is most likely not linked to the code itself.
Okay, it was exceedingly painful to test this on windows.
Of course I first tried on Linux (clang/gcc) and MingW 8.1 on windows.
Then I bit the bullet and jumped the hoops to get MSVC in command line with boost packages¹.
I cheated by manually copying the .lib/.dll for boost_{system,date_time,regex} into the working directory so the command line stayed "wieldy":
C:\work>C:\Users\sghee\Downloads\nuget.exe install boost_system-vc142
C:\work>C:\Users\sghee\Downloads\nuget.exe install boost_date_time-vc142
C:\work>C:\Users\sghee\Downloads\nuget.exe install boost_regex-vc142
(Be sure to get some coffee during those)
C:\work\> cl /EHsc test.cpp /I .\boost.1.72.0.0\lib\native\include /link
Now I can run test.exe
C:\work\> test.exe
And it listens fine, accepts connections (sequentially, not simultaneously). If you connect a second client while the first is still connected, it will be queued and be accepted only after the first disconnects. That's fine, because it's what you expect with the synchronous accept and loop.
I used Ncat.exe (from Nmap) to connect:
C:\Program Files (x86)\Nmap>.\ncat.exe localhost 8000
Quirk: The buffering was fine with the MSVC cl.exe build (linewise) as opposed to MingW behaviour, even though MingW also uses ws2_32.dll. #trivia
I know this doesn't "help", but maybe you can compare notes and see what is different with your system.
Video Of Test
¹ (that's a tough job without VS and also I - obviously - ran out of space, because 50GiB for a VM can't be enough right)

Opencascade crash when calling calling Transfer()

I have tested two cases:
I use STEPCAFControl_Reader then STEPControl_Reader to read my step file but both methods crash when I call STEPCAFControl_Reader::Transfer, repsectively STEPControl_Reader:: TransferRoots.
By using STEPControl_Reader, I displayed a log on my console, then there is a message like this:
1 F:(BOUNDED_SURFACE,B_SPLINE_SURFACE,B_SPLINE_SURFACE_WITH_KNOTS,GEOMETRIC_REPRESENTATION_ITEM,RATIONAL_B_SPLINE_SURFACE,REPRESENTATION_ITEM,SURFACE): Count of Parameters is not 1 for representation_item
EDIT:
There is a null reference inside TransferRoots() method.
const Handle(Transfer_TransientProcess) &proc = thesession->TransferReader()->TransientProcess();
if (proc->GetProgress().IsNull())
{
//This condition does not exist from the source code
std::cout << "GetProgress is null" << std::endl;
return 0;
}
Message_ProgressSentry PS ( proc->GetProgress(), "Root", 0, nb, 1 );
My app and FreeCAD crash but if I use CAD Assitant which OCC official viewer, it loads.
It looks like comments already provide an answer to the question - or more precisely answers:
STEPCAFControl_Reader::ReadFile() returns reading status, which should be checked before calling STEPCAFControl_Reader::Transfer().
Normally, it is a good practice to put OCCT algorithm into try/catch block and check for OCCT exceptions (Standard_Failure).
Add OCC_CATCH_SIGNALS at the beginning of try statements (required only on Linux) and OSD::SetSignal(false) within working thread creation to redirect abnormal cases (access violation, NULL dereference and others) to C++ exceptions (OSD_Signal which is subclass of Standard_Failure). This may conflict other signal handlers in mixed environment - so check also documentation of other frameworks used by application.
If you catch failures like NULL dereference on calling OCCT algorithm with valid arguments - this is a bug in OCCT which is desirable to be fixed in one or another way, even if input STEP file contains syntax/logical errors triggering such kind of issues. Report the issue on OCCT Bugtracker with sufficient information for reproducing bug, including sample files - it is not helpful to developers just saying that OCCT crashes somewhere. Consider also contributing into this open source project by debugging OCCT code and suggesting patches.
Check STEP file reading log for possible errors in the file itself. Consider reporting an issue to system producing a broken file, even if main file content can be loaded by STEP readers.
It is a common practice to use OSD::SetSignal() within OCCT-based applications (like CAD Assistant) to improve their robustness on non-fatal errors in application/OCCT code. It is more user friendly reporting an internal error message instead of silently crashing.
But it should be noted, that OSD::SetSignal() doesn't guarantee application not being crashed nor that application can work properly after catching such failure - due to asynchronous nature of some signals, the memory can be already corrupted at the moment, when C++ exception has been raised leading to all kinds of undesired behavior. For that reason, it is better not ignoring such kind of exceptions, even if it looks like application works fine with them.
OSD::SetSignal(false); // should be called ones at application startup
STEPCAFControl_Reader aReader;
try
{
OCC_CATCH_SIGNALS // necessary for redirecting signals on Linux
if (aReader.ReadFile (theFilePath) != IFSelect_RetDone) { return false; }
if (!aReader.Transfer (myXdeDoc)) { return false; }
}
catch (Standard_Failure const& theFailure)
{
std::cerr << "STEP import failed: " << theFailure.GetMessageString() << "\n";
return false;
}
return true;

Printing failure message in a try else block

I have a code block like this.
try {
gen <object> keeping { <constraints>};
} else {
error(Failed to generate){
out(<additional debug information>);
};
};
I would like to have Specman print out the regular debug message from a gen failure along with my additional debug information. Any way to do this?
If by "regular debug message" you mean the message generated by Specman when encountering a generation failure, then no, you can't print this message and your own custom message. This is the whole point of a try block, to eat up any errors and to replace them with a custom response.
If you need to know more about this, you might want to check out the reflection classes rf_constraint and rf_constraint_layer. You can use them to see whether a constraint is satisfied before you actually do generation (and possibly get an error).

How to trace error message in libav

I'm writing a simple program to decode any input audio file into pcm16/mono/wav file, using libav. Or, I supposed it was simple.
After struggling a lot, reading lots of sample code (like avconv/avplay), I've managed to code something that should work.
However, it's not working. The demuxing/decoding parts seems to work fine, but the encoding part failed with the following message:
mathematics.c:61: av_rescale_rnd: Assertion `c > 0' failed.
Here is the code extract:
printf("Fill Frame\n");
avcodec_fill_audio_frame(oframe, _oCodecCtx->channels, _oCodecCtx->sample_fmt, frame->data[0], frame->linesize[0], 0);
printf("Frame filled\n");
ret = avcodec_encode_audio2(_oCodecCtx, &opkt, oframe, &got_packet);
if (ret < 0) {
printf("Error encoding audio frame\n");
return 1;
}
"Fill Frame" And "Frame filled" are displayed before the error appears. So, I think its thrown by avcodec_encode_audio2. However, this function doesn't call av_rescale_rnd in its source code.
So here is the question: is there a way to know who called this function, without modifying/recompiling libav source code?

QuickFIX: Load a message from the logs

I am building a tool to replay logs. Manually parsing the logs is annoying, so I'm wondering if there is a way to simply load a message from the log.
Also, I am not against just using a third-party replay tool if one exists.
First read the log file by any mean you want, getting the individual lines (there is one message per line).
Then build a Data Dictionary:
// Use the version of the XML dictionary that is right for you
FIX::DataDictionary dd("FIX44.XML");
Then, for each line (as std::string str), build a message:
FIX::Message msg(str, dd, false);
Finally, handle the message just like your FIX::Application does, or better, call
yourFixApplication.fromApp(msg, mySessionID);
ValidFIX Log analyzer is an online log parser that makes a good job:
http://www.validfix.com/fix-log-analyzer.html