stringstream example in C++

6. November 2012 09:27

 

Short example of using string stream in C++ to build a string.

 

#include <stdio.h>
#include <iostream>
#include <sstream>


int main(int argc, char **argv) {
    std::stringstream ss;

    ss << "Hello, World" << "\n" << 42 << "\n";


 std::string str = ss.str();

 std::cout << str;

    return 0;
}
E-mail Kick it! DZone it! del.icio.us Permalink


HowTo Override malloc / free in c

3. November 2012 08:56

 

This is a short guide on how to override malloc / free in C/C++ on linux so that custom tracing / logging can be used on the functions to detect double free's

 

It is actually very simple to do. All you require is a short program that is compiled into a shared lib. Then this lib is pre loaded before your program loads and instead of binding to the libc functions it will bind to the ones in the lib.

 

 

#include <stdio.h>
#include <dlfcn.h>

extern void abort();

void *malloc(int size) {
        void * (*ptr)(int);
        void * handle = (void*) -1;
        ptr = (void *) dlsym(handle, "malloc");
        if (ptr == NULL) {
                printf("Opps\n");
                abort();
        }
        void *alloc = (*ptr)(size);
        printf("Alloc = %p Size: %d\n", alloc, size);
        return alloc;
}

void *realloc(void *alloc, int size) {
        void * (*ptr)(void *, int);
        void * handle = (void*) -1;
        ptr = (void *) dlsym(handle, "malloc");
        if (ptr == NULL) {
                printf("Opps\n");
                abort();
        }
        alloc = (*ptr)(alloc, size);
        printf("Realloc = %p Size: %d\n", alloc, size);
        return alloc;
}

void free(void *alloc) {
        if (alloc == NULL)
                return;
        printf("free %p\n", alloc);
        void * (*ptr)(void *);
        void * handle = (void *) -1;
        ptr = (void *) dlsym(handle, "free");
        if (ptr == NULL)
                abort();

        (*ptr)(alloc);
}

 

 

You can compile the above with the following command

 

gcc -Wall sample.c -fPIC -shared -o libsample.so -lc -ldl

 

Then set the LD_LIBRARY_PATH= so that it includes the path to the location that the libsample.so is in.

 

Then set the LD_PRELOAD=libsample.so which will tell the dynamic lib loader to load that library first.

 

Then you can simply run your program.

E-mail Kick it! DZone it! del.icio.us Permalink


Rasberry Pi - Alternative method to play video without omx gstreamer element

13. October 2012 21:03

 

I finally got my hands on a rasberry pi. So of course the first thing I did was attempt to play video. For this I turned to gstreamer and spent about 2-3 evening trying to get the omx gstreamer elements to work. Though I seemed to keep failing for various reasons. I managed to reach the stage of getting it to decode and play a single h264 frame. It would then hang and never play any further video.

 

So I went in search of some other examples. I found a small example app from broadcom which was actually located on the debian distribution that shipped with the pi. This was the "hello video" sample app which seemed to play the h264 file that came with it fine.

 

Running the sample app seemed to simple.

 

 

cd /opt/vc/src/hello_pi/hello_video
./hello_video.bin test.h264

 

This gets me playing. When looking into the source of the application I then notice that it was not going anything clever with the h264 eg seeks. It was in fact playing the h264 file as a stream. Therefore decided the following would also work.

 

cat test.h264 | ./hello_video.bin /dev/stdin

 

Thats great. That would mean that it would also work with nc (netcat) and the video can be sent from another machine.

 

On Pi

nc -l -p 10001 | ./hello_video.bin /dev/stdin

On other linux machine

gst-launch-0.10 videotestsrc ! \
 video/x-raw-yuv, width=720, height=402, framerate=30/1 ! \
 ffmpegcolorspace ! x264enc byte-stream=true ! \
 tcpclientsink host=<ip address of pi> port=10001

 

That managed to put up the nice gstreamer videotest source on the pi. So then I started to look into playing some real video which also involved audio. So this also turns the pi into an instant audio server.

 

 

gst-launch -v tcpserversrc host=0.0.0.0 port=10002 protocol=1 ! \
 audioconvert ! audioresample ! queue ! autoaudiosink

 

So by simply using the pi as a video and audio server you can play any video by using the source machine to split the audio / video and send them to the seperate service like this.

 

 

On the pi start the video / audio server

nc -l -p 10001 | ./hello_video.bin /dev/stdin

