Mixing static and dynamic linking

Due to some limitation of profiling software, it may be useful to link statically some libs into our programs. The following command links statically only lcrypto – while using dynamic linking on all other libs.

# gcc test.c -o test -Wl,-Bstatic -lcrypto -Wl,-Bdynamic

If you forget the ending -Wl,-Bdynamic you’ll get the following error:

 /usr/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status

This because gcc tries to link statically libgcc too – but using the wrong file: libgcc_s.a. To link statically libgcc you have to add the -static-libgcc flag

# gcc test.c -o test -Wl,-Bstatic -lcrypto  -static-libgcc

Logging a-la-printf with java

My C backgroud make me very unhappy when logging with java. I always have to type

log.info(String.format(“Logging field %s: with value: %d”, field, value));

Today I decide to extend the default log4j logger implementing my log.info & co using java varags.

I created two classes:

CustomLoggerFactory implements LoggerFactory:

  • @implement makeNewLoggerInstance(String name) return new MyLogger(name);

MyLogger extends Logger:

  • private MyLoggerFactory factory = new MyLoggerFactory();
  • @override getLogger(Class clazz)
  • info(String format, Object... params)

Now I can use MyLogger


MyLogger log = (MyLogger) MyLogger.getLogger(getClass());

log.info("Test base:string %s int %d" , "string", 0);

Further info here http://www.beknowledge.com/archives/article/extending-log4j-to-create-custom-logging-components

Send that message, quickly! (SystemV)

Thanks to ffiore I discovered a nice way for communicating data between processes and thread: Message Queues. MQs are a Linux feature that implement a kernel-based push-pop stack. Linux has two types of MQs: Posix and SystemV. This post is about SystemV.

Instead of reading/writing data to a standard pipe/socket where you have to manage the split of the messages and other issues, you can simply use MQs with the following pseudocode procedure:

# pusher thread

struct mq_msg msg;

msg.mtext = “my message”

mq = mq_create()

msgsnd(mq, msg, ..)

while the pop-er thread gets messages

# popper thread

msg = msgrcv(mq,..)

print msg.mtext

Linux provides some command line tools to manage the queue, while queue size is managed by sysctl and ulimit.

ananke # sysctl -a | grep msg

kernel.msgmnb = 65536 # max queue size = (msgsize*#msgs)

kernel.msgmni = 16

kernel.msgmax = 65536 # maximum  number  of  messages  in  a  queue.

fs.mqueue.msgsize_max = 8192 # maximum message size.

fs.mqueue.msg_max = 10

If we want to queue 10k messages of 12kbytes each, we should set:

# sysclt -w fs.mqueue.msgsize_max=12000

# sysclt -w kernel.msgmnb=120000000

You can view message queues with the #ipcs command:

ananke# sudo apt-get install util-linux

an MQ follows, containing 12 messages summing up 390 bytes

ananke #  ipcs -q

—— Message Queues ——–

key        msqid      owner      perms      used-bytes   messages

0x00000000 0          rpolli     666        390          13

For further info on System V and Posix MQs

#man svipc mq_overview

Guard your memory with Valgrind

Valgrind is an apt-and-play (or rpm-and-play) tool for finding memory leaks in your sw.

I recommend using it for code-reviewing and before deploying!

Just run it agains # ls -d /tmp

# valgrind  --leak-check=full --track-origins=yes ls -d /tmp

The output is [extract]

==27666== Memcheck, a memory error detector
==27666== Command: ls -d /tmp
/tmp
==27666== HEAP SUMMARY:
==27666==     in use at exit: 12,653 bytes in 8 blocks
==27666==   total heap usage: 1,396 allocs, 1,388 frees, 77,395 bytes allocated
==27666==
==27666== 120 bytes in 1 blocks are definitely lost in loss record 7 of 8
==27666==    at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==27666==    by 0x40CFACD: getdelim (in /lib/tls/i686/cmov/libc-2.10.1.so)
==27666==    by 0x405B73A: ??? (in /lib/libselinux.so.1)
==27666==    by 0x4064BFC: ??? (in /lib/libselinux.so.1)
==27666==    by 0x40530C7: ??? (in /lib/libselinux.so.1)
==27666==    by 0x400D8BB: ??? (in /lib/ld-2.10.1.so)
==27666==    by 0x400DA20: ??? (in /lib/ld-2.10.1.so)
==27666==    by 0x400088E: ??? (in /lib/ld-2.10.1.so)
==27666==
==27666== LEAK SUMMARY:
==27666==    definitely lost: 120 bytes in 1 blocks
==27666==    indirectly lost: 0 bytes in 0 blocks
==27666==      possibly lost: 0 bytes in 0 blocks
==27666==    still reachable: 12,533 bytes in 7 blocks
==27666==         suppressed: 0 bytes in 0 blocks
==27666== Reachable blocks (those to which a pointer was found) are not shown.
==27666== To see them, rerun with: --leak-check=full --show-reachable=yes
==27666==
==27666== For counts of detected and suppressed errors, rerun with: -v
==27666== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from 8)


Funnily we found ONE leak ;)

==27666== LEAK SUMMARY:
==27666==    definitely lost: 120 bytes in 1 blocks
==27666==    indirectly lost: 0 bytes in 0 blocks

ad it’s in

==27666== 120 bytes in 1 blocks are definitely lost in loss record 7 of 8
==27666==    at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==27666==    by 0x40CFACD: getdelim (in /lib/tls/i686/cmov/libc-2.10.1.so)
==27666==    by 0x405B73A: ??? (in /lib/libselinux.so.1)
...
==27666==    by 0x400088E: ??? (in /lib/ld-2.10.1.so)

but this time we shouldn’t care too much: ls is a one-shot command!

Comments welcome!