Improve DNS performance for Linux / Windows desktop using DNS caching software

One of my friend recently send me an email. It reads as follows:
"...My DSL service providers DNS server seems to be little slow, they have two servers it takes little time (some time upto 2 seconds) to resolve a domain name, once domain resolved, browsing speed remains the same, what should I do to improve DNS performance?...."
The answer is use a DNS proxy i.e. Dnsmasq. It is a a lightweight, easy to configure DNS forwarder and optional DHCP server. Dnsmasq is targeted at home networks using NAT and connected to the internet via a modem, cable-modem or ADSL connection but would be a good choice for any small network where low resource use and ease of configuration are important. The main use of the DNS proxy is to increase speed. Generally all computer send their request to ISP's DNS servers. But with DNS proxy request are cached. It stands between your local system and firewall server. Here is our sample network setup, 192.168.1.1-3 are all desktop system, 192.168.1.254 is our Linux firewall server:
Laptop | Desktop --> Linux Server --> ADSL Modem/Router
                   Firewall
192.168.1.1         192.168.1.254 -> Dynamic or
192.168.1.2                          Static IP assign
192.168.1.3                          by ISP
Login to your Linux firewall server and install Dnsmasq .

Step # 1 : Install Dnsmasq (Debian Linux)

# apt-get install dnsmasq
Fedora/Redhat/Centos user, use yum command to install dnsmasq:
# yum install dnsmasq
RedHat Linux user use rpm/up2date command to install it:
# up2date -i dnsmasq

Step # 2 Configure Dnsmasq

To be frank you don't have to change a single line in /etc/dnsmasq.conf. However you need to setup 127.0.0.1 as dns server name in /etc/resolve.conf file:
# vi /etc/resolve.conf
nameserver 127.0.0.1
nameserver 202.54.10.1
nameserver 202.54.20.1
Replace 202.54.10.1/202.54.20.1 with your actual ISP DNS server IPS. The dnsmasq should read the list of ISP nameservers from the automatically /etc/resolv.conf. You should list 127.0.0.1 as the first nameserver address in /etc/resolv.conf. So local desktop clients always gets cached queries.

Step # 3 Restart/start Dnsmasq

# /etc/init.d/dnsmasq start

Step # 4 Update DNS server IPS for all desktop systems

Point your windows XP or Linux Desktop client to IP of Linux firewall server i.e. 192.168.1.254 (see above network diagram)
It is easy to use Dnsmasq rather than setting up caching BIND server. But hold on it has some cool usage too. You can add domains which you want to force to specific IP address. For example, doubleclick.net displays ugly adds on many sites, just send this server it to our 127.0.0.1 (i.e. your local server ). Just open a file /etc/dnsmasq.conf and add following line to it:
address=/doubleclick.net/127.0.0.1
Restart Dnsmasq and make sure you runs local webserver at 127.0.0.1 with some default page. Read the Dnsmasq man page and docs for more information.

How To Flush Linux / UNIX DNS Cache

Under MS-Windows you can use the ipconfig command to flush dns cache. However, Linux and UNIX provides various ways to flush cache. Linux can run nscd or BIND or dnsmasq as the name service caching daemon. Large and work-group servers may use BIND or dnsmasq as a dedicated caching server to speed up queries.

HowTo: Flush nscd dns cache

Nscd caches libc-issued requests to the Name Service. If retrieving NSS data is fairly expensive, nscd is able to speed up consecutive access to the same data dramatically and increase overall system performance. Just restart nscd:
$ sudo /etc/init.d/nscd restart
OR
# service nscd restart
OR
# service nscd reload
This daemon provides a cache for the most common name service requests. The default configuration file, /etc/nscd.conf, determines the behavior of the cache daemon.

Flush dnsmasq dns cache

dnsmasq is a lightweight DNS, TFTP and DHCP server. It is intended to provide coupled DNS and DHCP service to a LAN. Dnsmasq accepts DNS queries and either answers them from a small, local, cache or forwards them to a real, recursive, DNS server. This software is also installed many cheap routers to cache dns queries. Just restart the dnsmasq service to flush out dns cache:
$ sudo /etc/init.d/dnsmasq restart
OR
# service dnsmasq restart

Flush caching BIND server dns cache

