It is really painful if you have tested the POSIX's regular expression functions with quite a lot of limitations. The good news is that I am not going to walk on the pure C programming for a further long time. Some C++ library's may save me at this point. The performance of my experiment monitor program is my most concern in the first place. It is not any more when I move to C++. There are two candidates that can be used as the regular experiment tool in my C++ programs: boost regex and TR1's regex. Maybe they share the same sources which is not my concerned; and I did not investigate that. According to my initial testing, they have different features during the development by using them.
Boost have a good compatibility across different present platforms: Windows, Linux and so on. The bad feature is that it requires to be linked against the boost_regex library which is different from most boost tools.
I have not looked into more details of TR1's regular expression. My insight told me that maybe it is still not exist in my system yet because it is a module of cxx11 standard. Really advanced and just don't use it.
If I got time, I will go back to do some investigation on these two tools with more sophisticated testing !!!
Tuesday, 8 May 2012
Friday, 27 April 2012
Chaos of the 'Places' menu
Today, the items in the menu of 'Places' on the above title bar of Fedora 14 are almost all lost from where they are, after I deleted everything in my home directory. Even after I copy back them from somewhere else, the items seems are lost completely without any recovery.
Google is the best way to solve problems. The config file to control these items are in the home directory named, '.config/user-dirs.dirs'. Each items are changed to be $HOME/. After the manual modifications on these incorrect config, Everything is back.
Google is the best way to solve problems. The config file to control these items are in the home directory named, '.config/user-dirs.dirs'. Each items are changed to be $HOME/. After the manual modifications on these incorrect config, Everything is back.
Monday, 16 April 2012
BE CAUTIONS: when you are using 'strncpy'
In my experiment results, an random error happened quite frequently. But it is not show itself in each time's experiment. It makes me be really frustrated as it is shown in a experiment. The PROBLEM is: an additional extra number always suffix the real number. Due to it happened randomly, which means that no patterns can be found from the situations it is shown, it is difficult to spot the problem's root cause.
What can I do at this point is to skim through the code where it probably happened from. Because this code is written with pure C instead of C++, the most possible reason should be the wrong memory pointer.
After the searching of man docs of the Linux, the reason is found --- the using of 'strncpy'.
When we copy a group of characters to a destination C-type string, a null-termination will be added to the destination automatically as 'strcpy' (without the 'n') is used. There are no problems at all.
However, the 'strncpy' is used, we need to think about the null-termination problem. As the statement of warning in the man doc, if the first 'n' characters of source C-type string have not null-termination in it. This function will not append the '\0' termination to the end of destination string automatically. This is not related to the size of destination string. We only need to be bare in mind the size of n and the first n characters of source string.
SOLUTION: add the '\0' termination to the destination string manually.
What can I do at this point is to skim through the code where it probably happened from. Because this code is written with pure C instead of C++, the most possible reason should be the wrong memory pointer.
After the searching of man docs of the Linux, the reason is found --- the using of 'strncpy'.
When we copy a group of characters to a destination C-type string, a null-termination will be added to the destination automatically as 'strcpy' (without the 'n') is used. There are no problems at all.
However, the 'strncpy' is used, we need to think about the null-termination problem. As the statement of warning in the man doc, if the first 'n' characters of source C-type string have not null-termination in it. This function will not append the '\0' termination to the end of destination string automatically. This is not related to the size of destination string. We only need to be bare in mind the size of n and the first n characters of source string.
SOLUTION: add the '\0' termination to the destination string manually.
Wednesday, 28 March 2012
Stop auto clean the Fedora's /tmp directory
In Fedora, the files that stored in /tmp directory seems would be removed after a certain period of time without operation on it. Which kind of time (last modification time, create time or read time) can be set using different parameters when invoke a program named tmpwatch. Beware in mind, this works only in Fedora series. I am not sure for other Linux distributions.
The tmpwatch is a watching program that is invoked daily-based by cron. A script is also called tmpwatch is in /etc/cron.daily/ directory to invoke the program in /sbin directory.
In my case, I want to keep my file in /tmp directory without bothering with the tmpwatch's auto-removing. So I am able to set myself to be a exclude user by -U parameter for tmpwatch in shell scripts in cron directory.
And it should be work.
The tmpwatch is a watching program that is invoked daily-based by cron. A script is also called tmpwatch is in /etc/cron.daily/ directory to invoke the program in /sbin directory.
In my case, I want to keep my file in /tmp directory without bothering with the tmpwatch's auto-removing. So I am able to set myself to be a exclude user by -U parameter for tmpwatch in shell scripts in cron directory.
And it should be work.
Friday, 2 March 2012
Add column to existing table
To add column in existing table, you may refer to the 2 examples below:-
Example I: Add new varchar column to the end of the table
Example I: Add new varchar column to the end of the table
ALTER TABLE `tablename_here` ADD `new_column_name` VARCHAR( 255 ) NOT NULL ;
Example II: Add new integer column after an existing column in table
ALTER TABLE `tablename_here` ADD `new_column_name` INT NOT NULL AFTER `existing_column` ;
It’s simple to add column to existing table right? 
Monday, 16 January 2012
Terminal Colors
Here's a list of different colors:
30 black foreground
31 red foreground
32 green foreground
33 brown foreground
34 blue foreground
35 magenta (purple) foreground
36 cyan (light blue) foreground
37 gray foreground
40 black background
41 red background
42 green background
43 brown background
44 blue background
45 magenta background
46 cyan background
47 white background
Commands can also be combined using a semicolon, like so:
Finally here is a list of other neat commands that go at the end (where the '0' is):
0 reset all attributes to their defaults
1 set bold
5 set blink
7 set reverse video
22 set normal intensity
25 blink off
27 reverse video off
=====================================================
Another one:
\033[22;30m - black
\033[22;31m - red
\033[22;32m - green
\033[22;33m - brown
\033[22;34m - blue
\033[22;35m - magenta
\033[22;36m - cyan
\033[22;37m - gray
\033[01;30m - dark gray
\033[01;31m - light red
\033[01;32m - light green
\033[01;33m - yellow
\033[01;34m - light blue
\033[01;35m - light magenta
\033[01;36m - light cyan
\033[01;37m - white
30 black foreground
31 red foreground
32 green foreground
33 brown foreground
34 blue foreground
35 magenta (purple) foreground
36 cyan (light blue) foreground
37 gray foreground
40 black background
41 red background
42 green background
43 brown background
44 blue background
45 magenta background
46 cyan background
47 white background
Commands can also be combined using a semicolon, like so:
printf("\033[45;37mGrey on purple.\033[0m");Finally here is a list of other neat commands that go at the end (where the '0' is):
0 reset all attributes to their defaults
1 set bold
5 set blink
7 set reverse video
22 set normal intensity
25 blink off
27 reverse video off
=====================================================
Another one:
\033[22;30m - black
\033[22;31m - red
\033[22;32m - green
\033[22;33m - brown
\033[22;34m - blue
\033[22;35m - magenta
\033[22;36m - cyan
\033[22;37m - gray
\033[01;30m - dark gray
\033[01;31m - light red
\033[01;32m - light green
\033[01;33m - yellow
\033[01;34m - light blue
\033[01;35m - light magenta
\033[01;36m - light cyan
\033[01;37m - white
Saturday, 19 November 2011
Use LD_PRELOAD to load another version library before running
LD_PRELOAD is a fantastic method to debug the code or library.
Basically, this just record other's work on the LD_PRELOAD and description. That's is fair enough, so I won't bored to modify that:
Basically, this just record other's work on the LD_PRELOAD and description. That's is fair enough, so I won't bored to modify that:
You Are Here
LD_PRELOAD fun
with 3 comments
Here is a welcome digression from my previous Twitter oriented posts. I’m starting to play around with the
Let’s start with a rather juvenile example. This will change the behavior of the read (2) function in order to make the user believe a file might have a different content.
If you compile this inside a library that is called, for example,
The subject of our next example will be the honorable ls (1).
The following example is a very simple override of the opendir (3) function which open a different directory than what the caller expects. I will explain more in detail the details of this function below.
In practice, calling
The next and final example of the use of
There is still a problem with this code on my new Ubuntu Hardy machine. The code from the preloaded library hangs before the program terminates. I do not understand why this happen and a search for this bug did not turn up anything. The problem doesn’t happen with Ubuntu Karmic.
There is nothing new about using
The code I have written for this demonstration is available on BitBucket.
LD_PRELOAD feature in the Linux dynamic linker. For those who might not know what this feature is, here is the description from ld.so (8).LD_PRELOAD
A whitespace-separated list of additional, user-specified, ELF
shared libraries to be loaded before all others. This can be
used to selectively override functions in other shared
libraries. For setuid/setgid ELF binaries, only libraries in
the standard search directories that are also setgid will be
loaded.
So in pratical term, any libraries you specify in the LD_PRELOAD environment variable will loaded before any system libraries. This means that dynamic symbols in a loading program will be first searched in those libraries before being searched anywhere else. This means you can override any defined symbol you want in standard libraries.Let’s start with a rather juvenile example. This will change the behavior of the read (2) function in order to make the user believe a file might have a different content.
ssize_t read(int fd, void *buf, size_t count) { static int done = 0; if (!done) { char silly_str[] = "Haha you got overriden.\n"; size_t s = count > sizeof(silly_str) ? sizeof(silly_str) : count; memcpy(buf, silly_str, s); done = 1; return s; } else return 0;} |
libread.so, you can test this code by running:> /bin/cat /etc/fstab # /etc/fstab: static file system information. # ... > LD_LIBRARY_PATH=. LD_PRELOAD=libread.so /bin/cat /etc/fstab Haha you got overriden.That in itself is just a rather silly prank you can play on your friend’s computer if you happen to have access to it. Experienced programmer will start seeing potential uses for
LD_PRELOAD. I am getting to that.The subject of our next example will be the honorable ls (1).
ls uses the opendir (3) function to open a directory and browse its files. It should react properly if it can’t open the directory. One way to test this is to make opendir() return NULL and observe how the caller reacts. You can do that using LD_PRELOAD.DIR *opendir(const char *name) { return NULL;} |
> LD_LIBRARY_PATH=. LD_PRELOAD=libls1.so /bin/ls /tmp /bin/ls: cannot open directory /tmpWhat can you do now if you want to preserve part of the behavior of the function, or modify they result it returns? Your preloaded library will then need to use
libdl to dynamically load the function it wants to modify the behavior.The following example is a very simple override of the opendir (3) function which open a different directory than what the caller expects. I will explain more in detail the details of this function below.
DIR *opendir(const char *name) { DIR *(*libc_opendir)(const char *name); *(void **)(&libc_opendir) = dlsym(RTLD_NEXT, "opendir"); return libc_opendir("/tmp");} |
libdl is fortunately very simple to use. The naive approach would be to use dlopen (3) to open the C library, then get the pointer to the function you are calling using dlsym (3). In theory, this technique is valid and working, but doing that circumvents the LD_PRELOAD mechanisme because preloaded libraries can be chained and calling directly into the C library prevents other caller to override our own function.In practice, calling
dlopen() on libc on an Ubuntu Karmic system made some program crash and burn for reasons I will not attempt to explain. The next technique should be preferred on Linux system, especially when dealing with the system C library.dlsym() has an option that makes the Linux dynamic linker search for the right symbol to be override. This is the RTLD_NEXT flag, which is to be used just for the purpose of wrapper dynamic library functions.libdl the task of returning the pointer to the right symbol. The RTLD_NEXT option to dlsym() returns the right symbol.The next and final example of the use of
LD_PRELOAD will still use the valiant ls. In time for Christmas, this will modify the output of ls by randomizing the d_type field returned in the dirent structure by readdir (3). If you use colorized ls output, and I believe most of you probably do, you should see a pretty display of color whenever you list a directory by preloading this function.struct dirent64 *readdir64(DIR *dir) { static struct dirent64 *(* libc_readdir64)(DIR *dir) = NULL; struct dirent64 *dent; unsigned char rnd_dtype[7] = { DT_UNKNOWN, DT_REG, DT_DIR, DT_FIFO, DT_SOCK, DT_CHR, DT_BLK }; if (libc_readdir64 == NULL) { *(void **)(&libc_readdir64) = dlsym(RTLD_NEXT, "readdir64"); srand(time(NULL)); } dent = libc_readdir64(dir); if (dent != NULL) dent->d_type = rnd_dtype[rand() % 7]; return dent;} |
There is nothing new about using
LD_PRELOAD this way. Several very nice libraries have been built with the intention of modifying the behavior of typical libraries.- fakeroot: “fakeroot provides a fake root environment by means of LD_PRELOAD and SYSV IPC (or TCP) trickery.”
- fakechroot: fakechroot provides a fake chroot environment to programs.
- libtrash:“[...] the shared library which, when preloaded, implements a trash can under GNU/Linux”
- cowdancer: cowdancer is an userland implementation of copy-on-write filesystem.
LD_PRELOAD on freshmeat.net. You might have used some of them.The code I have written for this demonstration is available on BitBucket.
Written by fdgonthier
January 11th, 2010 at 10:10 pm
January 11th, 2010 at 10:10 pm
Posted in Debian,Linux,Programming,Tips and Tricks
Tagged with bitbucket, libdl, Linux, opendir, preload
reference: http://www.lostwebsite.net/2010/01/ld_preload-fun/
Tagged with bitbucket, libdl, Linux, opendir, preload
reference: http://www.lostwebsite.net/2010/01/ld_preload-fun/
Subscribe to:
Posts (Atom)