Use Intellij IDEA as a Golang IDE

My Intellij IDEA is v15.0.1 community edition, and has been installed with golang-plugin. My Golang workspace is like this:

GOPATH=C:\Work\gocode

(1) Select “Create New Project“:

1

(2) Select “Go“, then “Next“:

2

(3) Select “SDK“, then “Next“:

3

(4) The important step coming! The up setting is for storing IDEA project files, while the down is for Golang workspace, then “Finish“:

4

(5) Now, use Intellij IDEA as a Golang IDE:

5
Enjoy it!

Set proxy for Maven

Sometimes, your Maven needs proxy to download object:

[INFO] Scanning for projects...
Downloading: http://repo.maven.apache.org/maven2/org/apache/apache/11/apache-11.pom
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project org.apache.mesos:mesos:0.25.0 (/home/nan/mesos-0.25.0/build/src/java/mesos.pom) has 1 error
[ERROR]     Non-resolvable parent POM: Could not transfer artifact org.apache:apache:pom:11 from/to central (http://repo.maven.apache.org/maven2): Connection to http://repo.maven.apache.org refused and 'parent.relativePath' points at wrong local POM @ line 18, column 11: Connection timed out -> [Help 2]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException

The method is configuring proxy setting in ${HOME}/.m2/settings.xml:

$ echo ${HOME}
/home/nan
$ cat ${HOME}/.m2/settings.xml
<settings>
        <proxies>
                <proxy>
                        <active>true</active>
                        <protocol>http</protocol>
                        <host>web-proxy.xxxxxx.com</host>
                        <port>8080</port>
                </proxy>
        </proxies>
</settings>

Then it can work!

P.S. My Maven version is 3.0.5.

 

SystemTap needs debug-info package when user-space probing

SystemTap needs debug-info package when user-space probing.E.g.:

 # stap -d /bin/ls --ldd -e 'probe process("ls").function("xmalloc") {print_usyms(ubacktrace())}' -c "ls /"
semantic error: while resolving probe point: identifier 'process' at <input>:1:7
        source: probe process("ls").function("xmalloc") {print_usyms(ubacktrace())}
                      ^

semantic error: no match (similar functions: malloc, calloc, realloc, close, mbrtowc)
Pass 2: analysis failed.  [man error::pass2]

Install coreutils-debuginfo package:

# zypper in coreutils-debuginfo
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following NEW package is going to be installed:
  coreutils-debuginfo

The following package is not supported by its vendor:
  coreutils-debuginfo

1 new package to install.
Overall download size: 2.1 MiB. Already cached: 0 B. After the operation, additional 18.6 MiB will be used.
Continue? [y/n/? shows all options] (y): y
Retrieving package coreutils-debuginfo-8.22-9.1.x86_64                                                (1/1),   2.1 MiB ( 18.6 MiB unpacked)
Retrieving: coreutils-debuginfo-8.22-9.1.x86_64.rpm ...................................................................[done (105.3 KiB/s)]
Checking for file conflicts: ........................................................................................................[done]
(1/1) Installing: coreutils-debuginfo-8.22-9.1 ......................................................................................[done]

Then execute the stap command again:

# stap -d /bin/ls --ldd -e 'probe process("ls").function("xmalloc") {print_usyms(ubacktrace())}' -c "ls /"
bin  boot  dev  etc  home  lib  lib64  lost+found  mnt  opt  proc  root  run  sbin  selinux  srv  sys  tmp  usr  var
 0x4114a0 : xmalloc+0x0/0x20 [/usr/bin/ls]
 0x411674 : xmemdup+0x14/0x30 [/usr/bin/ls]
 0x40ee4a : clone_quoting_options+0x2a/0x40 [/usr/bin/ls]
 0x403828 : main+0xa58/0x2140 [/usr/bin/ls]
 0x7fad37eefb05 : __libc_start_main+0xf5/0x1c0 [/lib64/libc-2.19.so]
 0x404f39 : _start+0x29/0x30 [/usr/bin/ls]
 0x4114a0 : xmalloc+0x0/0x20 [/usr/bin/ls]
 0x411674 : xmemdup+0x14/0x30 [/usr/bin/ls]
 0x40ee4a : clone_quoting_options+0x2a/0x40 [/usr/bin/ls]
 0x403887 : main+0xab7/0x2140 [/usr/bin/ls]
 0x7fad37eefb05 : __libc_start_main+0xf5/0x1c0 [/lib64/libc-2.19.so]
 0x404f39 : _start+0x29/0x30 [/usr/bin/ls]
 0x4114a0 : xmalloc+0x0/0x20 [/usr/bin/ls]
 0x4039e4 : main+0xc14/0x2140 [/usr/bin/ls]
 0x7fad37eefb05 : __libc_start_main+0xf5/0x1c0 [/lib64/libc-2.19.so]
.....

It works now!

 

Why doesn’t Linux device driver need to update file position in read/write functions?

From LDD3, “char drivers” section:

loff_t f_pos;

The current reading or writing position. loff_t is a 64-bit value on all platforms ( long long in gcc terminology). The driver can read this value if it needs to know the current position in the file but should not normally change it; read and write should update a position using the pointer they receive as the last argument instead of acting on filp->f_pos directly. The one exception to this rule is in the llseek method, the purpose of which is to change the file position.

Why “read and write should update a position using the pointer they receive as the last argument instead of acting on filp->f_pos directly“? After checking the kernel code(the version is 3.0), I get the answer.

Use read system call as an example, and others are similar. Firstly, check read code (fs/read_write.c):

SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
    struct file *file;
    ssize_t ret = -EBADF;
    int fput_needed;

    file = fget_light(fd, &fput_needed);
    if (file) {
        loff_t pos = file_pos_read(file);
        ret = vfs_read(file, buf, count, &pos);
        file_pos_write(file, pos);
        fput_light(file, fput_needed);
    }

    return ret;
}