A caching BIND server obtains information from another server (a Zone Master) in response to a host query and then saves (caches) the data locally. All you have to do is restart bind to clear its cache:
# /etc/init.d/named restart
You can also use rndc command as follows flush out all cache:
# rndc restart
OR
# rndc exec
BIND v9.3.0 and above will support flushing all of the records attached to a particular domain name with rndc flushname command. In this example flush all records releated to cyberciti.biz domain:
# rndc flushname cyberciti.biz
It is also possible to flush out BIND views. For example, lan and wan views can be flushed using the following command:
# rndc flush lan
# rndc flush wan

A note about Mac OS X Unix users

Type the following command as root user:
# dscacheutil -flushcache
OR
$ sudo dscacheutil -flushcache
If you are using OS X 10.5 or earlier try the following command:
lookupd -flushcache

A note about /etc/hosts file

/etc/hosts act as the static table lookup for hostnames. You need to remove and/or update records as per your requirements under Unix like operating systems:
# vi /etc/hosts
Sample outputs:
127.0.0.1 localhost
127.0.1.1 wks01.WAG160N wks01
# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.37.34.2     build
192.168.1.10 nas01
192.168.1.11 nas02
192.168.1.12 nas03
#192.168.2.50 nfs2.nixcraft.net.in nfs2
#192.168.2.51 nfs1.nixcraft.net.in nfs1
172.168.232.50  nfs1.nixcraft.net.in nfs1
172.168.232.51  nfs2.nixcraft.net.in nfs2
192.168.1.101 vm01

Error:conversion from ‘A’ to non-scalar type ‘B’ requested

Error:conversion from ‘A’ to non-scalar type ‘B’ requested

今天遇到了下面的问题:
error: conversion from ‘std::map, std::map, std::basic_string > >::const_iterator’ to non-scalar type ‘TextColors::ColorStylesIter’ requested
std::string TextColors::GetTextColor(std::string &styleName, std::string &textKind)const
{
    ColorStylesIter colorStylesIter = colorStyles.find(styleName);
    ……………………
}
在TextColors类的头文件中有:
typedef std::map ColorStyles;
typedef std::map::iterator ColorStylesIter;
错误的原因是:该成员函数(GetTextColor)是const成员函数,所以colorStyles.find(styleName)的返回值为const_iterator.
修改方法:在TextColors类的头文件中添加:
typedef std::map::const_iterator ColorStylesConstIter;
在GetTextColor的实现中使用ColorStylesConstIter;

下面的解答来自:http://topic.csdn.net/u/20110406/09/c17252ce-d022-404b-bcd0-90e10a4b7362.html
1.)
class base
{};
int main()
{
base b;//这个实例和下面的产生实例的方法的区别是什么阿 ?
base *b2 = new base();//
return 0;
}
2)
这里面的这个翻译 non-scalar type怎么翻译阿 ?
base.cpp:11: error: conversion from ‘base*’ to non-scalar type ‘base’ requested
答:
scalar在物理或者数学里面就是“标量”(即一个纯粹的数值)的意思。non-scalar type就是“非标量的数据类型”。
指针(base*)只是一个int,因此就是标量。
对象(base)不是一个简单的数值,因此就是非标量。
“conversion from ‘base*’ to non-scalar type ‘base’ requested”的意思:
要求提供从‘base*’到非标量数据类型‘base'的转换。

Magic cache line padding

The CPU is the heart of your machine and the thing that ultimately has to do all the operations, executing your program.  Main memory (RAM) is where your data (including the lines of your program) lives.  We're going to ignore stuff like hard drives and networks here because the Disruptor is aimed at running as much as possible in memory.