gst-launch -v tcpserversrc host=0.0.0.0 port=10002 protocol=1 ! \
audioconvert ! audioresample ! queue ! autoaudiosink

On your other linux machine run the player / re-encoder and send it to the pi

gst-launch-0.10 filesrc location=Movie.avi ! \
 decodebin2 name=dec ! queue ! ffmpegcolorspace ! \
 x264enc byte-stream=true psy-tune=1 speed-preset=1 ! \
 tcpclientsink host= port=10001 \
 dec. ! tcpclientsink host= port=10002 protocol=1

 

Now for the next problem. Technically the above works. Though the audio quaility is somewhat questionabile. The video quality seems to definatly pass even though in the above gstreamer command I have tunned the x264 encoder to the fastest possible setting (I have a slow machine)

 

Something that is definatly intresting is how the pi performs with the above setup. The audio playing seems to struggle mosty because of the driver issues and its gstreamer processes is using around 10% cpu time of the pi. The video player is split into two parts the netcat process uses around 2% cpu time and the h264 sample application also uses around 2% cpu time since it is a hardware decode. So thats a total of 14% of cpu time to play a movie.

 

Hopefully this opens up some cool options for some people to experement. I can already think of something useful todo with a pi, wall projector, gstreamer and ximagesrc

E-mail Kick it! DZone it! del.icio.us Permalink


Why you should not use new[] with shared_ptr.

13. October 2012 16:03

 

This is an example about why not to use the boost::shared_ptr with a new array with an explenation of why it will be dangerous to use.

 

Effectivly when using boost::shared_ptr or the normal std::shared_ptr when it releases the pointer it will always call delete. However when using new[] you need to use delete[]. This is the simple rule of when using malloc you use free. Then using new you use delete. When using new[] you need to use delete[]. Using a mixed combination will result at best a program crash. Or at worse siliently corrupting the heap and making a mess of your data.

 

The following code example which is using boost::shared_ptr correctly. Which is to allocate a new class and then the class will be automatically deleted once the last shared_ptr holding the reference has been removed.

 

 

#include <stdio.h>
#include <boost/shared_ptr.hpp>


class MyClass {
	public:
		MyClass() { 
			printf("MyClass Created\n");
		};
		
		~MyClass() {
			printf("MyClass Deleted\n");
		};
};


int main(int argc, char **argv) {
	boost::shared_ptr<MyClass> ptr;
	
	ptr.reset(new MyClass());

	return 0;
}


When running under valgrind we get the following output.

==5868== Memcheck, a memory error detector
==5868== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==5868== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==5868== Command: ./a.out
==5868==
MyClass Created
MyClass Deleted
==5868==
==5868== HEAP SUMMARY:
==5868==     in use at exit: 0 bytes in 0 blocks
==5868==   total heap usage: 2 allocs, 2 frees, 17 bytes allocated
==5868==
==5868== All heap blocks were freed -- no leaks are possible
==5868==
==5868== For counts of detected and suppressed errors, rerun with: -v
==5868== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from 8)

Once we modify the program slight to create an array of items like below. In this case ten items of "MyClass" things will change significantly.

int main(int argc, char **argv) {
	boost::shared_ptr<MyClass> ptr;
	
	ptr.reset(new MyClass[10]);

	return 0;
}

 

 

When run under valgrind this will show as a memory leak. You can see that there has been ten instances of the class created but only one instance has been deleted.

 

 

==5889== Memcheck, a memory error detector
==5889== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==5889== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==5889== Command: ./a.out
==5889==
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Deleted
==5889== Invalid free() / delete / delete[]
==5889==    at 0x4023881: operator delete(void*) (vg_replace_malloc.c:387)
==5889==    by 0x8048CC4: void boost::checked_delete<MyClass>(MyClass*) (in /home/james/tmp/posts/a.out)
==5889==    by 0x8048D3F: boost::detail::sp_counted_impl_p<MyClass>::dispose() (in /home/james/tmp/posts/a.out)
==5889==    by 0x80489F7: boost::detail::sp_counted_base::release() (in /home/james/tmp/posts/a.out)
==5889==    by 0x8048A69: boost::detail::shared_count::~shared_count() (in /home/james/tmp/posts/a.out)
==5889==    by 0x8048ACF: boost::shared_ptr<MyClass>::~shared_ptr() (in /home/james/tmp/posts/a.out)
==5889==    by 0x80488C8: main (in /home/james/tmp/posts/a.out)
==5889==  Address 0x42c402c is 4 bytes inside a block of size 14 alloc'd
==5889==    at 0x40243B0: operator new[](unsigned int) (vg_replace_malloc.c:299)
==5889==    by 0x8048827: main (in /home/james/tmp/posts/a.out)
==5889==
==5889==
==5889== HEAP SUMMARY:
==5889==     in use at exit: 14 bytes in 1 blocks
==5889==   total heap usage: 2 allocs, 2 frees, 30 bytes allocated
==5889==
==5889== LEAK SUMMARY:
==5889==    definitely lost: 14 bytes in 1 blocks
==5889==    indirectly lost: 0 bytes in 0 blocks
==5889==      possibly lost: 0 bytes in 0 blocks
==5889==    still reachable: 0 bytes in 0 blocks
==5889==         suppressed: 0 bytes in 0 blocks
==5889== Rerun with --leak-check=full to see details of leaked memory
==5889==
==5889== For counts of detected and suppressed errors, rerun with: -v
==5889== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 8)

 

 

