kk Blog —— 通用基础


date [-d @int|str] [+%s|"+%F %T"]
netstat -ltunp
sar -n DEV 1

高精度定时器 high-cpu-load

http://stackoverflow.com/questions/1125297/nanosleep-high-cpu-usage

I noticed that a little test program which calls nanosleep is showing a huge difference in CPU usage when run on Linux machines with a kernel newer than 2.6.22.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <time.h>
int main (void)
{
	struct timespec sleepTime;
	struct timespec returnTime;
	sleepTime.tv_sec = 0;
	sleepTime.tv_nsec = 1000;
	while (1)
	{
		nanosleep(&sleepTime, &returnTime); // usleep(1); 同样异常
	}
	return 0;
}

(Yes, I realise this program does nothing)

If I compile this and run it on an openSUSE 10.3 machine (2.6.22.19-0.2-default), the program does not even show up on the process list generated by “top”, indicating to me that it is using very little CPU time. If I run it on an openSUSE 11.1 machine (2.6.27.23-0.1-default), top shows the program taking 40% of the CPU time. Running on Fedora 9 (2.6.25-14.fc9.i686) and Fedora 10 also showed the same high CPU usage in “top”.

Has there been a change in the kernel that affects this?


Answers

This is due to the introduction of NO_HZ into the mainline scheduler.

Previously, your 1,000 ns sleep was usually sleeping for a whole tick - 1,000,000 ns. Now, when the machine is otherwise idle, it’s actually only sleeping for what you asked for. So it’s running the while() loop and syscall around 1,000 times more frequently - hence a lot more CPU usage. If you increase tv_nsec you should see a reduction in the CPU usage.


1
2
3
4
5
6
7
int nanosleep(const struct timespec *req, struct timespec *rem);

struct timespec
{
	time_t  tv_sec;         /* seconds */
	long    tv_nsec;        /* nanoseconds */
};

这个函数功能是暂停某个进程直到你规定的时间后恢复,参数req就是你要暂停的时间,其中req->tv_sec是以秒为单位,而tv_nsec以毫 微秒为单位(10的-9次方秒)。由于调用nanosleep是是进程进入TASK_INTERRUPTIBLE,这种状态是会相应信号而进入 TASK_RUNNING状态的,这就意味着有可能会没有等到你规定的时间就因为其它信号而唤醒,此时函数返回-1,切还剩余的时间会被记录在rem中。

crash vs gdb work

贴自https://www.redhat.com/archives/crash-utility/2014-October/msg00002.html
Yes, sure. GDB works very differently from crash. There main conceptual
difference is that GDB only handles with VIRTUAL addresses, while the
crash utility first translates everything to PHYSICAL addresses.
Consequently, GDB ignores the PhysAddr field in ELF program headers,
and crash ignores the VirtAddr field.

I have looked at some of my ELF dump files, and it seems to me that
VirtAddr is not filled correctly, except for kernel text and static
data (address range 0xffffffff80000000-0xffffffff9fffffff). Your linked
list is most likely allocated in the direct mapping
(0xffff880000000000-0xffffc7ffffffffff). However, I found out that the
virtual addresses for the direct mapping segments are wrong, e.g. my
dump file specifies it at 0xffff810000000000 (hypervisor area). This is
most likely a bug in the kernel code that implements /proc/vmcore.

But that’s beside the point. Why? The Linux kernel maps many physical
pages more than once into the virtual address space. It would be waste
of space if you saved it multiple times (for each virtual address that
maps to it). The crash utility can translate each virtual address to
the physical address and map it onto ELF segments using PhysAddr.
Incidentally, the PhysAddr fields are correct in my dump files…

I’m glad you’re interested in using GDB to read kernel dump files,
especially if you’re willing to make it work for real. I have proposed
more than once that the crash utility be re-implemented in pure gdb.
Last time I looked (approx. 1.5 years ago) the main missing pieces were:

  1. Use of physical addresses (described above)
  2. Support for multiple virtual address spaces (for different process contexts)
  3. Ability to read compressed kdump files
  4. Ability to use 64-bit files on 32-bit platforms (to handle PAE)

HTH,
Petr Tesarik

静态编译crash + xbt + bt -H

要在centos6上编译,为了能在centos5用,用静态编译
有两个显示函数参数的patch,但是不一定能起作用
patch1:

https://github.com/jhammond/xbt https://www.redhat.com/archives/crash-utility/2013-September/msg00010.html

patch2:

https://github.com/hziSot/crash-stack-parser https://github.com/hziSot/crash-stack-parser/blob/master/crash-parse-stack-7.0.1.patch

一、依赖包:

yum install bison zlib zlib-static glibc-static elfutils-devel elfutils-devel-static elfutils-libelf-devel-static ncurses ncurses-static crash-devel

二、patch1: xbt 显示参数

patch: https://github.com/hziSot/crash-stack-parser
make CFLAGS+=–static LDFLAGS+=–static

三、patch2: bt -H 显示参数

1
2
3
4
5
6
7
8
9
10
11
12
13
依赖:有些没有静态包,要自己编译安装:
liblzma.a: http://tukaani.org/xz/xz-5.0.7.tar.bz2
libbz2.a:  http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz
下载代码:git clone https://github.com/jhammond/xbt.git xbt.git
把xbt.git/xbt_crash.c中函数xbt_func前的static删了
把xbt.git/xbt_crash.c中函数xmod_init的register_extension删了
把 xbt 命令加到global_data.c        函数x86_64_exception_frame已经在其他库中定义了,所以要换个名字
编译xbt代码:make   ==  rm -rf *.so
把 xbt.git/xbt_crash.o  xbt.git/xbt_dwarf.o  xbt.git/xbt_dwfl.o  xbt.git/xbt_eval.o  xbt.git/xbt_frame_print.o 加到 Makefile 的 OBJECT_FILES= 中
make CFLAGS+=--static LDFLAGS+="--static -lc  -lm -ldl -ldw -lebl -lelf -lbz2 -llzma"


注意:-lelf -lebl要放在-ldw后面。