The CPU has several layers of cache between it and main memory, because even accessing main memory is too slow.  If you're doing the same operation on a piece of data multiple times, it makes sense to load this into a place very close to the CPU when it's performing the operation (think a loop counter - you don't want to be going off to main memory to fetch this to increment it every time you loop around).


The closer the cache is to the CPU, the faster it is and the smaller it is.  L1 cache is small and very fast, and right next to the core that uses it.  L2 is bigger and slower, and still only used by a single core.  L3 is more common with modern multi-core machines, and is bigger again, slower again, and shared across cores on a single socket.  Finally you have main memory, which is shared across all cores and all sockets.

When the CPU is performing an operation, it's first going to look in L1 for the data it needs, then L2, then L3, and finally if it's not in any of the caches the data needs to be fetched all the way from main memory.  The further it has to go, the longer the operation will take.  So if you're doing something very frequently, you want to make sure that data is in L1 cache.

Martin and Mike's QCon presentation gives some indicative figures for the cost of cache misses:

Latency from CPU to...Approx. number of
CPU cycles
Approx. time
in nanoseconds
Main memory~60-80ns
QPI transit
(between sockets, not drawn)
~20ns
L3 cache~40-45 cycles,~15ns
L2 cache~10 cycles,~3ns
L1 cache~3-4 cycles,~1ns
Register1 cycle

If you're aiming for an end-to-end latency of something like 10 milliseconds, an 80 nanosecond trip to main memory to get some missing data is going to take a serious chunk of that.

Cache lines
Now the interesting thing to note is that it's not individual items that get stored in the cache - i.e. it's not a single variable, a single pointer.  The cache is made up of cache lines, typically 64 bytes, and it effectively references a location in main memory.  A Java long is 8 bytes, so in a single cache line you could have 8 long variables.


(I'm going to ignore the multiple cache-levels for simplicity)

This is brilliant if you're accessing an array of longs - when one value from the array gets loaded into the cache, you get up to 7 more for free.  So you can walk that array very quickly.  In fact, you can iterate over any data structure that is allocated to contiguous blocks in memory very quickly.  I made a passing reference to this in the very first post about the ring buffer, and it explains why we use an array for it.

So if items in your data structure aren't sat next to each other in memory (linked lists, I'm looking at you) you don't get the advantage of freebie cache loading.  You could be getting a cache miss for every item in that data structure.

However, there is a drawback to all this free loading.  Imagine your long isn't part of an array.  Imagine it's just a single variable.  Let's call it head, for no real reason.  Then imagine you have another variable in your class right next to it.  Let's arbitrarily call it tail.  Now, when you load head into your cache, you get tail for free.


Which sounds fine.  Until you realise that tail is being written to by your producer, and head is being written to by your consumer.  These two variables aren't actually closely associated, and in fact are going to be used by two different threads that might be running on two different cores.


Imagine your consumer updates the value of head.  The cache value is updated, the value in memory is updated, and any other cache lines that contain head are invalidated because other caches will not have the shiny new value.  And remember that we deal with the level of the whole line, we can't just mark head as being invalid.


Now if some process running on the other core just wants to read the value of tail, the whole cache line needs to be re-read from main memory.  So a thread which is nothing to do with your consumer is reading a value which is nothing to do with head, and it's slowed down by a cache miss.

Of course this is even worse if two separate threads are writing to the two different values. Both cores are going to be invalidating the cache line on the other core and having to re-read it every time the other thread has written to it. You've basically got write-contention between the two threads even though they're writing to two different variables.

This is called false sharing, because every time you access head you get tail too, and every time you access tail, you get head as well.  All this is happening under the covers, and no compiler warning is going to tell you that you just wrote code that's going to be very inefficient for concurrent access.

Our solution - magic cache line padding
You'll see that the Disruptor eliminates this problem, at least for architecture that has a cache size of 64 bytes or less, by adding padding to ensure the ring buffer's sequence number is never in a cache line with anything else.

public long p1, p2, p3, p4, p5, p6, p7; // cache line padding
    private volatile long cursor = INITIAL_CURSOR_VALUE;
    public long p8, p9, p10, p11, p12, p13, p14; // cache line padding

So there's no false sharing, no unintended contention with any other variables, no needless cache misses.

It's worth doing this on your Entry classes too - if you have different consumers writing to different fields, you're going to need to make sure there's no false sharing between each of the fields.

How to repair clipboard functionality in Citrix XenApp and is it time to enable the fix by default?

The issue

Many people have encountered problems with clipboard (cut and paste) not working in Citrix XenApp ( formerly Presentation server/Metaframe) environment.

The cause

A not well behaving non-Citrix application can interfere with clipboard operation and cause problems with XenApp. A complete fix would require changes to the windows operating system.

Workaround exists but has limitations.

My colleague Dmitry Vostokov wrote a tool called RepairCBDChain to work around the issue. It works, but it is not easy to use, especially for end users.

A fix was incorporated in XenApp plugin (client)

Back in 2005 when I was still in Engineering department, I started tacking this problem. I found it a challenging but fun problem to solve since I can’t modify bad third party applications nor the operating system. And the problem happens intermittently.
After quite some effort, I found a way to allow the XenApp Plugin to detect broken clipboard and fix it automatically. I was happy and thought my job was done.
Here is the detailed information about the fix. The fix has been included in XenApp plugin (client) since 2005 version 9.100.
Our internal tests showed that the fix was effective. Some people in our support forum and blog have also reported successful use of my fix.

The fix is disabled by default unfortunately and was not well publicized.

The story didn’t end though. To reduce potential side effects, the feature was disabled by default. I didn’t agree with the decision but went alone. Unfortunately, the fix was buried in long release notes and not well publicized. As a result, not many people seem to know about the fix, including even XenApp experts. For example please see the comment section of this blog dated 2008 . And this blog. Another evidence is that RepairCBDChain is still one of the top downloaded knowledge base articles recently. I am disappointed that users haven’t benefited as much from my hard work as they should have been.

Should it be enabled by default now?

I wonder if this fix should be enabled by default now. After all, what good is a fix if people don’t know how to take advantage of it? In my opinion, the fix doesn’t have much risk. If it does have bad side effects, after all these years, people would have reported problems with the fix already. What do you think?

Related articles.

Citrix KB articles about clipboard issues

http://support.citrix.com/article/CTX104631
Articles about RepairCBDChain tool.

What is a 'thunk'?

thunk usually refers to a small piece of code that is called as a function, does some small thing, and then JUMPs to another location (usually a function) instead of returning to its caller. Assuming the JUMP target is a normal function, when it returns, it will return to the thunk's caller.
Thunks can be used to implement lots of useful things efficiently
  • protocol translation -- when calling from code that uses one calling convention to code that uses a different calling convention, a thunk can be used to translate the arguments appropriately. This only works if the return conventions are compatable, but that is often the case
  • virtual function handling -- when calling a virtual function of a multiply-inherited base class in C++, there needs to be a fixup of the this pointer to get it to point to the right place. A thunk can do this.
  • dynamic closures -- when you build a dynamic closure, the closure function needs to be able to get at the context where it was created. A small thunk can be built (usually on the stack) which sets up the context info in some register(s) and then jumps to a static piece of code that implements the closure's function. The thunk here is effectively supplying one or more hidden extra arguments to the function that are not provided by the call site.

Shared libraries and execute permissions

n the few discussions you can find on the web about shared-libraries and execute-permissions, you can find a range of various opinions but not a lot about what goes when you execute a library.
The first thing to consider is how the execute-permission interacts with the dynamic loader. When mapping a library, the dynamic-loader doesn't care about file-permissions; it cares about mapping specific internal parts of the .so. Specifically, it wants to map the PT_LOAD segments as-per the permissions specified by the program-header. A random example:
 $ readelf --segments /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0

Elf file type is DYN (Shared object file)
Entry point 0x77c00
There are 7 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000001b5ea4 0x00000000001b5ea4  R E    200000
  LOAD           0x00000000001b6b60 0x00000000003b6b60 0x00000000003b6b60
                 0x0000000000028dc4 0x000000000002c998  RW     200000
The permissions to load the code and data segments are given the Flags output. Code has execute-permissions, and data has write-permissions. These flags are mapped into flags for the mmap call, which the loader then uses to map the various segments of the file into memory.
So, do you actually need execute-permissions on the underlying file to mmap that segment as executable? No, because you can read it. If I can read it, then I can copy the segment to another area of memory I have already mapped with PROT_EXEC and execute it there anyway.
Googling suggests that some systems do require execute-permissions on a file if you want to directly mmap pages from it with PROT_EXEC (and if you dig into the kernel source, there's an ancient system call uselib that looks like it comes from a.out days, given it talks about loading libraries at fixed addresses, that also wants this). This doesn't sound like a terrible hardening step; I wouldn't be surprised if some hardening patches require it. Maximum compatability and historical-features such as a.out also probably explains why gcc creates shared libraries with execute permissions by default.
Thus, should you feel like it, you can run a shared-library. Something trivial will suffice:
int function(void) {
      return 100;
}
$ gcc -fPIC -shared -o libfoo.so foo.c

$ ./libfoo.so
Segmentation fault
This is a little more interesting (to me anyway) to dig into. At a first pass, why does this even vaguely work? That's easy -- an ELF file is an ELF file, and the kernel is happy to map those PT_LOAD segments in and jump to the entry point for you:
$ readelf --segments ./libfoo.so

Elf file type is DYN (Shared object file)
Entry point 0x570
There are 6 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x000000000000070c 0x000000000000070c  R E    200000
  LOAD           0x0000000000000710 0x0000000000200710 0x0000000000200710
                 0x0000000000000238 0x0000000000000240  RW     200000
What's interesting here is that the shared-library has an entry point (e_entry) at all. ELF defines it as:
This member gives the virtual address to which the system first transfers control, thus starting the process. If the file has no associated entry point, this member holds zero.
First things first, where did that entry point come from? The ld manual tells us that the linker will set the entry point based upon the following hierarchy:
  • the -e entry command-line option;
  • the ENTRY(symbol) command in a linker script;
  • the value of a target specific symbol
  • the address of the first byte of the .text section, if present;
  • The address 0.
We know we're not specifying an entry point. The ENTRY command is interesting; we can check our default-link script to see if that is specified:
$ ld --verbose | grep ENTRY
ENTRY(_start)
Interesting. Obviously we didn't specify a _start; so do we have one? A bit of digging leads to the crt files, for C Run-Time. These are little object files automatically linked in by gcc that actually do the support-work to get a program to the point that main is ready to run.
So, if we go and check out the crt files, one can find a definition of _start in crt1.o
$ nm /usr/lib/x86_64-linux-gnu/crt1.o
crt1.o:
0000000000000000 R _IO_stdin_used
0000000000000000 D __data_start
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
0000000000000000 T _start
0000000000000000 W data_start
                 U main
But do we have that for our little shared-library? We can get a feel for what gcc is linking in by examining the output of -dumpspecs. Remembering gcc is mostly just a driver that calls out to other things, a``specs`` file is what gcc uses to determine which arguments pass around to various stages of a compile:
$ gcc -dumpspecs
...
*startfile:
%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}
 crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}