The core part is the following part:

loff_t pos = file_pos_read(file);
ret = vfs_read(file, buf, count, &pos);
file_pos_write(file, pos);

file_pos_read is very simple, just one statement:

static inline loff_t file_pos_read(struct file *file)
{
    return file->f_pos;
}

It returns the current file position.

Then let we see the vfs_read:

ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
    ssize_t ret;

    if (!(file->f_mode & FMODE_READ))
        return -EBADF;
    if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read))
        return -EINVAL;
    if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
        return -EFAULT;

    ret = rw_verify_area(READ, file, pos, count);
    if (ret >= 0) {
        count = ret;
        if (file->f_op->read)
            ret = file->f_op->read(file, buf, count, pos);
        else
            ret = do_sync_read(file, buf, count, pos);
        if (ret > 0) {
            fsnotify_access(file);
            add_rchar(current, ret);
        }
        inc_syscr(current);
    }

    return ret;
}

Exclude a lot of condition checks, the skeleton is just like this:

if (file->f_op->read)
    ret = file->f_op->read(file, buf, count, pos);
else
    ret = do_sync_read(file, buf, count, pos);

If the driver provides the read function, use it, else call do_sync_read. No matter which function is used, the new file position should be updated in the memory which pos points to.

Finally, it is file_pos_write‘s function to update the new position:

static inline void file_pos_write(struct file *file, loff_t pos)
{
    file->f_pos = pos;
}

From the above analysis, we can see that it’s no need for every device driver update the file position, and file_pos_read/write will do this uniformly.Other functions are similar, so we can answer the question posted at the beginning of the article now.

“original filename unknown” warning in using crash

On my SuSE with Xen, executing crash command outputs:

# crash
......  
crash: /boot/symtypes-3.12.49-6-xen.gz: original filename unknown
    Use "-f /boot/symtypes-3.12.49-6-xen.gz" on command line to prevent this message.

crash: /boot/symtypes-3.12.49-6-default.gz: original filename unknown
    Use "-f /boot/symtypes-3.12.49-6-default.gz" on command line to prevent this message.

crash: /boot/xen-4.5.1_10-1.gz: original filename unknown
    Use "-f /boot/xen-4.5.1_10-1.gz" on command line to prevent this message.
......

In this post, Dave refers the cause of original filename unknown is “the original filename of the compressed file was not stored in the file's header.“. To verify it, I check the source code ofcrash:

(1) This message is printed from is_compressed_kernel function:

is_compressed_kernel(char *file, char **tmp)
{
    ......
    #define FNAME (1 << 3)
    ......
    if ((header[0] == 0x1f) && (header[1] == 0x8b) && (header[2] == 8)) {
            if (!(header[3] & FNAME)) {
                    if (!(st->flags & FORCE_DEBUGINFO)) {
                    error(INFO, "%s: "
                        "original filename unknown\n",
                        file);
                    error(CONT, 
                            "Use \"-f %s\" on command line to prevent this message.\n\n",
                        file);
                }
            } else if
    ......
}

(2) From gzip spec:

     ID1 (IDentification 1)
     ID2 (IDentification 2)
        These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
        (0x8b, \213), to identify the file as being in gzip format.

     CM (Compression Method)
        This identifies the compression method used in the file.  CM
        = 0-7 are reserved.  CM = 8 denotes the "deflate"
        compression method, which is the one customarily used by
        gzip and which is documented elsewhere.

     FLG (FLaGs)
        This flag byte is divided into individual bits as follows:

           bit 0   FTEXT
           bit 1   FHCRC
           bit 2   FEXTRA
           bit 3   FNAME
           bit 4   FCOMMENT
           bit 5   reserved
           bit 6   reserved
           bit 7   reserved
        ......
        If FNAME is set, an original file name is present,
        terminated by a zero byte.  The name must consist of ISO
        8859-1 (LATIN-1) characters; on operating systems using
        EBCDIC or any other character set for file names, the name
        must be translated to the ISO LATIN-1 character set.  This
        is the original name of the file being compressed, with any
        directory components removed, and, if the file being
        compressed is on a file system with case insensitive names,
        forced to lower case. There is no original file name if the
        data was compressed from a source other than a named file;
        for example, if the source was stdin on a Unix system, there
        is no file name.

As expected, after comparing the code with spec, the warning message is printed when the “original name isn’t present”.