However when run normally outside of valgrind using the normal c++ memory allocater in linux it will produce a heap corruption instead.

 

 

MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Deleted
*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x0809e00c ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6(+0x6b381)[0xb74cc381]
/lib/i686/cmov/libc.so.6(+0x6c5fe)[0xb74cd5fe]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb76a8701]
./a.out[0x8048cc5]
./a.out[0x8048d40]
./a.out[0x80489f8]
./a.out[0x8048a6a]
./a.out[0x8048ad0]
./a.out[0x80488c9]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7477ca6]
./a.out[0x8048771]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:11 4063698    /home/james/tmp/posts/a.out
0804a000-0804b000 rw-p 00001000 08:11 4063698    /home/james/tmp/posts/a.out
0809e000-080bf000 rw-p 00000000 00:00 0          [heap]
b7460000-b7461000 rw-p 00000000 00:00 0
b7461000-b75a1000 r-xp 00000000 08:01 586488     /lib/i686/cmov/libc-2.11.3.so
b75a1000-b75a2000 ---p 00140000 08:01 586488     /lib/i686/cmov/libc-2.11.3.so
b75a2000-b75a4000 r--p 00140000 08:01 586488     /lib/i686/cmov/libc-2.11.3.so
b75a4000-b75a5000 rw-p 00142000 08:01 586488     /lib/i686/cmov/libc-2.11.3.so
b75a5000-b75a8000 rw-p 00000000 00:00 0
b75a8000-b75c5000 r-xp 00000000 08:01 578602     /lib/libgcc_s.so.1
b75c5000-b75c6000 rw-p 0001c000 08:01 578602     /lib/libgcc_s.so.1
b75c6000-b75c7000 rw-p 00000000 00:00 0

[snip]

Aborted

 

 

Note that it is also possible for this to show up in valgrind as a "Mismatched free / delete / delete[]" message as well as memory leaks. Or really anything random may happen because mixing free / delete / delete[] will result in undefined behaviour.

Correcting the issue if you have come across it is easy. Simply replace the shared_ptr with a shared_array. Of course when using shared_array you can no longer use "new MyClass()" since this will then be calling delete[] instead of delete and the same problem will occur.

Here is the correct example.

 

 

#include <stdio.h>
#include <boost/shared_array.hpp>


class MyClass {
	public:
		MyClass() { 
			printf("MyClass Created\n");
		};
		
		~MyClass() {
			printf("MyClass Deleted\n");
		};
};


int main(int argc, char **argv) {
	boost::shared_array<MyClass> ptr;
	
	ptr.reset(new MyClass[10]);

	return 0;
}

 

When run under valgrind you can see that it no longer leaks / crashes or complains about anything and the same number of items being created are being deleted again.

 

 

==6074== Memcheck, a memory error detector
==6074== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==6074== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==6074== Command: ./a.out
==6074==
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Created
MyClass Deleted
MyClass Deleted
MyClass Deleted
MyClass Deleted
MyClass Deleted
MyClass Deleted
MyClass Deleted
MyClass Deleted
MyClass Deleted
MyClass Deleted
==6074==
==6074== HEAP SUMMARY:
==6074==     in use at exit: 0 bytes in 0 blocks
==6074==   total heap usage: 3 allocs, 3 frees, 54 bytes allocated
==6074==
==6074== All heap blocks were freed -- no leaks are possible
==6074==
==6074== For counts of detected and suppressed errors, rerun with: -v
==6074== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from 8)
E-mail Kick it! DZone it! del.icio.us Permalink