The format isn't really important here (of course you can read about it); but the gist is that various flags, such as -static or -pie get passed different run-time initailisation helpers to link-in. But we can see that if we're creating a shared library we won't be getting crt1.o. We can double-confirm this by checking the output of gcc -v (cut down for clarity).
$ gcc -v -fPIC -shared -o libfoo.so foo.c
Using built-in specs.
 ...
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2 -shared -o libfoo.so
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbeginS.o
/tmp/ccRpsQU3.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtendS.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o
So this takes us further down ld's entry-point logic to pointing to the first bytes of .text, which is where the entry-point comes from. So that solves the riddle of the entry point.
There's one more weird thing you notice when you run the library, which is the faulting address in kern.log:
libfoo.so[8682]: segfault at 1 ip 0000000000000001 sp 00007fffcd63ec48 error 14 in libfoo.so[7f54c51fa000+1000]
The first thing is decoding error; 14 doesn't seem to have any relation to anything. Of course everyone has the Intel 64 Architecture Manual (ormm/fault.c that also mentions the flags) to decode this into 1110 which means "no page found for a user-mode write access with reserved-bits found to be set" (there's another post in all that someday!).
So why did we segfault at 0x1, which is an odd address to turn up? Let's disassemble what actually happens when this starts.
00000000000004a0 <call_gmon_start>:
 4a0:   48 83 ec 08             sub    $0x8,%rsp
 4a4:   48 8b 05 2d 03 20 00    mov    0x20032d(%rip),%rax        # 2007d8 <_dynamic x190="">
 4ab:   48 85 c0                test   %rax,%rax
 4ae:   74 02                   je     4b2 
 4b0:   ff d0                   callq  *%rax
 4b2:   48 83 c4 08             add    $0x8,%rsp
 4b6:   c3                      retq
