LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   c++ performance (https://www.linuxquestions.org/questions/programming-9/c-performance-861205/)

katea 02-07-2011 12:02 PM

c++ performance
 
hello,

I'm trying to use winpcap, but I'm facing performance issues (my program is using 50% of my cpu, which I find highly uncalled for; edit: or rather 100% of one core)

What I have is pretty simple (I know some functions are deprecated, it's just pretty much a copy paste from the net):

Code:

#define BUFFERSIZE 65535

/*
* workhorse function, we will be modifying this function
*/
void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet)
{
// nothing there yet !
}



 void MyThread::run()
 {
        char *dev;
        char errbuf[PCAP_ERRBUF_SIZE];
        pcap_t* descr;
        struct bpf_program fp;      /* hold compiled program    */
        bpf_u_int32 maskp;          /* subnet mask              */
        bpf_u_int32 netp;          /* ip                        */
        u_char* args = NULL;


        /* grab a device to peak into... */
        dev = pcap_lookupdev(errbuf);
        if(dev == NULL)
        { printf("%s\n",errbuf); exit(1); }

        /* ask pcap for the network address and mask of the device */
        pcap_lookupnet(dev,&netp,&maskp,errbuf);

        /* open device for reading. NOTE: defaulting to
        * promiscuous mode*/
        descr = pcap_open_live(dev,BUFFERSIZE,1,-1,errbuf);
        if(descr == NULL)
        { printf("pcap_open_live(): %s\n",errbuf); exit(1); }



        /* Lets try and compile the program.. non-optimized */
        if(pcap_compile(descr,&fp,"port 80",0,netp) == -1)
        { fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }

        /* set the compiled program as the filter */
        if(pcap_setfilter(descr,&fp) == -1)
        { fprintf(stderr,"Error setting filter\n"); exit(1); }


        /* ... and loop */
        pcap_loop(descr,-1,my_callback,args);

        fprintf(stdout,"\nfinished\n");
 }


paulsm4 02-07-2011 12:24 PM

"Busy loop", dude :)

Put a "sleep(1)" in your callback and watch CPU utilization drop from 100% to 0%. Really fast :)

katea 02-07-2011 12:34 PM

hi,

thanks for your reply.

I put a sleep(1) from stdio.h but I still have the same cpu usage.

I don't understand why that would be anyway because from what I understand my_callback should only be called everytime a html packet is received, so it shouldn't occur that often so as to busy my cpu, especially if the callback is empty...

paulsm4 02-07-2011 01:13 PM

Whoops - my bad. Sorry :(

Sounds like you're on Windows, correct?

I presume you've only got one thread calling PCap (instead of many, many different threads all contending for the interface). And I presume you've got a relatively new version of PCap.

I also presume you've stepped through the debugger, and traced it down to a specific call (which I guess might be pcap_loop()?).

Perhaps try another, different version of Winpcap?

Q: What is your platform/version, compiler/version and WinPCap version?

Q: Which device did you try to open?

ta0kira 02-07-2011 01:27 PM

Quote:

Originally Posted by paulsm4 (Post 4251015)
"Busy loop", dude :)

Put a "sleep(1)" in your callback and watch CPU utilization drop from 100% to 0%. Really fast :)

I've read rumors that sleep can pause the entire process and not just the calling thread (as opposed to nanosleep,) but looking at the POSIX standard it appears this is incorrect. Any comments?
Kevin Barry

katea 02-07-2011 01:34 PM

Yes I'm on windows (xp), though I think the functions I used are cross plateform. I came to this forum because I know that's where experts are :).
I also have linux installed.

I would like to make a gui application, and I chose qt as my framework. I have created a specific thread (using QThread, but I could use posix if you request it) to handle the pcap part, because I thought it would be wise to separate that from the main thread.

I have winpcap 4.1.2 which should be the latest, I'm using qt4 and the vs compiler (vs10) because I like the UI, but I could try to compile with mingw in the command line as I have it installed too.

I'm just at the very beginning of this project, I just did a copy/paste from the net, so I'm opened to any suggestions, and I could copy paste the whole project here if you think that's relevant.