Linux Programming - Using inotify for detecting file modifications

22. September 2012 09:21

 

This is a short introduction to using the inofity api in linux to detect file system modifications for specific files. Which can be useful for a number of reasons. The particular reason why I wrote the example program here was to reload parts of apache when python scripts were being modified while doing some web development. the problem being that apache + django caches the python files.

 

The example here is simple. It will take a file list to monitor and will then execute a command when one of thoose files are modified. Though it also shows a simple example of how to use the inofity api in linux.

 

To start with you will need to get a suitable file descriptor by calling inotify_init and then setup the files you would like to monitor you can do this by using the function inotify_add_watch with the correct arguments to be notified when files changes. See below for the first half of the program. Note that the program expects the file list to be passed on the command line.

 

int main(int argc, char **argv) {
	int fdnotify = -1;
	int i;

	fdnotify = inotify_init();
	if (fdnotify < 0) {
		fprintf(stderr, "inotify_init failed: %s\n", strerror(errno));
		exit(-1);
	}

	for(i = 2;i<argc;i++) {
		int wd = inotify_add_watch(fdnotify, argv[i], IN_MODIFY);
		if (wd < 0) {
			fprintf(stderr, "inotify_add_watch failed: %s\n", strerror(errno));
		}
	}

 

Once the initial list has been completed you just need to wait for a notification which is done by reading from the file decriptor with the inotify_event data structure and just keep reading from that file descriptor in a loop.

 

while(1) {
		char buffer[4096];
		struct inotify_event *event = NULL;
		int exec = 0;

		int len = read(fdnotify, buffer, sizeof(buffer));
		if (len < 0) {
			fprintf(stderr, "read: %s\n", strerror(errno));
			exit(-1);
		}

		event = (struct inotify_event *) buffer;
		while(event != NULL) {
			if ( (event->mask & IN_MODIFY) && event->len > 0) {
				printf("File Modified: %s\n", event->name);
				exec = 1;
			} else {
				printf("Unknown Mask 0x%.8x\n", event->mask);
			}
				
			/* Move to next struct */	
			len -= sizeof(*event) + event->len;
			if (len > 0)
				event = ((void *) event) + sizeof(event) + event->len;
			else
				event = NULL;
		}
	
		if (exec)	
			system(argv[1]);
	}

And that is really it. Note that I wanted to "eat" most of the file notification events before running the external script so that it would only execute the script once. It can also serve other nice purposes eg it can be used to auto rebuild a c project on the file by using it like this "./inotify make `find . -type f -name '*.[ch]'" which will run make any time any of the .c, .h files change. the program has 100's of useful ways to be used for being able to trigger shell scripts from filesystem events.

 

Here is a copy of the full program

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <sys/inotify.h>

void printhelp(FILE *out, char *app) {
	fprintf(out, "Usage: %s <command> <dirs to watch>\n", app);
}

int main(int argc, char **argv) {
	int fdnotify = -1;
	int i;

	fdnotify = inotify_init();
	if (fdnotify < 0) {
		fprintf(stderr, "inotify_init failed: %s\n", strerror(errno));
		exit(-1);
	}

	if (argc < 3) {
		fprintf(stderr, argv[0]);
		exit(-1);
	}

	for(i = 2;i<argc;i++) {
		int wd = inotify_add_watch(fdnotify, argv[i], IN_MODIFY);
		if (wd < 0) {
			fprintf(stderr, "inotify_add_watch failed: %s\n", strerror(errno));
		}
	}

	while(1) {
		char buffer[4096];
		struct inotify_event *event = NULL;
		int exec = 0;

		int len = read(fdnotify, buffer, sizeof(buffer));
		if (len < 0) {
			fprintf(stderr, "read: %s\n", strerror(errno));
			exit(-1);
		}

		event = (struct inotify_event *) buffer;
		while(event != NULL) {
			if ( (event->mask & IN_MODIFY) && event->len > 0) {
				printf("File Modified: %s\n", event->name);
				exec = 1;
			} else {
				printf("Unknown Mask 0x%.8x\n", event->mask);
			}
				
			/* Move to next struct */	
			len -= sizeof(*event) + event->len;
			if (len > 0)
				event = ((void *) event) + sizeof(event) + event->len;
			else
				event = NULL;
		}
	
		if (exec)	
			system(argv[1]);
	}

	return 0;
}

E-mail Kick it! DZone it! del.icio.us Permalink