We're moving something in rax and testing it; if true we call that value, otherwise skip and retq. In this case, objdump is getting a bit confused telling us that 2007d8 is related to _DYNAMIC; in fact we can check the relocations to see it's really the value of __gmon_start__:
$ readelf --relocs ./libfoo.so

Relocation section '.rela.dyn' at offset 0x3f0 contains 4 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000200810  000000000008 R_X86_64_RELATIVE                    0000000000200810
0000002007d8  000200000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
0000002007e0  000300000006 R_X86_64_GLOB_DAT 0000000000000000 _Jv_RegisterClasses + 0
0000002007e8  000400000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize + 0

Relocation section '.rela.plt' at offset 0x450 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000200808  000400000007 R_X86_64_JUMP_SLO 0000000000000000 __cxa_finalize + 0
Thus call_gmon_start, rather unsurprisingly, checks the value of __gmon_start__ and calls it if it is set. Presumably this is set as part of profiling and called during library initialisation -- but it is clearly not an initialiser by itself. The retq ends up popping a value off the stack and jumping to it, which in this case just happens to be 0x1 -- which we can confirm with gdb by putting a breakpoint on the first text address and examining the stack-pointer:
(gdb) x/2g $rsp
0x7fffffffe7d8:        0x0000000000000000      0x0000000000000001
So that gives us our ultimate failure.
Of course, if you're clever, you can get around this and initalise yourself correctly and actually make your shared-library do something when executed. The canonical example of this is libc.so itself:
$ /lib/x86_64-linux-gnu/libc-2.13.so
GNU C Library (Debian EGLIBC 2.13-37) stable release version 2.13, by Roland McGrath et al.
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
...
You can trace through how this actually does work in the same way as we traced through why the trivial example doesn't work.
If you wondering my opinion on executable-bits for shared-libraries; I would not give them execute permissions. I can't see it does anything but open the door to confusion. However, understanding exactly why the library segfaults the way it does actually ends up being a fun little tour around various parts of the toolchain!