The first little task I'd like to do is to show in a QTextEdit the contents of every html packed I've grabbed.

I only have one network card device (as far as I know) so there shouldn't be any problems with that. I've done some tests with printf before chosing to use qt and it grabbed the right device.

If you have any more questions feel free to ask.

Thanks for your interest in my small issue :).

paulsm4 02-07-2011 02:01 PM

You might be surprised about "only one NIC". If you've ever installed any VPN software ... or ever installed VMWare ... or any number of 100 other things ... you might well have MULTIPLE NICs. Perhaps causing you unnecessary grief ;)

The "sleep()" is still a good idea. But use the Win32 equivalent "Sleep (1000)" instead. And set a breakpoint, and step through the debugger to make sure you hit it.

Most importantly - please step through under the debugger and see exactly where things go awry ;)

PS:
VS2010 Pro, or the VS2010 Express version?

PPS:
Quote:

I've read rumors that sleep can pause the entire process and not just the calling thread (as opposed to nanosleep,) but looking at the POSIX standard it appears this is incorrect. Any comments?
No way do I trust any of the "compatibility APIs" in Windows :) When in Rome, "VOID Sleep (DWORD dwMilliseconds)" as the Romans do ;)

katea 02-07-2011 02:15 PM

I used other source codes from the net that listed all my devices and only one was found.
From what I can see with the debugger, pcap_loop() causes indeed multiple calls to my_callback. I can't see the contents of the packets with the debugger because "packet" is just a pointer (to const u_char), and the debugger just gives me its address.

It is VS2010 ultimate (not express).

From a Qt point of view, I also don't know how to get the packet and send it to a qttextedit accross threads (that would help me to see what's going on, and that was actually what I wanted to do in the first place). Any idea how to do that ?

Thanks.

katea 02-07-2011 02:36 PM

To put it simply, let's forget about qt for a while.
I created a new project without qt embedded (just a console application). I didn't make a seperate thread either.
The rest of the code is the same (MyThread::run() becomes main()). I've added printf("a"); to my_callback.
Some 'a's are printed everytime I do a web browser task (which incidently means that the whole thing works, which is a good thing...), but not that many 'a's (10 maybe max for each task), and otherwise nothing is written on the console. Yet the cpu usage is still 50%.
So that's very likely due to pcap_loop but how to make the loop be less greedy?

katea 02-07-2011 09:23 PM

I also found out that I have another (somehow more important) problem, which is that "packet" (from my_callback) is actually empty...
for instance, printf((char*) packet) prints nothing :(.

paulsm4 02-07-2011 10:40 PM

Here are two tutorials:

http://www.tcpdump.org/pcap.html

http://yuba.stanford.edu/~casado/pcap/section1.html

There doesn't seem to be anything "substantially different" from what it looks like you're doing - but who knows? For example, you're passing pointer "arg = NULL"; the example is passing a NULL instead of a pointer.

Also remember that VS2008 and higher defaults to 16-bit character strings (no longer 8-bit char*). It's entirely possible this "feature" might lead to unexpected surprises :)

Suggestion: Cut/paste the tutorial examples *directly*. See what happens.

Good luck!

PS:
Alternate suggestion: if all else fails, try Linux, libpcap, and GCC. Specifically:
1. Download a (free!) copy of VMWare player:
http://www.vmware.com

2. Download a (free! pre-built! prêt-à-porter!) Linux VM:
http://www.thoughtpolice.co.uk/vmware/

3. Try the *same* code under Linux/GCC

katea 02-11-2011 04:07 AM

Hi again,

I've tried a lot of things but I'm still facing issues.
I had already read the tutorials you mentionned (actually, my code is a copy paste from the second one, except that I've removed the argv part).
I downloaded vmware and ubuntu as you said.
I need to download libpcap. If I use aptget the last version is not available. So I downloaded the last version from the site. I got a taz.gz with a lot of different files. What should I do with them ?

katea 02-11-2011 02:21 PM

If I use the libpcap0.8 with the source above, the program doesn't pick any packets.


All times are GMT -5. The time now is 08:42 AM.