Stack Overflow exception (0xC00000FD) at winsock select function - c++

I have an application which makes use of winsock.
I/O part is handled on an other thread.
And I am using blocking select method for sockets.
But the point is that after 5-6 hours,my application gives 0xC00000FD exception, at the line of select function.
As far as I know, this exception occurs when there is recursion, or very large local variables. But neither of them is the case for me.
So do you have any idea why am I getting this exception?
Or any ideas to discover what actually causes exception?
many thanks
EDIT 2:
Dear All, I am very sorry but since reproducing the case takes long time, I just realized that this has not solved the problem.
Everything seems ok when stack overflow exception occurs at the line of select function.
I mean it is a server socket with a one client connected. So there is 2 socket in rset and 1 in wset. After selecting, I am checking all ready sockets and making required, read,write,accept. Timeout is 250 ms. Do you think can this be the problem? I don't want this function to be blocking so it is not null. But what will be the exact difference if I use {0,0}
An important hint is:
Same code was working without any problem, when client socket wasn't sending any data.
But when I started sending some data from client to server this problem occured.
I am sure that there is no problem with FD_SETs and FD_CLRs, I mean when client was not sending only 1(server) socket was in rset and 1(client) was in wset.
Anyway I had a look a lot of samples, but it seems that there is not a difference.
Please see local variables screenshot below(I have deleted name of executable, since it is a commercial product)
http://img192.imageshack.us/img192/1948/stackoverflow.jpg
And here is the call stack:
ntdll.dll!7c90df3a()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
mswsock.dll!71a53c9c()
ntdll.dll!7c90d26c()
mswsock.dll!71a55f9f()
mswsock.dll!71a55974()
ws2_32.dll!71ab314f()
xyz.exe!vm_socket_select(vm_socket * hds=0x04c1fb84, int nhd=1, int masks=7) Line 230 + 0x1b bytes C
xyz.exe!ND::nd_socket::SocketThreadProc() Line 173 + 0x12 bytes C++
xyz.exe!ND::nd_socket::ThreadRoutineStarter(void * u=0x07d63f90) Line 332 C++
xyz.exe!_callthreadstartex() Line 348 + 0x6 bytes C
xyz.exe!_threadstartex(void * ptd=0x011a3ce8) Line 326 + 0x5 bytes C
kernel32.dll!7c80b713()
I am waiting for any advice.
Many thanks

Have you tried stopping your program in a debugger after some time running? Then take a look at the stack it might give you a hint.
Recursion doesn't mean one of your functions call itself endlessly, it can't be more tricky and involve several layers before it comes back where it started.

Related

Get inode for lookup in /proc/net/udp

I am trying to programmatically track the amount of data in my receive buffer. I am receiving UDP data. After doing some research it seems that the only way to do this in Linux is to look at /proc/net/udp. This seems like a good solution until I realized that two applications could be listening to the same multicast group and I need to tell them apart. It seems that I am supposed to do this by determining what my inode is.
I spend some time looking into this and there are suggestions that sockfd_lookup or sock_from_file is the way to go but on my CentOS Linux machine, these functions do not seem to be available.
Can someone please help me to figure out which line in /proc/net/udp belongs to my application?
I started using the ioctl (handle, FIONREAD, &bytesInBuffer) call only to discover that in Linux this only returns the size of the first datagram packet in the buffer.
Google seems to suggest that the sockfd_lookup call can be used to get the inode but a grep in my /usr/local/include/ does not return these functions.
My linux/net.h seems pretty bare-bone compared to some I can find on google which includes structs like "socket" which has the sock member which I believe has the inode information. My linux/net.h on CentOs only is 58 lines long and has only a few #defines and an enum.
after a bit of fiddling I noticed that readlink("/proc/self/fd/$fd") (under Linux 5.3) gives me something like:
socket:[3753088]
back. I can parse this and use the resulting digits to look up the relevant line in /proc/net/udp:
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
2867: 00000000:0BB8 00000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 3753088 2 000000003ae8e911 0
that said, I don't understand why you'd want to do this, but never mind!
I'm also not sure why you don't just look up by sock&peer name, which might be easier

Segmentation fault using GstDiscoverer (GStreamer)

I am writing desktop app for windows on C++ using Qt for GUI and GStreamer for audio processing.
In my app I need to monitor several internet aac audio streams if they are online, and listen to available stream that has the most priority. For this task I use GstDiscoverer object from GStreamer, but I have some problems with it.
I check audio streams every 1-2 seconds, so GstDiscoverer is called very often.
And every time my app is running, eventually it will crash with segmentation fault error during GstDiscoverer check.
I tried both sync and async methods of calling GstDiscoverer ( gst_discoverer_discover_uri(), gst_discoverer_discover_uri_async() ) , both work the same way.
The crash happens in aac_type_find() function from gsttypefindfunctions.c on line 1122 (second line of code below).
len = ((c.data[offset + 3] & 0x03) << 11) |
(c.data[offset + 4] << 3) | ((c.data[offset + 5] & 0xe0) >> 5);
Local variables received from debugger during one of crashes:
As we can see, offset variable is greater than c.size, so c.data[offset] is out of range, I think that's why segmentation fault happens.
This happens not regularly. The program can work several hours or ten minutes.
But it seems to me that it happens more often if time interval between calls of GstDiscoverer is little. So, there is some probability of crash calling aac_type_find().
I tried GStreamer versions 1.6.1 and latest 1.6.2, the bug exists in both.
Can somebody help me with this problem? Is this Gstreamer bug or maybe I do something wrong?
It was reported to the GStreamer project here and a patch for the crash was merged and will be in the next releases: https://bugzilla.gnome.org/show_bug.cgi?id=759910