How to run a shared library on Linux

In my prevoius blog I have written how to run the shared libraries on
Open-Solaris.
http://bhushanverma.blogspot.com/2008/06/how-to-run-shared-library-on-open.html
Shared object should have following entries to run:
1. +x permission that is by default is given by the static
linker(program linker) when creating a shared object.
2. Entry point at which the program/shared library is starts to run.
3. Interpreter(Run time linker) that is used to run any shared library
after loaded by kernel part exec().
Entry point at which the program/shared library is starts to run can be
given by passing -Wl,-e entry_point to the linker at command line:
To create .interp section by using GNU gcc, use the follwing line of
code on linux:
const char my_interp[] __attribute__((section(".interp"))) =
"/lib/ld-linux.so.2";
Where /lib/ld-linux.so.2 is the path of interpreter(Run time linker)  in linux.
In open solaris we passed -Wl,-I,/usr/lib/ld.so.1 to the sun linker to
create this section.
I think in gnu linker this option is available but do other things.
Demo on Linux machine:
-------------------------
$ cat func.c
const char my_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
void bar();

int func() {
    printf("Hacking\n");
    bar();
    exit (0);
}

void bar() {
    printf("Bye...\n");
}
$ gcc -fPIC -o func.so -shared -Wl,-e,func func.c
You can see that foo.so have .interp section and interp program header.
# readelf -l func.so
Elf file type is DYN (Shared object file)
Entry point 0x4dc
There are 7 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x000e0 0x000e0 R E 0x4
INTERP 0x0005a3 0x000005a3 0x000005a3 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x00000000 0x00000000 0x005bc 0x005bc R E 0x1000
LOAD 0x0005bc 0x000015bc 0x000015bc 0x00104 0x0010c RW 0x1000
DYNAMIC 0x0005d4 0x000015d4 0x000015d4 0x000c0 0x000c0 RW 0x4
NOTE 0x000114 0x00000114 0x00000114 0x00024 0x00024 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version
.gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata
.interp .eh_frame
03 .ctors .dtors .jcr .data.rel.ro .dynamic .got .got.plt .bss
04 .dynamic
05 .note.gnu.build-id
06
You can cleary see, func.so have .interp section and INTERP program header.
Now try to run func.so:
$ ./func.so
Hacking
Bye...

我的程序我做主--不改代码让只读数据可写

什么情况下,下面这个foo()  函数会返回一个 "Aello  world" 的指针, 而不会运行报错
char *foo()
{
    char* p = (char*)"Hello world";

    p[0] = 'A';

    return p;
}

(运行环境: linux )
很多公司的笔试题里,都认为这段代码是肯定执行出错的。不过某些时候,还是可以继
续运行的。

