Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 days ago.
Improve this question
i am trying to make a program in ns3 with OLSR protocol to drop a packet with 1024bytes size when energy of the node under 500j.but when i tried to compile in 1000s, i got a problem "free(): double free detected in tcache 2 when the node send package 1024 bytes and the energy hit under 500j. Here's the code what i am trying to modify in routeinput method file olsr-routing-protocol.cc in ns3
bool RoutingProtocol::RouteInput (Ptr<const Packet> p,
const Ipv4Header &header, Ptr<const NetDevice> idev,
UnicastForwardCallback ucb, MulticastForwardCallback mcb,
LocalDeliverCallback lcb, ErrorCallback ecb)
{
NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination ());
/**/ //rekayasa
std::string deviceName = idev->GetInstanceTypeId ().GetName ();
Ptr<Node> node = m_ipv4->GetObject<Node> ();
Ptr<EnergySourceContainer> energysourcecont = (node)->GetObject<EnergySourceContainer> ();
Ptr<EnergySource> source = energysourcecont->Get(0);
NS_ASSERT(node !=NULL);
NS_LOG_LOGIC (node << " nodes "
<<node->GetId() << " "
<< energysourcecont->Get(0) << " "
<< source->GetRemainingEnergy() << " = "
<< "\n"
);
/**/
Ipv4Address dst = header.GetDestination ();
Ipv4Address origin = header.GetSource ();
// Consume self-originated packets
if (IsMyOwnAddress (origin) == true)
{
return true;
}
// Local delivery
NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
if (m_ipv4->IsDestinationAddress (dst, iif))
{
if (!lcb.IsNull ())
{
NS_LOG_LOGIC ("Local delivery to " << dst);
if (source->GetRemainingEnergy() > 500.0){
NS_LOG_LOGIC("ENERGY > 500, deliver" << " size payload = "<< p->GetSize() << " id packet= " << p->GetUid() << " Node: " <<node->GetId() << " Energy: " <<source->GetRemainingEnergy() << " from: " << origin << " to: " << dst );
lcb (p, header, iif);
}
else if (source->GetRemainingEnergy()<= 500.0){
if((p->GetSize() - 8) == 1024){
NS_LOG_LOGIC("ENERGY < 500, not deliver " << " size payload = "<< p->GetSize() << " id packet= " << p->GetUid() << " Node: " <<node->GetId() << " Energy: " <<source->GetRemainingEnergy());
}
else{
NS_LOG_LOGIC("ENERGY < 500, deliver " << " size payload = "<< p->GetSize() << " id packet= " << p->GetUid() << " Node: " <<node->GetId() << " Energy: " <<source->GetRemainingEnergy() << " from: " << origin << " to: " << dst );
lcb (p, header, iif);
}
}
return true;
}
else
{
// The local delivery callback is null. This may be a multicast
// or broadcast packet, so return false so that another
// multicast routing protocol can handle it. It should be possible
// to extend this to explicitly check whether it is a unicast
// packet, and invoke the error callback if so
NS_LOG_LOGIC ("Null local delivery callback");
return false;
}
}
NS_LOG_LOGIC ("Forward packet");
// Forwarding
Ptr<Ipv4Route> rtentry;
RoutingTableEntry entry1, entry2;
if (Lookup (header.GetDestination (), entry1))
{
bool foundSendEntry = FindSendEntry (entry1, entry2);
if (!foundSendEntry)
{
NS_FATAL_ERROR ("FindSendEntry failure");
}
rtentry = Create<Ipv4Route> ();
rtentry->SetDestination (header.GetDestination ());
uint32_t interfaceIdx = entry2.interface;
// the source address is the interface address that matches
// the destination address (when multiple are present on the
// outgoing interface, one is selected via scoping rules)
NS_ASSERT (m_ipv4);
uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
NS_ASSERT (numOifAddresses > 0);
Ipv4InterfaceAddress ifAddr;
if (numOifAddresses == 1)
{
ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
}
else
{
/// \todo Implement IP aliasing and OLSR
NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
}
rtentry->SetSource (ifAddr.GetLocal ());
rtentry->SetGateway (entry2.nextAddr);
rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
NS_LOG_DEBUG ("Olsr node " << m_mainAddress
<< ": RouteInput for dest=" << header.GetDestination ()
<< " --> nextHop=" << entry2.nextAddr
<< " interface=" << entry2.interface);
if (source->GetRemainingEnergy() > 500.0){
NS_LOG_LOGIC("PACKET FORWARD" << " size payload = "<< p->GetSize() << " id packet= " << p->GetUid() <<" Node: " <<node->GetId() << " Energy: " <<source->GetRemainingEnergy());
ucb (rtentry,p,header);
return true;
}
else if(source->GetRemainingEnergy()<= 500.0){
if((p->GetSize()- 8) == 1024){
NS_LOG_LOGIC("DROP PACKET FORWARD "<< p->GetSize() << " " << p->GetUid()<< " Node: " <<node->GetId() << " Energy: " <<source->GetRemainingEnergy()
);
}
else {
NS_LOG_LOGIC("PACKET FORWARD "<< p->GetSize() << " " << p->GetUid()<<
" Node: " <<node->GetId() << " Energy: " <<source->GetRemainingEnergy()
);
ucb (rtentry,p,header);
return true;
}
}
}
else
{
NS_LOG_LOGIC ("No dynamic route, check network routes");
if (m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
{
return true;
}
else
{
#ifdef NS3_LOG_ENABLE
NS_LOG_DEBUG ("Olsr node " << m_mainAddress
<< ": RouteInput for dest=" << header.GetDestination ()
<< " --> NOT FOUND; ** Dumping routing table...");
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
iter != m_table.end (); iter++)
{
NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
<< " via interface " << iter->second.interface);
}
NS_LOG_DEBUG ("** Routing table dump end.");
#endif // NS3_LOG_ENABLE
return false;
}
}
}
Related
I'm currently having an issue with a function call of get_set() for a doubly-linked list class I am making. The function returns a vector of all the elements within the list from position_from to position_to. For the tests I am sending
dll_UT->get_set( dll_UT->size()/2+1 , dll_UT->size()-1)
however, the value of dll_UT->size() somehow doubles within the call. When called directly before in my COUT statement, it shows the correct value of 100, but when inside the function this turns to 200. I've left console logs below as well as screenshots of the test.cpp and doubly_linked_list.cpp.
Any help on this is greatly appreciated as I've never seen this type of behavior before and would like to understand why such a thing is occuring.
Doubly_linked_list get_set(unsigned position_from, unsigned_position to){
std::cout << "\n\t__NEW TEST__\nSize of size/2+1 = " << this->size()/2+1 << "\nSize of size()-1 = " << this->size()-1 << std::endl;
std::cout << "position_from = " << position_from << "\nposition_to = " << position_to << std::endl;
//value of position_from == 200, should be == this->size()/2+1 which = 100
std::vector<int> temp;
temp.reserve(position_to - position_from);
while(position_from < position_to){
temp.push_back( this->get_data(position_from) );
position_from++;
}
temp.push_back(this->get_data(position_to));
std::cout << "Size of position_from = " << position_from << "\nSize of position_to = " << position_to << "\n\t__END TEST__" << std::endl;
return temp;```
}
Test.cpp {
```std::cout << "\nTEST.cpp::: dll_UT-size() = " << dll_UT->size() <<
"\nTEST.cpp::: dll_UT-size()/2+1 = " << dll_UT->size()/2+1 << std::endl;
//assuring dll_UT->size()/2+1 = 100
std::cout << "\nTEST.cpp::: expected_set.size() = " << expected_set.size() <<
"\nTEST.cpp::: expected_set.begin()+expected_set.size()/2+1 = " << expected_set.size()/2+1 << std::endl;
ASSERT_EQ(std::vector<int> (expected_set.begin()+expected_set.size()/2+1,expected_set.end()),
dll_UT->get_set( dll_UT->size()/2+1 , dll_UT->size()-1));//second half of data
// ^first operand doubled, ^second operand fine
//actually value sent is 200. dll_UT->size() is somehow doubling and equaling 400 but only for first operand of get_set(unsigned, unsigned)
Updated Caputre
I am new to ZeroMQ.
I have multiple publishers and one client. Seeking suggestions to implement it in a best way.
Currently its making use of a reply - request pattern for a single client and a server; this has to be extended to multiple publishers and a single subscriber.
This application is going to run on a QNX-system that does not support C11, so zmq::multipart_t is not helping.
void TransportLayer::Init()
{
socket.bind( "tcp://*:5555" );
}
void TransportLayer::Receive()
{
while ( true ) {
zmq::message_t request;
string protoBuf;
socket.recv( &request );
uint16_t id = *( (uint16_t*)request.data() );
protoBuf = std::string( static_cast<char*>( request.data()
+ sizeof( uint16_t )
),
request.size() - sizeof( uint16_t )
);
InterfaceLayer::getInstance()->ParseProtoBufTable( protoBuf );
}
Send();
usleep( 1 );
}
void TransportLayer::Send()
{
zmq::message_t reply( 1 );
memcpy( reply.data(), "#", 1 );
socket.send( reply );
}
This is the code that I had written, this was initially designed to listen to only one client, now I have to extend it to listen to multiple clients.
I tried using zmq::multipart_t but this requires C11 support but the QNX-version we are using does not support C11.
I tried implementing the proposed solution.
I created 2 publishers connecting to same static location.
Observation :
I )
Execution Order :
1. Started Subscriber2. Started Publisher1 ( it published only one data value )
Subscriber missed to receive this data.
II )modified Publisher1 to send the same data in a while loop
Execution Order :
1. Started Subscriber2. Started Publisher13. Started Publsiher2.
Now I see that the Subscriber is receiving the data from both publishers.
This gives me an indication that there is a possibility for data loss.
How do I ensure there is absolutely no data loss?
Here is my source code :
Publisher 2 :
dummyFrontEnd::dummyFrontEnd():context(1),socket(context,ZMQ_PUB) {
}
void dummyFrontEnd::Init()
{
socket.connect("tcp://127.0.0.1:5555");
cout << "Connecting .... " << endl;
}
void dummyFrontEnd::SendData() {
while ( std::getline(file, line_str) ) {
std::stringstream ss(line_str);
std::string direction;
double tdiff;
int i, _1939, pgn, priority, source, length, data[8];
char J, p, _0, dash, d;
ss >> tdiff >> i >> J >> _1939 >> pgn >> p >> priority >> _0 >> source
>> dash >> direction >> d >> length >> data[0] >> data[1] >> data[2]
>> data[3] >> data[4] >> data[5] >> data[6] >> data[7];
timestamp += tdiff;
while ( gcl_get_time_ms() - start_time <
uint64_t(timestamp * 1000.0) - first_time ) { usleep(1); }
if (arguments.verbose) {
std::cout << timestamp << " " << i << " " << J << " " << _1939 << " "
<< pgn << " " << p << " " << priority << " " << _0 << " " << source
<< " " << dash << " " << direction << " " << d << " " << length
<< " " << data[0] << " " << data[1] << " " << data[2] << " "
<< data[3] << " " << data[4] << " " << data[5] << " " << data[6]
<< " " << data[7] << std::endl;
}
uint64_t timestamp_ms = (uint64_t)(timestamp * 1000.0);
protoTable.add_columnvalues(uint64ToString(timestamp_ms)); /* timestamp */
protoTable.add_columnvalues(intToString(pgn)); /* PGN */
protoTable.add_columnvalues(intToString(priority)); /* Priority */
protoTable.add_columnvalues(intToString(source)); /* Source */
protoTable.add_columnvalues(direction); /* Direction */
protoTable.add_columnvalues(intToString(length)); /* Length */
protoTable.add_columnvalues(intToString(data[0])); /* data1 */
protoTable.add_columnvalues(intToString(data[1])); /* data2 */
protoTable.add_columnvalues(intToString(data[2])); /* data3 */
protoTable.add_columnvalues(intToString(data[3])); /* data4 */
protoTable.add_columnvalues(intToString(data[4])); /* data5 */
protoTable.add_columnvalues(intToString(data[5])); /* data6 */
protoTable.add_columnvalues(intToString(data[6])); /* data7 */
protoTable.add_columnvalues(intToString(data[7])); /* data8 */
zmq::message_t create_values(protoTable.ByteSizeLong()+sizeof(uint16_t));
*((uint16_t*)create_values.data()) = TABLEMSG_ID; // ID
protoTable.SerializeToArray(create_values.data()+sizeof(uint16_t), protoTable.ByteSizeLong());
socket.send(create_values);
protoTable.clear_columnvalues();
usleep(1);
}
}
Publisher 1 :
dummyFrontEnd::dummyFrontEnd():context(1),socket(context,ZMQ_PUB) {
}
void dummyFrontEnd::Init()
{
socket.connect("tcp://127.0.0.1:5555");
cout << "Connecting .... " << endl;
}
void dummyFrontEnd::SendData()
{
cout << "In SendData" << endl;
while(1) {
canlogreq canLogObj = canlogreq::default_instance();
canLogObj.set_fromhours(11);
canLogObj.set_fromminutes(7);
canLogObj.set_fromseconds(2);
canLogObj.set_fromday(16);
canLogObj.set_frommonth(5);
canLogObj.set_fromyear(2020);
canLogObj.set_tohours(12);
canLogObj.set_tominutes(7);
canLogObj.set_toseconds(4);
canLogObj.set_today(17);
canLogObj.set_tomonth(5);
canLogObj.set_toyear(2020);
zmq::message_t logsnippetmsg(canLogObj.ByteSizeLong() + sizeof(uint16_t));
*((uint16_t*)logsnippetmsg.data()) = 20;
canLogObj.SerializeToArray(logsnippetmsg.data()+sizeof(uint16_t), canLogObj.ByteSizeLong());
socket.send(logsnippetmsg);
usleep(1);
canLogObj.clear_fromhours();
canLogObj.clear_fromminutes();
canLogObj.clear_fromseconds();
canLogObj.clear_fromday();
canLogObj.clear_frommonth();
canLogObj.clear_fromyear();
canLogObj.clear_tohours();
canLogObj.clear_tominutes();
canLogObj.clear_toseconds();
canLogObj.clear_today();
canLogObj.clear_tomonth();
canLogObj.clear_toyear();
}
}
Subscriber :
TransportLayer::TransportLayer():context(1),socket(context,ZMQ_SUB){ }
void TransportLayer::Init()
{
socket.bind("tcp://*:5555");
socket.setsockopt(ZMQ_SUBSCRIBE, "", 0);
}
void TransportLayer::Receive()
{
cout << "TransportLayer::Receive " << " I am in server " << endl;
static int count = 1;
// Producer thread.
while ( true ){
zmq::message_t request;
string protoBuf;
socket.recv(&request);
uint16_t id = *((uint16_t*)request.data());
cout << "TransportLayer : " << "request.data: " << request.data() << endl;
cout << "TransportLayer : count " << count << endl; count = count + 1;
cout << "TransportLayer : request.data.size " << request.size() << endl;
protoBuf = std::string(static_cast<char*>(request.data() + sizeof(uint16_t)), request.size() - sizeof(uint16_t));
cout << "ProtoBuf : " << protoBuf << endl;
InterfaceLayer *interfaceLayObj = InterfaceLayer::getInstance();
switch(id) {
case TABLEMSG_ID: cout << "Canlyser" << endl;
interfaceLayObj->ParseProtoBufTable(protoBuf);
break;
case LOGSNIPPET_ID: cout << "LogSnip" << endl;
interfaceLayObj->ParseProtoBufLogSnippet(protoBuf);
interfaceLayObj->logsnippetSignal(); // publish the signal
break;
default: break;
}
usleep(1);
}
}
Q : "how to use multiple Publishers and a single Client, using C < C11?"
So, the QNX-version was not explicitly stated, so let's work in general.
As noted in ZeroMQ Principles in less than Five Seconds, the single Client ( being of a SUB-Archetype ) may zmq_connect( ? ), however at a cost of managing some, unknown for me, way how all the other, current plus any future PUB-s were let to zmq_bind(), after which to let somehow let the SUB learn where to zmq_connect( ? ), so that to get some news from the newly bound PUB-peer.
So it would be a way smarter to make the single SUB-agent to perform a zmq_bind() and let any of the current or future PUB-s perform zmq_connect() as they come, directed to the single, static, known SUB's location ( this does not say, they cannot use any of the available transport-classes - one inproc://, another one tcp://, some ipc://, if QNX permits & system architecture requires to do so ( and, obviously, supposing the SUB-agent has exposed a properly configured AccessNode for receiving such connections ).
Next, your SUB-Client has to configure its subscription filtering topic-list: be it an order to "Do Receive EVERYTHING!" :
...
retCode = zmq_setsockopt( <aSubSocketINSTANCE>, ZMQ_SUBSCRIBE, "", 0 );
assert( retCode == 0 && "FAILED: at ZMQ_SUBSCRIBE order " );
...
Given this works, your next duty is to make the setup robust enough ( an explicit ZMQ_LINGER setting to 0, access-policies, security, scaled-resources, L2/L3-network protective measures, etc ).
And you are done to harness the ZeroMQ just fit right to your QNX-system design needs.
my program is reading in 2 text files, one is going into an array and one is priming read normally. The one that is being read into an array has an item code, price, quantity, and item name. When the item code matches with the code on the other text document I need to get the price associated with it and cant figure out how.
while (!purchasesFile.eof())
{
purchasesFile >> PurchaseItem >> purchaseQty;
cout << purchaseNum << " " << PurchaseItem << " " << setw(4) <<
purchaseQty << " # " << dollarSign << endl;
int n = 0;
if (inventoryRec[n].itemCode != PurchaseItem)
{
inventoryRec[n+1];
}
else
{
cout << inventoryRec[n].itemPrice << endl;
inventoryRec[n+1];
}
if (PurchaseItem == inventoryRec[itemCount].itemCode)
{
inventoryRec[itemCount].itemOnHand - purchaseQty;
purchaseAmount = inventoryRec[itemCount].itemPrice * purchaseQty;
cout << purchaseAmount << " " <<
inventoryRec[itemCount].itemOnHand;
purchaseCount++;
}
purchasesFile >> purchaseNum;
}
purchasesFile.close();
There are several statements in your code that do nothing:
inventoryRec[n+1];
inventoryRec[itemCount].itemOnHand - purchaseQty;
What you are looking for is probably something like the STL map
typedef struct inventory_item_t {
inventory_item_t(const std::string& item_code, double price, int quantity) :
item_code(item_code),
price(price),
quantity(quanity) { }
std::string item_code;
double price;
int quantity;
} inventory_item_t;
typedef std::map<std::string, inventory_item_t> inventory_items_t;
inventory_items_t inventory_items;
inventory_items.insert(make_pair("item1", inventory_item_t("item1", 1.0, 1)));
inventory_items.insert(make_pair("item2", inventory_item_t("item2", 1.1, 2)));
inventory_items.insert(make_pair("item3", inventory_item_t("item3", 1.2, 3)));
inventory_items_t::iterator inventory_item = inventory_items.find("item1");
if(inventory_item != inventory_items.end()) {
std::cout << "Inventory Item found - item_code: ["
<< inventory_item->first
<< "], price: ["
<< inventory_item->second.price
<< "]"
<< std::endl;
} else {
std::cout << "Inventory Item not found" << std::endl;
}
I'm getting problem with segmentation fault when trying to compile a C++ program, but not sure where the problem lies. I suspect that the problem lies with the .find() ..... could it be the iterator operator < and == which are the comparators for find() that is the issue? I hope that someone can point out to me where they think the problem lies.
The following is part of test01.cpp, where I run it to test the code and use print statements to find out where the problem is:
bool confirmEverythingMatches(const btree<long>& testContainer, const set<long>& stableContainer) {
cout << "Confirms the btree and the set "
"contain exactly the same values..." << endl;
for (long i = kMinInteger; i <= kMaxInteger; i++) {
cout << "Start of for-loop to find iterator for comparisons..." << endl;
if (stableContainer.find(i) != stableContainer.end()) {
cout << "can find i (" << i << ") in stableContainer!" << endl;
} else {
cout << "cannot find i (" << i << ") in stableContainer!" << endl;
}
cout << "In between finding i in stable and testContainers..." << endl;
if (testContainer.find(i) != testContainer.end()) {
cout << "can find i (" << i << ") in testContainer!" << endl;
} else {
cout << "cannot find i (" << i << ") in testContainer!" << endl;
}
cout << "Before assigning the find to boolean variables..." << endl;
bool foundInTree = (testContainer.find(i) != testContainer.end());
cout << "testContainer.find(i) != testContainer.end()" << endl;
bool foundInSet = (stableContainer.find(i) != stableContainer.end());
cout << "stableContainer.find(i) != stableContainer.end()" << endl;
if (foundInTree != foundInSet) {
cout << "- btree and set don't contain the same data!" << endl;
cout << "Mismatch at element: " << i << endl;
return false;
} else {cout << "foundInTree == foundInSet!!!" << i << endl;}
}
cout << "- btree checks out just fine." << endl;
return true;
}
} // namespace close
/**
* Codes for testing various bits and pieces. Most of the code is commented out
* you should uncomment it as appropriate.
**/
int main(void) {
// initialise random number generator with 'random' seed
initRandom();
cout << "after initRandom().." << endl;
// insert lots of random numbers and compare with a known correct container
btree<long> testContainer(99);
cout << "after specifying max node elements in testContainer.." << endl;
set<long> stableContainer;
cout << "after constructing stableContainer.." << endl;
insertRandomNumbers(testContainer, stableContainer, 1000000);
cout << "after inserting random numbers into testContainer and for success inserts, also into stableContainer.." << endl;
btree<long> btcpy = testContainer;
cout << "after copy assigning a copy of testContainer to btcopy.." << endl;
confirmEverythingMatches(btcpy, stableContainer);
cout << "after confirming everything internally matches between testContainer and stableContainer.." << endl;
return 0;
}
The output I get when running the program (No problem when compiling) is this:
Confirms the btree and the set contain exactly the same values...
Start of for-loop to find iterator for comparisons...
cannot find i (1000000) in stableContainer!
In between finding i in stable and testContainers...
ASAN:DEADLYSIGNAL
=================================================================
==7345==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x000108d132a8 bp 0x000000000000 sp 0x7fff56eee6f0 T0)
#0 0x108d132a7 in btree<long>::find(long const&) const (test01+0x1000022a7)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (test01+0x1000022a7) in btree<long>::find(long const&) const
==7345==ABORTING
Abort trap: 6
I also got this error when I tried to run it on another machine:
==29936==ERROR: AddressSanitizer failed to allocate 0x200000 (2097152) bytes of SizeClassAllocator32: 12
I found that when it goes into the find(), it will have the segmentation fault:
/**
* Identical in functionality to the non-const version of find,
* save the fact that what's pointed to by the returned iterator
* is deemed as const and immutable.
*
* #param elem the client element we are trying to match.
* #return an iterator to the matching element, or whatever the
* const end() returns if no such match was ever found.
*/
template<typename T> typename btree<T>::const_iterator
btree<T>::find(const T& elem) const {
std::cout << "CONST ITERATOR'S FIND" << std::endl;
Node *tmp_ = root_;
std::cout << "1" << std::endl;
while(true) {
std::cout << "2" << std::endl;
size_t i;
std::cout << "3" << std::endl;
// go through all elements from root to tail
for (i = 0; i < tmp_->__occupied_size_; ++i) {
std::cout << "4" << std::endl;
if (tmp_->__elem_[i] == elem) {
std::cout << "5" << std::endl;
// find the elem, return an iterator
return const_iterator(tmp_, i, this);
std::cout << "6" << std::endl;
} else if (tmp_->__elem_[i] > elem) {
std::cout << "7" << std::endl;
// elem is not in current Node, go to descendants
// for the elem.
if (tmp_->__descendants_ == nullptr) {
std::cout << "8" << std::endl;
return cend();
std::cout << "9" << std::endl;
} else {
std::cout << "10" << std::endl;
tmp_ = tmp_->__descendants_[i];
std::cout << "11" << std::endl;
break;
}
}
}
// handling boundaries cases
if (i == tmp_->__occupied_size_) {
std::cout << "12" << std::endl;
if (tmp_->__descendants_[i] == nullptr) {
std::cout << "13" << std::endl;
return cend();
std::cout << "14" << std::endl;
} else {
std::cout << "15" << std::endl;
tmp_ = tmp_->__descendants_[i];
}
}
}
}
The print statements for this find is:
CONST ITERATOR'S FIND
1
2
3
4
4
7
10
11
2
3
4
7
10
11
ASAN:DEADLYSIGNAL
Ok, so based on the implementation of this find function, I think the problem might be located in
if (tmp_->__descendants_ == nullptr) {
std::cout << "8" << std::endl;
return cend();
std::cout << "9" << std::endl;
} else {
std::cout << "10" << std::endl;
tmp_ = tmp_->__descendants_[i];
std::cout << "11" << std::endl;
break;
}
and then
// handling boundaries cases
if (i == tmp_->__occupied_size_) {
std::cout << "12" << std::endl;
if (tmp_->__descendants_[i] == nullptr) {
std::cout << "13" << std::endl;
return cend();
std::cout << "14" << std::endl;
} else {
std::cout << "15" << std::endl;
tmp_ = tmp_->__descendants_[i];
}
}
So, You are checking if tmp->__descendants_ is not null. If it is not, then you set tmp_ = tmp_->descendants_[i];
Note: you are just checking __descendants_ pointer to be null or not, you are not checking the __descendants_ [i] if it is null!
What if the tmp->__descendants_[i] is null (or gets out of the descendants array)?
If that value is null, then tmp_->occupied_size_ might give you segfault.
Note2: For some reason you are using same index "i" for iterating through __elem_ and __descendants_. I am not sure, how descendants are created, but it might be also a problem here.
This is why debuggers exist. Run your program in the debugger, let the program fail, and then the debugger will tell you where and why it's gone wrong.
It looks like you've got potentially a lot of code to trawl through, which no one here will really want to do as it's not a concise question.
Good luck!
I am currently working on a project that should help me create an implied volatility surface for a given stock. For this purpose, I am writing a script that will download all the available options for this specific stock - from what I've gathered, this is possible by sending a request through the Bloomberg API using bulks fields/overrides. Here is my current code:
d_host = "localhost";
d_port = 8194;
SessionOptions sessionOptions;
sessionOptions.setServerHost(d_host.c_str());
sessionOptions.setServerPort(d_port);
Session session(sessionOptions);
Service refDataService = session.getService("//blp/refdata");
Request request = refDataService.createRequest("ReferenceDataRequest");
request.append("securities", "MSFT US EQUITY");
request.append("fields", "CHAIN_TICKERS");
// add overrides
Element overrides = request.getElement("overrides");
Element override1 = overrides.appendElement();
override1.setElement("fieldId", "CHAIN_PUT_CALL_TYPE_OVRD");
override1.setElement("value", "C");
Element override2 = overrides.appendElement();
override2.setElement("fieldId", "CHAIN_POINTS_OVRD");
override2.setElement("value", 100);
Element override3 = overrides.appendElement();
override3.setElement("fieldId", "CHAIN_EXP_DT_OVRD");
override3.setElement("value", "20250203");
std::cout << "Sending Request: " << request << std::endl;
CorrelationId cid(this);
session.sendRequest(request, cid);
(followed by event handling)
Now I have several issues/questions:
The code compiles without problems, but when running it on the Bloomberg terminal,the following error is printed:
How would I go about fixing this problem? I assume I made a mistake somewhere in the override fields..
How would I need to adjust my code to download all options available given a specific maturity, i.e. I want to get a list of all the options until today + 15 years.
How would I then download the implied volatility for each option? Would I need to store the tickers in an array and then send a request for the field "IVOL_MID" for each option or is there some kind of way to obtain all the volatilities at once?
Edit: Here is the code of my event handler, since that seems to be the problem.
session.sendRequest(request, cid);
while (true)
{
Event event = session.nextEvent();
MessageIterator msgIter(event);
while (msgIter.next()) {
Message msg = msgIter.message();
if (msg.correlationId() == cid) {
processMessage(msg);
}
}
if (event.eventType() == Event::RESPONSE) {
break;
}
}
void processMessage(Message &msg)
{
Element securityDataArray = msg.getElement(SECURITY_DATA);
int numSecurities = securityDataArray.numValues();
for (int i = 0; i < numSecurities; ++i) {
Element securityData = securityDataArray.getValueAsElement(i);
std::cout << securityData.getElementAsString(SECURITY)
<< std::endl;
const Element fieldData = securityData.getElement(FIELD_DATA);
for (size_t j = 0; j < fieldData.numElements(); ++j) {
Element field = fieldData.getElement(j);
if (!field.isValid()) {
std::cout << field.name() << " is NULL." << std::endl;
}
else {
std::cout << field.name() << " = "
<< field.getValueAsString() << std::endl;
}
}
Element fieldExceptionArray =
securityData.getElement(FIELD_EXCEPTIONS);
for (size_t k = 0; k < fieldExceptionArray.numValues(); ++k) {
Element fieldException =
fieldExceptionArray.getValueAsElement(k);
std::cout <<
fieldException.getElement(ERROR_INFO).getElementAsString(
"category")
<< ": " << fieldException.getElementAsString(FIELD_ID);
}
std::cout << std::endl;
}
The problem is in the event handling code that you are not showing. You are probably parsing it incorrectly.
Running your query I get the following result:
MSFT US 01/20/17 C23
MSFT US 01/20/17 C25
MSFT US 01/20/17 C30
MSFT US 01/20/17 C33
MSFT US 01/20/17 C35
MSFT US 01/20/17 C38
MSFT US 01/20/17 C40
MSFT US 01/20/17 C43
MSFT US 01/20/17 C45
MSFT US 01/20/17 C47
MSFT US 01/20/17 C50
MSFT US 01/20/17 C52.5
MSFT US 01/20/17 C55
MSFT US 01/20/17 C57.5
MSFT US 01/20/17 C60
MSFT US 01/20/17 C65
MSFT US 01/20/17 C70
Note: I'm using the Java API but it is essentially the same.
UPDATE:
your code does not parse the field data array element properly: the returned data contains an array of sequences so you need to parse it in two steps. Instead of field.getValueAsString(), you should have a code that looks like this (it's in Java and not tested):
//...
for (int i = 0; i < field.numValues(); i++) {
Element sequence = field.getValueAsElement(i);
ElementIterator it = sequence.elementIterator();
while (it.hasNext()) {
Element e = it.next();
System.out.println(e.getValueAsString());
}
If that does not work I suggest you debug your code step by step and inspect the type of data you receive and handle it accordingly.
For more details you should read the Developer's guide, in particular A.2.3.
As seen in the other answer, the problem lies in the event handling so I've rewritten that part using some examples from the Bloomberg API emulator.
session.sendRequest(request, cid);
bool continueToLoop = true;
while (continueToLoop)
{
Event evt = session.nextEvent();
switch (evt.eventType())
{
case Event::RESPONSE:
continueToLoop = false; //fall through
case Event::PARTIAL_RESPONSE:
ProcessReferenceDataEvent(evt);
break;
}
}
void ProcessReferenceDataEvent(Event evt)
{
const string level1 = "";
const string level2 = "\t";
const string level3 = "\t\t";
const string level4 = "\t\t\t";
std::cout << endl << endl;
std::cout << level1 << "EventType = " << evt.eventType();
MessageIterator iter(evt);
while (iter.next())
{
Message msg = iter.message();
std::cout << endl << endl;
std::cout << level1 << "correlationID = " << msg.correlationId().asInteger() << endl;
std::cout << level1 << "messageType = " << msg.messageType().string() << endl;
std::cout << endl << endl;
Element SecurityDataArray = msg.getElement(SECURITY_DATA);
int numSecurities = SecurityDataArray.numValues();
for (int valueIndex = 0; valueIndex < numSecurities; valueIndex++)
{
Element SecurityData = SecurityDataArray.getValueAsElement(valueIndex);
string Security = SecurityData.getElementAsString(SECURITY);
std::cout << level2 << Security << endl;
bool hasFieldErrors = SecurityData.hasElement("fieldExceptions", true);
if (hasFieldErrors)
{
Element FieldErrors = SecurityData.getElement(FIELD_EXCEPTIONS);
for (size_t errorIndex = 0; errorIndex < FieldErrors.numValues(); errorIndex++)
{
Element fieldError = FieldErrors.getValueAsElement(errorIndex);
string fieldId = fieldError.getElementAsString(FIELD_ID);
Element errorInfo = fieldError.getElement(ERROR_INFO);
string source = errorInfo.getElementAsString("source");
int code = errorInfo.getElementAsInt32("code");
string category = errorInfo.getElementAsString("category");
string strMessage = errorInfo.getElementAsString("message");
string subCategory = errorInfo.getElementAsString("subcategory");
cerr << level3 << "field error:" << endl;
cerr << level4 << "fieldId = " << fieldId << endl;
cerr << level4 << "source = " << source << endl;
cerr << level4 << "code = " << code << endl;
cerr << level4 << "category = " << category << endl;
cerr << level4 << "errorMessage = " << strMessage << endl;
cerr << level4 << "subCategory = " << subCategory << endl;
}
}
bool isSecurityError = SecurityData.hasElement("securityError", true);
if (isSecurityError)
{
Element secError = SecurityData.getElement("securityError");
string source = secError.getElementAsString("source");
int code = secError.getElementAsInt32("code");
string category = secError.getElementAsString("category");
string errorMessage = secError.getElementAsString("message");
string subCategory = secError.getElementAsString("subcategory");
cerr << level3 << "security error:" << endl;
cerr << level4 << "source = " << source << endl;
cerr << level4 << "code = " << code << endl;
cerr << level4 << "category = " << category << endl;
cerr << level4 << "errorMessage = " << errorMessage << endl;
cerr << level4 << "subCategory = " << subCategory << endl;
}
else
{
Element FieldData = SecurityData.getElement(FIELD_DATA);
double pxLast = FieldData.getElementAsFloat64("PX_LAST");
double bid = FieldData.getElementAsFloat64("BID");
double ask = FieldData.getElementAsFloat64("ASK");
string ticker = FieldData.getElementAsString("TICKER");
std::cout << level3 << "fields: " << endl;
std::cout << level4 << "PX_LAST = " << pxLast << endl;
std::cout << level4 << "BID = " << bid << endl;
std::cout << level4 << "ASK = " << ask << endl;
std::cout << level4 << "TICKER = " << ticker << endl;
bool excludeNullElements = true;
if (FieldData.hasElement("CHAIN_TICKERS", excludeNullElements))
{
Element chainTickers = FieldData.getElement("CHAIN_TICKERS");
for (size_t chainTickerValueIndex = 0; chainTickerValueIndex < chainTickers.numValues(); chainTickerValueIndex++)
{
Element chainTicker = chainTickers.getValueAsElement(chainTickerValueIndex);
string strChainTicker = chainTicker.getElementAsString("Ticker");
std::cout << level4 << "CHAIN_TICKER = " << strChainTicker << endl;
}
}
else
{
std::cout << level4 << "NO CHAIN_TICKER information" << endl;
}
}
}
}
}
Regarding the second question, the Bloomberg support staff recommended me to just pick an arbitarily high number so that all options would be downloaded, i.e.
override2.setElement("fieldId", "CHAIN_POINTS_OVRD");
override2.setElement("value", 50000);
For the third question, it is possible to download the chain tickers for all maturities by setting the "CHAIN_EXP_DT_OVRD" override to 'ALL' (this part is currently untested):
Element override3 = overrides.appendElement();
override3.setElement("fieldId", "CHAIN_EXP_DT_OVRD");
override3.setElement("value", 'ALL');