LibsUsbK buffers not being filled when using function UsbK_IsoReadPipe

I'm trying to write some code to read from an Isochronous pipe using LibUsbK in Win32. I have successfully initialised the device into the correct state to send and receive Isochronous data and I can see data being sent over the USB in my hardware USB analyser, but the buffers I am receiving are always unfilled even though the analyser shows that there was data in the packets sent to the PC.
I'm new to LibUsbK and using Isochronous transfers though I'm not new to USB in general but I've been really struggling with this.
The code I'm using to read from the device is something like this...
UsbK_SelectInterface(usbHandle,1,0);
UsbK_SetAltInterface(usbHandle,1,0,1);
IsoK_Init(&isoCtx, ISO_PACKETS_PER_XFER, 0);
IsoK_SetPackets(isoCtx, ISO_PACKET_SIZE); // Size of each individual packet
OvlK_Init(&ovlPool, usbHandle, 4, 0);
OvlK_ResetPipe(usbHandle, 0x83);
OclK_Acquire(&ovlkHandle, ovlPool);
UsbK_IsoReadPipe(usbHandle, 0x83, inBuffer, sizeof(inBuffer), ovlkHandle, isoCtx);
while(!finished)
{
if(OvlK_IsComplete(ovlkHandle)
{
fwrite(inBuffer, sizeof(inBuffer), 1, outFile);
memset(inBuffer,0xcc,sizeof(inBuffer));
OvlK_ReUse(ovlkHandle);
UsbK_IsoReadPipe(usbHandle, 0x83, inBuffer, sizeof(inBuffer), ovlkHandle, isoCtx);
{
}
If I put a breakpoint at the fwrite line then the inBuffer is always full of 0xCC - ie, not having been filled by the iso read.
I've checked all the error return values from the UsbK/OvlK function calls and they are all as they should be. I've checked my buffers are sufficiently big to receive the data.
I use very similar code to write to the ISO out pipe on endpoint 0x02 and that works perfectly, the only difference really between the code above and my write code is that the fwrite/memset commands are replaced with a call to a "fillbuffer" function that populates my outBuffer before calling UsbK_IsoWritePipe function.
I tried looking through any examples I could find in the samples and also online but struggled to understand/get them to work with my particular device.
Any suggestions or help greatly appreciated.
So it appears that the above code did work and I was being mislead by the fact that the debugger was interrupting the flow of things - I keep forgetting that trying to debug real time stuff can introduce it's own issues.
The first issue was that stepping through the code in the debugger was causing issues with the low level libusbk code capturing the usb packets and filling my buffers correctly - once I let it run full speed and found other ways to test the buffers I did actually find there was some data in there.
The second problem I had was that quite often the buffer was starting to be filled part way through only (and not always right from the start) so when I examined the data I was only printing the first part of the buffer to the console and so all I saw was 0xCC and I was therefore assuming it hadn't worked.
Once I realised that there was actually some data later in the buffer I just started looking through the buffer in packet sized chuncks, if the packet was completely contained of 0xCC I would skip it and move on, but if any of it was not 0xCC then I would treat it as a valid packet - this worked perfectly and I was successfully receiving all the data. I'm sure there's a more "proper" way of doing this, but it works for me now.

std::string messed up when using it as storage within (boost.)async_read_some

I am using async_read_some to read data from a port that is saved in a char[] called _data. Its buffer size is big enough for every request:
void start() {
socket_.async_read_some(boost::asio::buffer(data_,BUFFERSIZE),make_custom_alloc_handler(allocator_,boost::bind(&attentionSession::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
string ip = socket_.remote_endpoint().address().to_string();
log->processData(data_,ip,"memory");
strcpy(data_,"");
}
processData adds some additional information (like timestamp etc.) to the request by copying it to another newly alloced char*. Then this char[] is sent to writeToMemory(char*) to append that char* to the std::string memoryBuffer:
void writeCacheToFile() {
// This function writes buffer data to the log file
char* temp = new char[memoryBuffer.length() + 1];
strcpy(temp, memoryBuffer.c_str());
writeToFile(temp);
delete[] temp;
memoryBuffer.clear();
}
void writeToMemory(char* data) {
int maxSize = 1024;
// Checks if char* data would 'fit' into the pre-defined maxSize
if ((strlen((const char*)data) + memoryBuffer.length()) >= maxSize) {
writeCacheToFile(); // If not the cache memoryBuffer is saved first
}
memoryBuffer.append((const char*) data);
cout << memoryBuffer.length() << endl;
}
It works but if there are constantly requests (bombarding it with requests) things get messed up. As you can see above in the writeToMemory() function I'll added a line to print out the current length of memoryBuffer and this is where I think it has somethings to do with thread safety of std::strings:
96
188
284
3639
94
190
286
2591
102
198
294
388
484
2591
96
2591
96
190
286
2591
The length of each (processed by processData()) request is 96 characters. But here the length of memoryBuffer just rises and falls down - some lengths are even bigger than maxSize (1024 chars).
EDIT: Sam pointed out I should add some more code. This is how I start the io_service:
boost::asio::io_service ioService;
boost::scoped_ptr<boost::thread> ioServiceThread;
server_class server (ioService,PORT); // Create server instance
ioServiceThread.reset (new boost::thread ( boost::bind ( &boost::asio::io_service::run, &ioService ) ) );
// Only one threaded io_service (to receive user inputs in main() function)
And this is the async_acceptor's function after completing a request:
typedef boost::shared_ptr<session_class> session_ptr;
void handleAccept(session_ptr thisSession, const boost::system::error_code& error) {
if (!error) {
thisSession->start(); // Calls the start() function above
thisSession.reset(new session(ioService,LOGGING_CLASS));
acceptor.async_accept(thisSession->socket(),boost::bind(&server_class::handleAccept, this, thisSession, PLACEHOLDER_ERROR));
}
}
The session_class holds the functions start() and handle_read(x,y) mentioned above. LOGGING_CLASS provides the class to write log files (holds the functions writeCacheToFile() and writeToMemory(char*)). log (mentioned above) is a kind of this class.
EOE: END OF EDIT
If I try to fix outsource the caching part (appending received char* to std::string) with boost::threads it ends up with a totally mixed up memoryBuffer
Is it really the thread safety of std::strings or something else I missed?
Thanks for your help in advance! :)
Paul
I made this same point as a comment but I figured it would be worth expanding into an answer. Posting the snippets of code you have are not terribly helpful, they don't give us the full picture. For example, the following concepts are not clear to me:
You're not checking the bytes_transferred parameter in your async_read_some handler. This is very important because even though you tell it to read n bytes it can return when reading n - x bytes where x <= n. As the documentation states, you should consider using one of the composed operations like the async_read free function.
you're using custom memory allocations for your asynchronous read operations, presumably based on the example provided. Why do you need that?
buffer lifetime. Ex: do your buffers stay in scope until the async_read handler is invoked?
object lifetime. Ex: are you using shared_ptr properly? Is the io_service in scope for the entirety of its event loop?
are you using a single io_service per process or one per thread?
why you need threads? Typically it's easier to understand asynchronous programming in a single threaded context first.
All of these are very important concepts to get right when using Boost.Asio. Part of debugging is boiling down a perceived problem into a smaller reproducer. This is useful both on Stack Overflow and for becomming a good programmer in general. It will help you understand the problem, and also help us help you find it. I strongly suggest you spend some effort on making a smaller reproducible example that we can compile. If that's not possible, consider using multiple threads only after you have proved a single threaded scenario works.
Well, the problem wasn't Boost nor Boost::Asio. It was the method how I tested my application:
I used nc (Netcat) to test the performance and functions of my application with this command
nc localhost 4450 <testfile
where testfile contained a 36 characters long test string. Netcat wasn't only slow - it was the origin of this problem.
After I changed my strategy and coded a little boost::asio application to send the same requests to my application it worked. Fast, easy and without any problems.
I learned my lesson: Never use Netcat for stress tests again!
The first thing I would do is refactor the line where you invoke async_read_some. It is so long it is almost impossible to see what is happening.
My guess would be that when you hammer this, you will have new calls to handle_read before the old calls return. handle_read is not thread-safe. Apart from anything else,
strcpy(data_,"");
is going to give you trouble when multiple copies are all trying to copy into data_.
You need to make handle_read thread-safe.

WinPCap Data Getting Truncated

Working on parsing Arp packets and I found this nice problem.
when receiving an Arp packet I was parsing the target's IP address.
I have c0 a8 in my hex dumb but after that it ends. I am missing data! I see the data in Wireshark but I am not getting the data through WinPCap.
I have yet to run into this issue before. Any ideas SO? So far no memory access errors though. Probably just luck. :x
EDIT:
My main look for processing packets is from the example pktdump_ex.
Here is the while line
while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
After that is executed, the snalen is 2b.
As noted in he comment, this smells like a faulty snaplen configuration. If you look at the winpcap api docs pcap_open() apidoc, it states:
snaplen,: length of the packet that has to be retained. For each packet received by the filter, only the first 'snaplen' bytes are stored in the buffer and passed to the user application. For instance, snaplen equal to 100 means that only the first 100 bytes of each packet are stored.
As explanation for the second parameter of pcap_open. Unless you provide some more detailed code snippets to work with, this is the closest to an answer we will get.