========================================================
基于我对ELF的理解,稍稍研究了一下,结果如下:

这个返回出错是因为"Hello world"会被放到.rodata里面。
kinwin@ustc-king:/tmp$ cat tt.c
char * foo(){
    char *a = (char *)"Hello  world\n";
    a[0] = 'A';
    return a;
}

kinwin@ustc-king:/tmp$ cc -c tt.c
kinwin@ustc-king:/tmp$ objdump -d tt.o

tt.o:     file format elf32-i386


Disassembly of section .text:

00000000
   0:   55                      push   p
   1:   89 e5                   mov    %esp,p
   3:   83 ec 10                sub    $0x10,%esp
   6:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(p)
   d:   8b 45 fc                mov    -0x4(p),x
  10:   c6 00 41                movb   $0x41,(x)
  13:   8b 45 fc                mov    -0x4(p),x
  16:   c9                      leave  
  17:   c3                      ret  
这里的"Hello World"会生成一个重定位表项
 kinwin@ustc-king:/tmp$ readelf -r tt.o

Relocation section '.rel.text' at offset 0x31c contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000009  00000501 R_386_32          00000000   .rodata
链接的时候把这个.rodata中的字符串地址填入那堆0的地方。

产生segment fault的原因就是指针指的是.rodata中的内容,而.rodata的段属性是
ALLOC,不带WRITE和EXECUTE,这样在load的时候生成的vm_area_struct也是只读属性的
,写其中的内容自然会在vm_area_struct那里被捕获,然后被sigsegv了。

要让它可写也是Ok的,最根本的就是让它写的时候对应地址的vm_area_struct属性是可
写的,pte层面应该都是可写的。就有几种办法了
1. loader载入elf文件是根据elf的program header来生成对应的vm_area_struct的,其
中默认是两个,一个可读可执行,一个可读可写,.rodata落在了第一块。
因此,法一, program header table的映射关系让.rodata这个section映射到
program header的可读可写块即可

或者,法二:干脆在链接的时候让各目标文件的.rodata连接到.data这个section来(任
一program header中映射的可读可写区域),而.data load的时候是可读可写的,如:
链接脚本如此写:
 .data           :
    *(.rodata)
    *(.data .data.* .gnu.linkonce.d.*)
kinwin@ustc-king:/tmp$ gcc test.c -Wl,-T,ld.ver -o test.out
kinwin@ustc-king:/tmp$ ./test.out
Aello  world

法三: 提示gcc在生成目标文件的时候不放入.rodata,而是放入.data,不知道gcc有无
这样的选项

法四:以上都为修改elf文件输出,也可以在运行时写只读区域之前,把对应的区域用
mprotect把权限改了

Right-click is slow or weird behavior caused by context menu handlers

Symptoms

  1. When you right-click a file/folder, there may be a huge delay before Windows displays the context menu.
  2. When you try to empty Recycle Bin (from Common Tasks), it opens Quick Finder instead.
  3. When you click Play All in the Music or Videos folder Common Tasks, nothing may happen.
  4. When you select multiple files and right click and open / print nothing happens. Whereas, selecting a single file in explorer and right click and open / print, it works fine.
  5. When you right-click a folder in the Start Menu and choose Open or Explore, nothing may happen. (Whereas, it works fine in Windows Explorer.)
  6. Error message "Windows Explorer has encountered a problem and needs to close. We are sorry for the inconvenience" when you right-click a folder.
  7. Right-click is extremely slow only when the network card is enabled.
  8. When you right-click on a folder and choose Properties, nothing may happen.
  9. Your image editing program does not start when you click the Edit button in Windows Picture and Fax Viewer.
  10. Data Execution Prevention (DEP) error occurs when Windows Explorer or Control Panel is launched.
  11. Nothing happens when you click Slideshow or Print in the Tasks pane in Windows Vista.
  12. Unable to launch applications (mainly Windows Installer shortcuts) from the recent programs list in the Windows Vista Start menu.
  13. Device Manager link in the tasks pane does not work in Windows Vista
  14. When you click "Set up backup" or click "Change settings" in Windows 7 Backup and Restore, nothing happens or the System32 folder opens.

Cause

These problems are caused by a bad context menu handler. A context menu handler is a shell extension handler that adds commands to an existing context menu (Example: cut, copy, paste, print, Scan with Norton etc). A poorly coded context menu handler may be causing any of the above symptoms. As context menu handlers can be added in different areas (file class, folder, allfilesystemobjects, HKCR\* registry keys), it's a difficult task for an end-user to pinpoint which shell extension is causing the problem.

Resolution

This article describes the two methods to identify the problematic shell extension.Method 1 involves direct registry editing, which is for advanced users. Method 2 is user-friendly and suits most users (recommended method)
Method 1 is for advanced users. If you are not confident about dealing with registry, proceed to Method 2.

Method 1

First, isolate the problem. Observe when the problem occurs. While right-clicking a particular file type? While right-clicking Folders? While right-clicking all file types? As said earlier, context menu handlers can load from any of these areas:
Registry KeyDescription
HKCR \*\shellex\contextmenuhandlersFiles
HKCR\AllFileSystemObjects\shellex\ contextmenuhandlersFiles and file folders
HKCR\Folder\shellex\contextmenuhandlersFolders
HKCR\Directory\shellex\contextmenuhandlersFile Folders
HKCR\\shellex\contextmenuhandlersFile class
HKCR\Directory\Background\shellex\ContextMenuHandlersDesktop
If any of the symptoms occur when you deal with a folder, then you may need to inspect the context menu handlers loaded in these areas (AllFileSystemObjects, Folder, Directory). If it's only for a .txt file, inspect the file class of .txt file (HKCR\txtfile). Open Registry Editor and backup the selected branch, delete the context menu handlers one-by-one.

Method 2 - Using ShellExView to determine the Context-menu causing the problem

shellexview.JPG (54542 bytes)ShellExView (by Nir Sofer) is an excellent tool  to view and manage all installed shell extensions. If available, it displays the description, as well as version details, company information, location, file name and more. You can optionally disable/enable any item, which can be very useful to disable an extension, that you don t need or that has been left behind in your right click menu from a previous software install.
Effective usage of ShellExView to resolve right-click problems
Download ShellExView (from nirsoft.net) and run it. It will scan the registry for all the shell extensions. Once the scan is over and the list is displayed, you need to spot the context menu handlers. Sort the results using "Type", so that the context menu handlers are displayed together.
The rule is to disable non-Microsoft context menu handlers *one-by-one* and verify if the problem is solved. If disabling one does not solve the problem, undo the disabled item and disable the next non-Microsoft handler. Do the same until the problem is solved and finally identify the culprit. Scroll right to see the Company Name column in ShellExView.
Even more quicker method is to bisect the list of context menu handlers into two groups, disabling half of the entries at a stretch, rebooting and testing the behavior again. JClarke commented on this article:
You can disable them ...they say "one at a time" and see what effect it has on the problem. I did it a lot quicker by bisecting the list, disabling half of the entries in one fell swoop, rebooting and trying the right click.
It worked, so I knew I just had to narrow it down, just as we used to do with msconfig. Then I kept bisecting the list until it was just a few and did those one at a time. The problem is that you have to reboot between tries to get accurate testing of the results of your disabling. I didn't find logging off to be consistent.

Problems when you right-click an empty area in the Desktop?

If you have a problem when you right-click on a blank area on the Desktop, then you need to inspect the handlers in this registry key. (ShellExView v1.14 and later versions enumerate the items from this location)
HKEY_CLASSES_ROOT \ Directory \ Background  \ shellex \ ContextMenuHandlers
The only handler present by default (in a clean XP installation) is the New handler. If you find any additional sub-keys there, it may have be added by third-party applications. Usually, the software that comes with your graphic card adds entries to the above location. Here is one instance, an article from the Intel Graphics Controller website.
Thanks to Cliff for sending this link:
NOTE:  It's not always the Context menu handler,  but a PropertySheet handler or an Icon Handler may be the culprit sometimes. Some readers have reported that the Property Sheet handler "IIS W3ext Module" was responsible for the folder properties issue (See Case:8 in the Symptoms section above), in a Windows XP Professional system, and that reinstalling IISfrom Add/Remove Windows Components fixed the problem.
In one peculiar case, the system file shimgvw.dll (Shell Image Verbs - {e84fda7c-1d6a-45f6-b725-cb260c236066}) itself causing the problem. In case of system files, try running sfc /scannow to fix the problem.