This commit is contained in:
geekard
2012-12-30 14:55:16 +08:00
parent 411a288513
commit f8638a5844
58 changed files with 9509 additions and 81 deletions

Binary file not shown.

View File

@@ -1,7 +1,7 @@
[History]
list=[["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",4502,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",187,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",145,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki KEYMAPS",1701,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",187,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",145,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",877,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",145,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",944,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",125,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki KEYMAPS",2508,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",637,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",914,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",914,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",914,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",983,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",2995,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:personal.map",178,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",4928,null]]
list=[["Utils:gdb:gdb debugging",292,null],["Utils:gdb:gdb debugging:gdb pointer",284,null],["Utils:gdb:gdb debugging:gdb demo",340,null],["Research:Error Notes:\u4e0b\u8f7d\u9519\u8bef:chosen node create failed",0,null],["Programme:goagent",43,null],["Linux:accounts",0,null],["Utils:autoconf---automake",0,null],["Utils:autoconf---automake:\u4ee3\u7801",0,null],["Utils:blkid",0,null],["Utils:autoconf---automake",0,null],["Utils:gcc&g++",0,null],["Utils:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:gdb",0,null],["Utils:gcc&g++:Installing---GCC--Configuration",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",null,null]]
current=24
recent=[["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04",43,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:\u66f4\u6539\u952e\u76d8\u5e03\u5c40(vitual terminal\u548cX\u7a0b\u5e8f)",0,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:dumpkeys",75,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:dumpkeys -l",14500,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki KEYMAPS",2508,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps",13256,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:wiki xmodmap",2995,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:keymaps:personal.map",178,null],["Utils:\u952e\u76d8\u5e03\u5c40\u548c\u6309\u952e\u6620\u5c04:xmodmap",4928,null]]
recent=[["Utils:gdb",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",null,null]]
[MainWindow]
windowsize=[1278,779]
@@ -20,8 +20,8 @@ windowpos=[0,19]
toolbar_style=None
toolbar_size=tiny
active_tabs=["Index",null,null,"Attachments"]
toggle_panes=[]
left_pane=[true,222,"Index"]
toggle_panes=["left_pane"]
left_pane=[true,276,"Index"]
right_pane=[false,200,null]
top_pane=[false,200,null]
bottom_pane=[false,200,null]
@@ -50,7 +50,7 @@ calendar_expanded=False
[InsertImageDialog]
windowsize=[1280,749]
attach_inserted_images=False
last_image_folder=/home/geekard/Notes/Zim/Research/\u5d4c\u5165\u5f0fPowerPC\u4e0a\u7684\u6241\u5e73\u8bbe\u5907\u6811FDT
last_image_folder=/home/geekard/Notes/Zim/Utils/gdb/gdb_debugging
[InsertLinkDialog]
windowsize=[328,156]
@@ -70,7 +70,7 @@ windowsize=[637,165]
windowsize=[500,400]
[PreferencesDialog]
windowsize=[537,422]
windowsize=[592,422]
[AttachmentBrowserPlugin]
active=True
@@ -125,5 +125,5 @@ output_file=/home/geekard/\u4e3a\u4ec0\u4e48\u8981\u7528\u975e\u5173\u7cfb\u6570
windowsize=[411,157]
[FindAndReplaceDialog]
windowsize=[330,298]
windowsize=[332,298]

View File

@@ -0,0 +1,129 @@
[History]
list=[["Utils:gdb:gdb debugging:gdb demo",340,null],["Research:Error Notes:\u4e0b\u8f7d\u9519\u8bef:chosen node create failed",0,null],["Programme:goagent",43,null],["Linux:accounts",0,null],["Utils:autoconf---automake",0,null],["Utils:autoconf---automake:\u4ee3\u7801",0,null],["Utils:blkid",0,null],["Utils:autoconf---automake",0,null],["Utils:gcc&g++",0,null],["Utils:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:gdb",0,null],["Utils:gcc&g++:Installing---GCC--Configuration",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:make",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",null,null]]
current=24
recent=[["Utils:gdb",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:gcc&g++:C++\u7f16\u8bd1\u521d\u6b65",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:irssi",0,null],["Utils:\u5de5\u5177\u94fe:make",0,null],["Utils:script",0,null],["Utils:\u5de5\u5177\u94fe",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",null,null]]
[MainWindow]
windowsize=[1278,779]
show_sidepane=True
sidepane_pos=316
show_menubar=True
show_menubar_fullscreen=True
show_toolbar=True
show_toolbar_fullscreen=False
show_statusbar=True
show_statusbar_fullscreen=False
pathbar_type=recent
pathbar_type_fullscreen=none
readonly=False
windowpos=[0,19]
toolbar_style=None
toolbar_size=tiny
active_tabs=["Index",null,null,"Attachments"]
toggle_panes=["left_pane"]
left_pane=[true,276,"Index"]
right_pane=[false,200,null]
top_pane=[false,200,null]
bottom_pane=[false,200,null]
[ImportPageDialog]
windowsize=[500,400]
[NewPageDialog]
windowsize=[362,170]
[RenamePageDialog]
windowsize=[643,204]
[DeletePageDialog]
windowsize=[633,438]
[PropertiesDialog]
windowsize=[395,299]
[InsertDateDialog]
windowsize=[319,247]
lastusedformat=%A %d/%m/%Y
linkdate=True
calendar_expanded=False
[InsertImageDialog]
windowsize=[1280,749]
attach_inserted_images=False
last_image_folder=/home/geekard/Notes/Zim/Utils/gdb/gdb_debugging
[InsertLinkDialog]
windowsize=[328,156]
[EditImageDialog]
windowsize=[339,268]
[AttachFileDialog]
windowsize=[500,400]
last_attachment_folder=/home/geekard/Notes/Zim/Research/Error_Notes/\u7f16\u8bd1\u9519\u8bef/crdb
insert_attached_images=False
[PromptExistingFileDialog]
windowsize=[637,165]
[InsertTextFromFileDialog]
windowsize=[500,400]
[PreferencesDialog]
windowsize=[592,422]
[AttachmentBrowserPlugin]
active=True
bottompane_pos=516
[TaskListDialog]
windowsize=[550,400]
hpane_pos=75
[InsertSymbolDialog]
windowsize=[350,400]
[InsertScreenshotDialog]
windowsize=[212,148]
[WordCountDialog]
windowsize=[316,146]
[CustomToolManagerDialog]
windowsize=[410,299]
[OpenPageDialog]
windowsize=[298,118]
[NotebookDialog]
windowsize=[500,400]
[PageWindow]
windowsize=[500,400]
[CalendarDialog]
windowsize=[222,258]
[TagsPlugin]
treeview=tagged
tagcloud_sorting=score
[ExportDialog]
windowsize=[400,325]
document_root_url=
selection=page
selected_page=NonSQL:\u4e3a\u4ec0\u4e48\u8981\u7528\u975e\u5173\u7cfb\u6570\u636e\u5e93\uff1f
format=HTML
template=Default
template_file=None
document_root=absolute
output_folder=None
index_page=
output_file=/home/geekard/\u4e3a\u4ec0\u4e48\u8981\u7528\u975e\u5173\u7cfb\u6570\u636e\u5e93\uff1f.html
[MovePageDialog]
windowsize=[411,157]
[FindAndReplaceDialog]
windowsize=[332,298]

11
Zim/Linux/accounts.txt Normal file
View File

@@ -0,0 +1,11 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-12-02T14:03:59+08:00
====== accounts ======
Created Friday 02 December 2011
kb310小熊
ip: 192.168.1.113
port: 222
username: geekard

View File

@@ -1,14 +0,0 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-12-02T14:03:59+08:00
====== kb318 ======
Created Friday 02 December 2011
常利伟帐号:
ssh -p 1998 clw@192.168.1.1
密码000000
ssh 192.168.1.85
root: 000000
geekard:ho4o44

View File

@@ -8,3 +8,7 @@ Created Friday 02 November 2012
grub gfx = graphics, 两者的读音差不多。
VESA = Video Electronics Standards Association
VBE = VESA BIOS Extensions
evdev = event device: A componet of the linux kernel for handling input(from keyboards, mice, joysticks, etc.)
and a closely related input driver fo the X.Org server.The kernel componet is glue-code which translates input
events from peripheral-specific drivers into a generic structure which the input driver can easily translate into X11
events.

View File

@@ -0,0 +1,38 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-23T16:02:09+08:00
====== Introduction to PIC ======
Created Sunday 23 December 2012
http://www.gentoo.org/proj/en/hardened/pic-guide.xml
PIC code radically differs from conventional code in the way it calls functions and operates on data variables.
It will access these functions and data __through an indirection table__, the "Global Offset Table" (GOT), by software convention accessible using the reserved name "**_GLOBAL_OFFSET_TABLE_**".
The exact mechanism used for this is hardware architecture dependent, but usually __a special machine register__ is reserved for setting up the location of the GOT when entering a function.
The rationale behind this indirect addressing is to generate code that can be __independently accessed__ of the actual load address. 例如共享库的目标代码在内存中只加载一次,但是可以映射到多个进程中。
In a true PIC library **without** relocations in the __text segment__, only the symbols exported in the __"Global Offset Table"__ need updating at run-time depending on the current load address of the various shared libraries in the address space of the running process. 使用PIC技术的共享库在动态链接(映射)到某个进程的地址空间中时其text section不需要重定位(更改),只需要对
GOT表中的符号进行重定位即可。而GOT位于.data section中。
Likewise, procedure calls to globally defined functions are redirected through the __"Procedure Linkage Table" (PLT)__ residing in the data segment of the core image. Again, this is done to avoid run-time modifications to the text segment.
其实PLT位于.text section之中是只读和可执行的它会使用GOT中的函数符号条目。
The __linker-editor__ allocates the Global Offset Table and Procedure Linkage Table when combining PIC object files into an image suitable for mapping into the process address space. It also collects all symbols that may be needed by the run-time link-editor and stores these along with the image's text and data bits. Another reserved symbol, **_DYNAMIC** is used to indicate the presence of the run-time linker structures. Whenever _DYNAMIC is relocated to 0, there is no need to invoke the run-time link- editor. If this symbol is non-zero, it points at a data structure from which the location of the necessary relocation- and symbol information can be derived. This is most notably used by the start-up module, **crt0, crt1S** and more recently **Scrt1**. The _DYNAMIC structure is conventionally located at the start of the data segment of the image to which it pertains.
On most architectures, when you compile source code to object code, you __need to specify__ whether the object code should be position independent or not. There are occasional architectures which don't make the distinction, usually because all object code is position independent by virtue of the __Application Binary Interface (ABI),__ or less often because the load address of the object is fixed at compile time, which implies that shared libraries are not supported by such a platform. If an object is compiled as position independent code (PIC), then the operating system can load the object __at any address__ in preparation for execution. This involves a time overhead, in replacing direct address references with relative addresses at compile time, and a space overhead, in maintaining information to help the runtime loader fill in the unresolved addresses at runtime.
Consequently, PIC objects are usually slightly larger and slower at runtime than the equivalent non-PIC object. The advantage of sharing library code on disk and in memory outweigh these problems as soon as the PIC object code in shared libraries is reused.
PIC compilation is exactly what is required for objects which will become __part of__ a shared library. Consequently, __libtool__ builds PIC objects for use in shared libraries and non-PIC objects for use in static libraries. Whenever libtool instructs the compiler to generate a PIC object, it also defines the preprocessor symbol, `PIC', so that assembly code can be aware of whether it will reside in a PIC object or not.
Typically, as libtool is compiling sources, it will generate a `.lo' object, as PIC, and a `.o' object, as non-PIC, and then it will use the appropriate one of the pair when linking executables and libraries of various sorts. On architectures where there is no distinction, the `.lo' file is just a soft link to the `.o' file.
In practice, you can link PIC objects into a static archive for a small overhead in execution and load speed, and often you can similarly link non-PIC objects into shared archives.
When you use position-independent code, relocatable references are generated as an indirection that use data in the shared object's data segment. The text segment code remains read-only, and all relocation updates are applied to corresponding entries within the data segment.
If a shared object is built from code that is not position-independent, the text segment will usually require a large number of relocations to be performed at runtime. Although the runtime linker is equipped to handle this, the system overhead this creates can cause serious performance degradation.
You can identify a shared object that requires relocations against its text segment using tools such as 'readelf -d foo' and inspect the output for any TEXTREL entry. The value of the TEXTREL entry is irrelevant. Its presence in a shared object indicates that text relocations exist.

View File

@@ -0,0 +1,213 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-21T20:33:28+08:00
====== elf 重定位 ======
Created Friday 21 December 2012
Relocation is the process of __associate the symbolic reference with symbolic definition.__ For example, when a program calls a function, the associate all instruction must transfor control to the **proper destination address.** In other words, relocatable files must have information for modifying their section content.
Relocation table entry structer:
{{./0.gif}}
* **r_offset:** Holds the location at which the relocation apply. For a relocable file, the value is the byte offset from the beginning of the section to the storage unit affected by relocation. For an executable file or a share object file, the value is the virtual address of units affected by relocation.
* **r_info:** Holds both the __symbol table index__ with respect to which the relocation must be made, and __the type of relocation__. For example, a call instrution's relocation enry would hold the symbol index of the function. Relocation types are processor-sepcific. The following code shows how to manipulate the values.
#define ELF32_R_SYM(info) ((info)>>8)
#define ELF32_R_TYPE(info) ((info)&ff)
#define ELF32_R_INFO(s,t) (((s)<<8) + ((t)&0xff))
symbol: bits 328
type: bits 70
**r_addend:** Holds a constand addend used to compute the value to be stored into the relocable field.
===== Relocation Types:(SYSTEM V Architecture) =====
The __link editor__ merge one or more relocable object files to form the output. It first disides how to combine and locate the input files then update the symbol values, and finally preform the relocation. Relocations applied to excutable or shared object files are similar.
link editor(ld)首先合并可重定位目标文件,然后解析其中的符号引用,并将符号的最终实际地址写入到符号表中,最后重定位。
The relocation types specific which bits to change and how to caculate their values下表真对的是x86而非x86_64.
{{./1.gif}}
**R_386_32:** Symbols value + addend. In the following Fig, thre is a relocation at the **0×7 bytes** offset into **.text** section. The linker alter the address of b with S+A, S is symbold bs new address after reset. A is the endian, here it is zero.
**R_386_32是绝对寻址的重定位。将符号解析后的绝对实际地址填充到关联section的offset处。**
{{./2.gif}}
**R_386_PC32:** Symbols **value+Addend-Place**. Because it is __Relative Near CALL__, the operand is the offset from the “next instruction” (EIP) to the called procedure, more infor is here. **VALUE+EIP = Symbol.value, EIP = Place+4. So VALUE = Symbold.value 4 Place**. S is Symbol.vale, -4 is the Addend. P is the new virtuall address of relocation entry computed by r_offset and other factors.
R_386_PC32是相对寻址的重定位。S是符号表中符号解析后的实际地址Place是调用该符号的指令地址所以相对偏移量为 **VALUE = Symbold.value 4 Place**
**R_386_GLOB_DAT:** This type is used to __set a global offset table entry__ to the address of the specific symbol. It is used for global or external variable in PIC code . 将解析后的全局或外部符号的实际地址写入到对应的__GOT条目中__。
**R_386_JMP_SLOT:** The linker editor creates this relocation type for dynamic linking. Its offset specify __the GOT entry that contain a PLT entry__. The dynamic linker use it to implement lazy linking.将解析后的外部函数实际入口地址写入到对应的GOT中的PLT条目类型中。
R_386_GLOB_DAT and R_386_JMP_SLOT are only appear in executable file or shared library.
__上面两种类型的重定位是由动态链接器解析符号后完成的与代码里是否引用该符号无关(因为代码是间接地利用GOTPLT来引用外部变量和符号的)。而且是对GOT中的符号value进行填充与代码段无关。__
**R_386_GOTOFF:**引用本文件内使用的static和rodata类型变量时使用的重定位类型。外部static变量和函数内static变量定义在.data section中对它们的引用不通过GOT条目而是其符号位置与GOT首地址的偏移量来实现的(同理,字符串字面量由于不能修改,一般保存在.rodata section中对它们的引用也不是通过GOT条目),即重定位值= S+A-GOT。示例如下
//ebx事先保存的是GOT的首地址
movl __globalVarStatic@GOTOFF__(%ebx), %eax __//globalVarStatic@GOTOFF的值为S+A-GOT再加上GOT的正好为符号globalVarStatic的地址。__
movl (%eax), 4(%esp)
**R_386_GOT32**代码中引用外部变量时ld生成的重定位类型。动态链接器将G+A-P的值填充到代码中的重定位位置。所以CPU实际寻址时得到的地址为R_386_GOT32+P-A = G。
**R_386_PLT32**代码中引用外部函数时ld生成的重定位类型。动态链接器将L+A-P的值填充到代码中的重定位位置。所以CPU实际寻址时得到的地址为R_386_PLT32+P-A = L。
上面的G和L指的是__相应符号GOT条目距GOT首地址的偏移量。注意GOT32和PLT32一般和GOTPC一起使用后者将GOT的首地址填充到代码段中的引用位置处。G+GOTPC=相应符号在GOT条目中的实际地址。__
在代码中引用外部变量时汇编器一般生成如下代码x86系统如果是x86_64则直接具有**rip寄存器**
call __i686.get_pc_thunk.cx
addl $_GLOBAL_OFFSET_TABLE_, %ecx //_GLOBAL_OFFSET_TABLE符号的值是__GOT表首地址距当前指令的偏移量__它的重定位类型为R_386_GOTPC。现在ecx寄存器保存的是__GOT表的绝对地址__。
movl var@GOT(%ecx), %eax //var@GOT是__var符号在GOT表中的偏移量__所以var@GOT(%ecx)会通过GOT中的var条目取得__var符号的实际地址并将其保存在eax寄存器中__。var@GOT的值是通过R_386_GOT32重定位的。
movl (%eax), %eax //取得var符号引用的内存单元值保存到eax寄存器中。
__i686.get_pc_thunk.cx: //该函数的目的是获取EIP的值。
mov (%esp),%ecx //此时的esp指向的内存单元保存的值时__函数返回后执行的指令地址即紧接着call的addl指令地址__。
ret
**R_386_GOTPC:** This type asembles R_386_PC32, except it use __the address of GOT__ in its caculation. The symbol referenced in this relocation normally is **_GLOBAL_OFFSET_TABLE_(见上面的代码示例)** , which additionally instructs linker to build the GOT. It normally used in PICs relocable files. See “ELF PIC Dessection“.
Sample:
d.c
int var = 10;
void fun (void){
var++;
int a = var;
}
#gcc -S -o __d.s__ -fPIC d.c //生成汇编代码这样其中包含有__编译器生成的指导汇编器生成重定位条目的具体信息__。而通过objdump -d d.o看到的反汇编代码已经去掉了这些重定位信息。
#gcc -c -o d.o -fPIC d.c
In d.s, d.c assembled with PIC option, there are instructions to load the GOT address, shown in the following figure.
{{./3.gif}}
There will be a R_386_GOTPC relocation entry in d.o for __update the value of “$_GLOBAL_OFFSET_TABLE”__ to the offset from “addl” to “GOT”(addl指令的地址与GOT表首地址的差值即为_GLOBAL_OFFSET_TABLE符号的值。__该值的计算方法是由重定位类型决定的__), see the following figureobjdump -d的反汇编代码已经看不出原始的重定位信息. The relocation entry is at 0xd bytes offset from .text section, $_GLOBAL_OFFSET_TABLE resides there. The items initial value is 0×2. It is the endian A for caculating the address of addl. During the relocation, the linker caculate the relocation entrys P (position) by r_offset first. Thus P-2 is the address addl. why -2? because the opcode of addl is 2 bytes long. So $_GLOBAL_OFFSET_TABLE = GOT-P+A.
{{./4.gif}}
**R_386_COPY:** The link editor creates this relocation type for dynamic linking. Its offset member refers to a location in a writable segement. The symbol table index specifies a symbol that should exists __both__ in the current object file and in a shared object. During execution, the dynamic linker __copies the data__ associated with the shared objects symbol to location specified by the offset.
Sample:
[root@www save]# cat 386copy.c
#include <stdio.h>
extern int a;
int main(void) {
printf(“%d\n”, a);
}
[root@www save]# cat b.c
int a = 10;
#gcc -fPIC -share -o b.so b.c
#gcc -o 386copy 386copy.c ./b.so
{{./5.gif}}
Fig2 shows the variable as value from shared object to executables .bss section.
===== Notation: =====
S : The value of the symbol whose index resides in the relocation entrys r_info.
A: The addend used to caculate the value of the relocation field.
P: The place, section offset or address, of the storage unit __being relocated__ (computed useing r_offset).__也就是计算后的值所替换的位置。__
G: The __offset__ into the global offset table at which the address of relocation entrys symbol will reside during execution.
GOT: The address of the global offset table.
L: The place, section offset or address, of PLT entry for a symbol.
B: The __base address__ at which a shared object file has been loaded into the memory during execution.
===== Relocation section: =====
A relocation section(**而不是重定位条目的属性**) reference other two sections: __a symbol table and a section to modify__. The section headers sh_info and sh_link, specify these relationships. sh_link is the symbol table index, sh_info is the section link.
Samples Code:
#include <stdio.h>
char a = a;
int b = 10;
extern char c;
extern void fun();
void pp (void) { }
int main(void) {
printf(“%d\n”, __b__);
int bb = __b__;
char cc = __c__; //b和c都是绝对寻址
**pp**(); //相对寻址
fun();
}
# gcc -c -o test1 test.c //生成的是可重定位的目标对象文件__没有使用GOT和PLT__所以和它们相关的重定位类型都没有使用。一般只使用了__R_386_PC32和R_386_32__两种类型。
[geekard@geekard rel]$ readelf -r rel.o
Relocation section '.rel.text' at offset 0x478 contains 7 entries:
Offset Info Type Sym.Value Sym. Name
0000000f 00000a01 __R_386_32__ 00000004 b
0000001a 00000501 R_386_32 00000000 .rodata
0000001f 00000d02 R_386_PC32 00000000 printf
00000024 00000a01 R_386_32 00000004 b
0000002f 00000e01 R_386_32 00000000 c
00000038 00000b02 R_386_PC32 00000000 pp
0000003d 00000f02 __R_386_PC32__ 00000000 fun
Relocation section '.rel.eh_frame' at offset 0x4b0 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000020 00000202 R_386_PC32 00000000 .text
00000040 00000202 R_386_PC32 00000000 .text
没有使用PIC技术时对目标对象文件中全局变量符号引用地址的重定位是直接用实际地址替换(**R_386_32**)对__内部和外部函数__的调用是相对调转(**R_386_PC32**)。
[geekard@geekard rel]$ readelf -s rel.o
Symbol table '.symtab' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS rel.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 SECTION LOCAL DEFAULT 5
6: 00000000 0 SECTION LOCAL DEFAULT 7
7: 00000000 0 SECTION LOCAL DEFAULT 8
8: 00000000 0 SECTION LOCAL DEFAULT 6
**9: 00000000 1 OBJECT GLOBAL DEFAULT 3 a**
** 10: 00000004 4 OBJECT GLOBAL DEFAULT 3 b**
** 11: 00000000 5 FUNC GLOBAL DEFAULT 1 pp**
** 12: 00000005 62 FUNC GLOBAL DEFAULT 1 main**
** 13: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf**
** 14: 00000000 0 NOTYPE GLOBAL DEFAULT UND c**
** 15: 00000000 0 NOTYPE GLOBAL DEFAULT UND fun**
[geekard@geekard rel]$
[geekard@geekard rel]$ gcc -c __-fPIC__ -o rel.o rel.c #还是可重定位目标类型目标文件但是符号的引用使用了__位置无关__技术所以对全局变量和外部函数的引用使用了GOT和PLT。
[geekard@geekard rel]$ readelf -r rel.o
Relocation section '.rel.text' at offset 0x594 contains 9 entries:
Offset Info Type Sym.Value Sym. Name
00000010 00000f02 R_386_PC32 00000000 __x86.get_pc_thunk.bx
00000016 0000100a __R_386_GOTPC__ 00000000 _GLOBAL_OFFSET_TABLE_
0000001c 00000c03 __R_386_GOT32__ 00000004 b
00000028 00000509 R_386_GOTOFF 00000000 .rodata
00000030 00001104 R_386_PLT32 00000000 printf
00000036 00000c03 R_386_GOT32 00000004 b
00000042 00001203 R_386_GOT32 00000000 c
0000004e 00000d04 __R_386_PLT32__ 00000000 pp
00000053 00001304 R_386_PLT32 00000000 fun
Relocation section '.rel.eh_frame' at offset 0x5dc contains 3 entries:
Offset Info Type Sym.Value Sym. Name
00000020 00000202 R_386_PC32 00000000 .text
00000040 00000202 R_386_PC32 00000000 .text
00000064 00000602 R_386_PC32 00000000 .text.__x86.get_pc_thu
[geekard@geekard rel]$
使用了PIC技术后所有符号的重定位使用__GOT和PLT。__
Here is the details of how REL section associated with symbol table and the section to relocation.
1. Show the ELF sections.
{{./7.gif}}
In fig1, the section .rel.text is REL, the sections it is associated with are the first and the 9th section, .text and .symtab.
2. Show the relocation section entries:
{{./8.gif}}
In fig2, we can see there are two relocation entries for symbol b because b is referenced two times and the linker has to relocation it two times.
3. What is the raw data of relocation table entry?
{{./9.gif}}
Fig3 shows the content of the first entry of relocation table. r_offset is 0×10, that means the relocation entry is at the 0×10 of test1. the symbol table index is 0×09. we can see the 9th entry of symbol table is b through Fig4;
4. bs offset if 4 byts offset from the start of data section and size is 4 bytes. Then the linercaculate the address of b and modify its address in .text section through relocation entry.
{{./10.gif}}
So, we get a simple flow of how linker do the relocation. __first, get all relocation entries, then get all symbols associated with the relocation entries, then caculate the address and modify the unist in the section assosicated with the relocation entries.__ The real relocation is more complex but main flow is like this.
Sunday, September 12th, 2010 at 16:29

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,15 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-23T13:11:25+08:00
====== CFI for gas ======
Created Sunday 23 December 2012
Modern ABIs don't require frame pointers to be used in functions.
Howerver missing FPs bring difficulties when doing a backtrace.
One solutions is to provide Dwarf-2 CFI(call frame information) data
for each such function. This can be easily done for example by GCC in
its output, but isn't that easy to write by hand for pure assembler functions.
With the help of these .cfi_* directives one can ass appropriate unwind info
into his asm source without too much trouble.

View File

@@ -0,0 +1,198 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-22T10:50:43+08:00
====== sample2--可重定位类型 ======
Created Saturday 22 December 2012
[geekard@geekard rel]$ cat -n rel.c **#测试文件**
1 #include <stdio.h>
2 int globalVar = 1;
3 int globalVarUninit;
4 static int globalVarStatic = 3;
5 extern externVar;
6
7 extern void externFun(void);
8 void Fun(void) {}
9
10 int main(void) {
11 int autoVar = globalVar;
12 static int staticVar = 2;
13 globalVarUninit = externVar;
14 printf("%d\n",globalVarStatic);
15 externFun();
16 Fun();
17 }
[geekard@geekard rel]$ **gcc -c rel.c #编译,生成可重定位类型的目标对象文件**
[geekard@geekard rel]$ readelf **-r** rel.o **#查看可重定位条目**
Relocation section '.rel.text' at offset 0x4e0 contains 8 entries:
Offset Info Type Sym.Value Sym. Name
0000000f 00000b01 R_386_32 00000000 globalVar __#对文件中的第11行变量引用进行重定位__
00000018 00000f01 R_386_32 00000000 externVar **#13**
0000001d 00000c01 R_386_32 00000004 globalVarUninit **#13**
00000022 00000301 R_386_32 00000000 .data
0000002d 00000601 R_386_32 00000000 .rodata
00000032 00001002 R_386_PC32 00000000 printf **#14**
00000037 00001102 R_386_PC32 00000000 externFun **#15**
0000003c 00000d02 R_386_PC32 00000000 Fun **#16**
Relocation section '.rel.eh_frame' at offset 0x520 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000020 00000202 R_386_PC32 00000000 .text
00000040 00000202 R_386_PC32 00000000 .text
由于在编译时没有指定PIC所以重定位条目没有使用GOT或PLT。对全局变量使用的时R_386_32的绝对地址重定位对函数使用的是
R_386_PC32相对寻址重定位。
[geekard@geekard rel]$ **objdump -t rel.o #查看符号表**
rel.o: file format elf32-i386
SYMBOL TABLE:
00000000 l df *ABS* 00000000 rel.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000004 l O __.data__ 00000004 globalVarStatic
00000000 l d .rodata 00000000 .rodata
00000008 l O __.data__ 00000004 staticVar.1828
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .eh_frame 00000000 .eh_frame
00000000 l d .comment 00000000 .comment
00000000 g O __.data__ 00000004 globalVar
00000004 O __*COM*__ 00000004 globalVarUninit
00000000 g F .text 00000005 Fun
00000005 g F .text 0000003d main
00000000 *UND* 00000000 externVar
00000000 *UND* 00000000 printf
00000000 *UND* 00000000 externFun
[geekard@geekard rel]$
全局静态变量、全局已初始化变量、静态自动变量都位于.data section中。但是全局未初始化变量位于COMMON(named after Fortran 77's "common blocks") section中而且对外不可见。file-scope and local-scope uninitiated global variables 保存在bss"Block Started by Symbol"段中。如果想让globalVarUninit保存在.bss section中可以在编译时使用-fno-common选项则是建议的用法。
geekard@ubuntu:~/Code$ cat bar.c
double globalVar;
int main() {}
geekard@ubuntu:~/Code$ cat bar.c
double globalVar;
int main() {}
geekard@ubuntu:~/Code$
geekard@ubuntu:~/Code$ gcc foo.c bar.c
编译并链接上面两个文件时,编译器并没有提示符号重复定义的错误,但是如果启用-fno-common选项则会提示错误。
geekard@ubuntu:~/Code$ gcc foo.c bar.c **-fno-common**
/tmp/cceNAIis.o:(.bss+0x0): multiple definition of `globalVar'
/tmp/ccWmFhZG.o:(.bss+0x0): first defined here
/usr/bin/ld: Warning: size of symbol `globalVar' changed from 4 in /tmp/ccWmFhZG.o to 8 in /tmp/cceNAIis.o
collect2: ld 返回 1
geekard@ubuntu:~/Code$
则是由于foo.oh和bar.o中的globalVar都放在.bss section中而且都是global bind所以会冲突。注意放在COMMON section中时
没有bind属性默认是外界不可见的
geekard@ubuntu:~/Code$ objdump -t bar.o |grep globalVar //未启用-fno-common无绑定信息外界不可见
0000000000000008 __O *COM*__ 0000000000000008 globalVar
geekard@ubuntu:~/Code$ objdump -t bar.o |grep globalVar //启用-fno-common后
0000000000000000 __g__ O __.bss__ 0000000000000008 globalVar
kkkn
[geekard@geekard rel]$ __gcc -S rel.c #编译__
[geekard@geekard rel]$ cat rel.s #查看编译生成的汇编代码代码中含有指示链接器ld生成各section和重定位的指令。
.file "rel.c"
.globl globalVar **#符号全局可见**
.data **#data section开始**
.align 4
.type globalVar, @object **#符号类型**
.size globalVar, 4 **#符号对象大小**
globalVar:
.long 1 **#符号的值**
__.comm__ globalVarUninit,4,4 **#COMMON section**
.align 4
.type globalVarStatic, @object
.size globalVarStatic, 4
globalVarStatic:
.long 3
.text **#代码段开始**
.globl Fun
.type Fun, @function
Fun:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size Fun, .-Fun #函数对象的大小
.section .rodata **#rodata section的开始**
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl __globalVar,__ %eax __#对全局变量的引用是绝对寻址没有使用GOT。汇编时as会生成R_386_32类型的重定位条目__
movl %eax, 28(%esp)
movl __externVar__, %eax
movl %eax, __globalVarUninit__
movl __globalVarStatic__, %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call __printf #对外部或全局函数的引用使用的是相对寻址没有使用PLT。汇编时as会生成R_386_PC32类型的重定位条目__
call __externFun__
call __Fun __
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size main, .-main
.data
.align 4
.type __staticVar.1828__, @object
.size staticVar.1828, 4
staticVar.1828:
.long 2
.ident "GCC: (GNU) 4.7.2"
.section .note.GNU-stack,"",@progbits
[geekard@geekard rel]$
[geekard@geekard rel]$ objdump -d rel.o
rel.o: file format elf32-i386
Disassembly of section .text:
00000000 <Fun>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 5d pop %ebp
4: c3 ret
00000005 <main>:
5: 55 push %ebp
6: 89 e5 mov %esp,%ebp
8: 83 e4 f0 and $0xfffffff0,%esp
b: 83 ec 20 sub $0x20,%esp
e: a1 00 00 00 00 mov 0x0,%eax
13: 89 44 24 1c mov %eax,0x1c(%esp)
17: a1 00 00 00 00 mov 0x0,%eax
1c: a3 00 00 00 00 mov %eax,0x0
21: a1 04 00 00 00 mov 0x4,%eax
26: 89 44 24 04 mov %eax,0x4(%esp)
2a: c7 04 24 00 00 00 00 movl $0x0,(%esp)
31: e8 fc ff ff ff call 32 <main+0x2d>
36: e8 fc ff ff ff call 37 <main+0x32>
3b: e8 fc ff ff ff call 3c <main+0x37>
40: c9 leave
41: c3 ret
[geekard@geekard rel]$

View File

@@ -0,0 +1,236 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-22T22:55:46+08:00
====== sample3--PIC可重定位类型 ======
Created Saturday 22 December 2012
[geekard@geekard rel]$ cat rel.c
#include <stdio.h>
int globalVar = 1;
int globalVarUninit;
static int globalVarStatic = 3;
extern externVar;
extern void externFun(int);
void Fun(void) {}
int main(void) {
int autoVar = globalVar;
static int staticVar = 2;
globalVarUninit = externVar;
printf("%d\n",globalVarStatic);
externFun(staticVar);
Fun();
}
[geekard@geekard rel]$ gcc -c __-fPIC__ rel.c
[geekard@geekard rel]$ readelf -r rel.o
Relocation section '**.rel.text**' at offset 0x600 contains 10 entries: **//对text section中的符号引用重定位**
Offset Info Type Sym.Value Sym. Name
00000010 00001102 R_386_PC32 00000000 __x86.get_pc_thunk.bx //相对寻址重定位这里没有使用PLT是因为该函数是文件内部定义的。
00000016 0000120a R_386___GOTPC__ 00000000 _GLOBAL_OFFSET_TABLE_ //用IP与GOT首地址的偏移量重定位代码中的值。
0000001c 00000d03 R_386___GOT32__ 00000000 globalVar //用var条目在GOT中的偏移量重定位代码中的值。
00000028 00001303 R_386_GOT32 00000000 externVar
00000030 00000e03 R_386_GOT32 00000004 globalVarUninit
00000038 00000309 R_386___GOTOFF__ 00000000 .data //用__static符号的地址与GOT的偏移量__来重定位代码段中的值。
00000042 00000609 R_386_GOTOFF 00000000 .rodata //.rodata section中保存的是**字符串字面量**。
0000004a 00001404 R_386___PLT32__ 00000000 printf //用printf条目在GOT PLT中的偏移量重定位代码中的值。
00000050 00000309 R_386_GOTOFF 00000000 .data
0000004f 00001504 R_386_PLT32 00000000 externFun
00000054 00000f04 R_386_PLT32 00000000 Fun
Relocation section '.rel.eh_frame' at offset 0x650 contains 3 entries:
Offset Info Type Sym.Value Sym. Name
00000020 00000202 R_386_PC32 00000000 .text
00000040 00000202 R_386_PC32 00000000 .text
00000064 00000802 R_386_PC32 00000000 .text.__x86.get_pc_thu
[geekard@geekard rel]$ objdump -t rel.o
rel.o: file format elf32-i386
SYMBOL TABLE:
00000000 l df *ABS* 00000000 rel.c
00000000 l d .text 00000000 .text //.text section定义
00000000 g F __.text__ 00000005 Fun //.text section中的第一个函数(偏移量为0),本文件内定义
00000005 g F .text 00000058 main //.text section中的第二个函数
00000000 g F .text.x86.get_pc_thunk.bx 00000000 .hidden x86.get_pc_thunk.bx
00000000 l d .text.x86.get_pc_thunk.bx 00000000 .text.x86.get_pc_thunk.bx
00000000 l d .data 00000000 .data //.data section定义
00000000 g O .data 00000004 globalVar
00000004 l O .data 00000004 globalVarStatic
00000008 l O .data 00000004 __staticVar.1828__
00000000 l d .rodata 00000000 .rodata
00000000 l d .bss 00000000 .bss
00000004 O __*COM*__ 00000004 globalVarUninit
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .eh_frame 00000000 .eh_frame
00000000 l d .comment 00000000 .comment
00000000 l d .group 00000000 .group
00000000 __*UND*__ 00000000 _GLOBAL_OFFSET_TABLE_
00000000 *UND* 00000000 externVar
00000000 *UND* 00000000 printf
00000000 *UND* 00000000 externFun
[geekard@geekard rel]$ gcc -S __-fPIC__ rel.c
[geekard@geekard rel]$ cat rel.s
.file "rel.c"
.globl globalVar
.data
.align 4
.type globalVar, @object
.size globalVar, 4
globalVar:
.long 1
.comm globalVarUninit,4,4
.align 4
.type globalVarStatic, @object
.size globalVarStatic, 4
globalVarStatic:
.long 3
.text
.globl Fun
.type Fun, @function
Fun:
.LFB0: **//.LFB是Dwarf使用的一个标号与.LFE相匹配。**
.cfi_startproc //[[../CFI_for_gas.txt|cfi(call frame information)]]
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size Fun, .-Fun
.section __.rodata__
__.LC0: //该标号没有使用.globl限定所以符号表中没有包含。只在本文件内有效。__
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB1: //前面使用的是.LFB0, 所以这里是.LFB1
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %ebx
andl $-16, %esp
subl $32, %esp
.cfi_offset 3, -12
call ____x86.get_pc_thunk.bx __**//获得IP的值保存在ebx寄存器中**
addl $___GLOBAL_OFFSET_TABLE___, %ebx **//通过GOTPC重定位获得GOT与当前IP的偏移量。最终获得GOT的首地址**
movl __globalVar@GOT__(%ebx), %eax **//通过GOT32重定位获得var@GOT的值即var所在的GOT条目相对GOT的偏移量。**
movl (%eax), %eax **//eax寄存器的值为var符号的实际地址这样间接引用获得其实际值。**
movl %eax, 28(%esp)
movl externVar@GOT(%ebx), %eax
movl (%eax), %edx
movl globalVarUninit@GOT(%ebx), %eax
movl %edx, (%eax)
movl __globalVarStatic@GOTOFF__(%ebx), %eax __//GOTOFF类型的重定位__
movl %eax, 4(%esp)
leal __.LC0@GOTOFF__(%ebx), %eax
movl %eax, (%esp)
call __printf@PLT__
movl __staticVar.1828@GOTOFF__(%ebx), %eax
movl %eax, (%esp)
call externFun@PLT
call Fun@PLT
movl -4(%ebp), %ebx
leave
.cfi_restore 5
.cfi_restore 3
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size main, .-main
.data
.align 4
.type staticVar.1828, @object
.size staticVar.1828, 4
staticVar.1828:
.long 2
.section .text.x86.get_pc_thunk.bx,"axG",@progbits,x86.get_pc_thunk.bx,comdat
.globl __x86.get_pc_thunk.bx
.hidden __x86.get_pc_thunk.bx
.type __x86.get_pc_thunk.bx, @function
__x86.get_pc_thunk.bx:
.LFB2:
.cfi_startproc
movl (%esp), %ebx
ret
.cfi_endproc
.LFE2:
.ident "GCC: (GNU) 4.7.2"
.section .note.GNU-stack,"",@progbits
[geekard@geekard rel]$
[geekard@geekard rel]$ objdump -d rel.o
rel.o: file format elf32-i386
Disassembly of section .text:
00000000 <Fun>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 5d pop %ebp
4: c3 ret
00000005 <main>:
5: 55 push %ebp
6: 89 e5 mov %esp,%ebp
8: 53 push %ebx
9: 83 e4 f0 and $0xfffffff0,%esp
c: 83 ec 20 sub $0x20,%esp
f: e8 __fc ff ff ff__ call 10 <main+0xb>
14: 81 c3 __02 00 00 00__ add $0x2,%ebx //objdump反汇编后的代码中已经__看不到原始的重定位信息__。所以需要和重定位条目一起查看。
1a: 8b 83 __00 00 00 00__ mov 0x0(%ebx),%eax
20: 8b 00 mov (%eax),%eax
22: 89 44 24 1c mov %eax,0x1c(%esp)
26: 8b 83 __00 00 00 00__ mov 0x0(%ebx),%eax
2c: 8b 10 mov (%eax),%edx
2e: 8b 83 __00 00 00 00__ mov 0x0(%ebx),%eax
34: 89 10 mov %edx,(%eax)
36: 8b 83 __04 00 00 00__ mov 0x4(%ebx),%eax
3c: 89 44 24 04 mov %eax,0x4(%esp)
40: 8d 83 __00 00 00 00__ lea 0x0(%ebx),%eax
46: 89 04 24 mov %eax,(%esp)
49: e8 __fc ff ff ff__ call 4a <main+0x45>
4e: 8b 83 __08 00 00 00__ mov 0x8(%ebx),%eax
54: 89 04 24 mov %eax,(%esp)
57: e8 __fc ff ff ff__ call 58 <main+0x53>
5c: e8 __fc ff ff ff__ call 5d <main+0x58>
61: 8b 5d fc mov -0x4(%ebp),%ebx
64: c9 leave
65: c3 ret
#上面黄色标记的位置需要链接器对其重定位。
Disassembly of section .text.__x86.get_pc_thunk.bx:
00000000 <__x86.get_pc_thunk.bx>:
0: 8b 1c 24 mov (%esp),%ebx
3: c3 ret
[geekard@geekard rel]$

View File

@@ -0,0 +1,125 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-16T17:34:49+08:00
====== ld-linux调试信息 ======
Created Sunday 16 December 2012
启用动态连接器调试信息输出的方法是定义变量LD_DEBUG=all
**[geekard@geekard hello]$ cat hello.c**
#include <stdio.h>
#include <stdlib.h>
int glb_init = 1;
int glb_uninit;
int main(void)
{
char *str = "Just a test string!";
printf("The test string is:\"%s\"\n", str);
printf("glb_init:%d, glb_uninit:%d\n", glb_init, glb_uninit);
pause(); **//暂停进程,这样可以查看其内存映射情况。**
exit(0);
}
[geekard@geekard hello]$ __strace -e trace=mmap2,mprotect,munmap,open,close -ELD_DEBUG=all ./hello &>log__
^Z
[1]+ Stopped strace -e trace=mmap2,mprotect,munmap,open,close -ELD_DEBUG=all ./hello &>log
#上面的log文件中包含有strace的输出和hello的ld-linux.so的DEBUG信息。
**#4727为hello的进程号下面命令从log中提取ld-linux.so的DEBUG信息**
**[geekard@geekard hello]$ cat log|grep 4727>log.ld **
#**下面命令从log中提取hello的系统调用信息**
**[geekard@geekard hello]$ cat log |sed '/4727/d' >log.strace**
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77b8000
**[geekard@geekard hello]$ readelf -l /lib/libc.so.6**
Elf file type is DYN (Shared object file)
Entry point __0x19760__
There are __10__ program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x00140 0x00140 R E 0x4
INTERP 0x16b7e8 0x0016b7e8 0x0016b7e8 0x00017 0x00017 R 0x1
[Requesting program interpreter: [[/usr/lib/ld-linux.so.2]]]
#第一个LOAD为RE其大小为1718236B(0x1a37dc)需要4KB对齐所以实际需要空间1720320B这会传给mmap2函数。
**LOAD** __0x000000__ 0x00000000 0x00000000 __0x1a37dc__ 0x1a37dc R E 0x1000
**LOAD** 0x1a41dc 0x001a41dc 0x001a41dc 0x02ce0 __0x058e8__ RW 0x1000
DYNAMIC __0x1a5d9c__ 0x001a5d9c 0x001a5d9c 0x000f8 0x000f8 RW 0x4
NOTE 0x000174 0x00000174 0x00000174 0x00044 0x00044 R 0x4
TLS 0x1a41dc 0x001a41dc 0x001a41dc 0x00008 0x00040 R 0x4
GNU_EH_FRAME 0x16b800 0x0016b800 0x0016b800 0x07454 0x07454 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
**GNU_RELRO** 0x1a41dc 0x001a41dc 0x001a41dc 0x01e24 0x01e24 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.version_r .rel.dyn .rel.plt .plt .text __libc_freeres_fn __libc_thread_freeres_fn .rodata .interp .eh_frame_hdr .eh_frame .gcc_except_table .hash
03 .tdata .init_array __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.gnu.build-id .note.ABI-tag
06 .tdata .tbss
07 .eh_frame_hdr
08
09 .tdata .init_array __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic .got
可以看出libc.so.6中的__虚拟地址从0开始__。
**[geekard@geekard hello]$ pmap $(pgrep hello) |nl #查看hello进程的地址映射情况**
1 4727: ./hello
2 08048000 4K r-x-- /home/geekard/Code/hello/hello
3 08049000 4K rw--- /home/geekard/Code/hello/hello
4 __b75eb000__ 4K rw--- [ anon ] //libc的保护区域
//0xb75ec000为ld-linux.so映射libc到a.out进程地址空间时的__随机base地址(见后文log文件)__。
5 __b75ec000__ 1680K r-x-- /usr/lib/libc-2.16.so
6 __b7790000__ 8K r---- /usr/lib/libc-2.16.so
7 b7792000 4K rw--- /usr/lib/libc-2.16.so
8 __b7793000__ 12K rw--- [ anon ]
9 b77b8000 **8K** rw--- [ anon ] //包含有第一次调用mmap2()分配的匿名内存块。
10 b77ba000 4K r-x-- [ anon ] //ld的保护区域
11 b77bb000 128K r-x-- /usr/lib/ld-2.16.so
12 b77db000 4K r---- /usr/lib/ld-2.16.so
13 b77dc000 4K rw--- /usr/lib/ld-2.16.so
14 __bff8b000__ 132K rw--- [ stack ]
15 total 1996K
**[geekard@geekard hello]$ cat log //查看strace打印出的系统调用和ld-linux.so打印的DEBUG信息。**
//匿名映射mmap2的第一个参数为NULL所以内核会随机地选择一个地址这里为 **0xb77b9000。**
//匿名映射的虚拟地址空间为**0xb77b90000xb77ba000。包含在pmap打印的第9行中。**
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|**MAP_ANONYMOUS**, -1, 0) = **0xb77b9000**
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
//文件映射,内核随机选择一个起始地址,这里为**0xb7796000**
mmap2(**NULL**, 139868, PROT_READ, MAP_PRIVATE, 3, 0) = **0xb7796000**
4727:
4727: file=libc.so.6 [0]; needed by ./hello [0]
4727: find library=libc.so.6 [0]; searching
4727: search cache=/etc/ld.so.cache
//关闭了ld.so.cache所以**其映射的内存区域将删除**。
close(3) = 0
4727: trying file=/usr/lib/libc.so.6
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
//文件映射,内核随机选择一个起始地址,这里为 __0xb75ec000。这里映射的是第一个LOAD segment__
mmap2(**NULL**, 1743556, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = __0xb75ec000__
//这里映射的是第二个LOAD segment
mmap2(**0xb7790000,** 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, **0x1a4**) = 0xb7790000
mmap2(**0xb7793000**, 10948, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|**MAP_ANONYMOUS**, -1, 0) = 0xb7793000
close(3) = 0
4727:
4727: file=libc.so.6 [0]; generating link map
4727: dynamic: __0xb7791d9c__ base: __0xb75ec000__ size: 0x001a9ac4
4727: entry: 0xb7605760 phdr: 0xb75ec034 phnum: 10
4727:
4727: checking for version `GLIBC_2.0' in file /usr/lib/libc.so.6 [0] required by file ./hello [0]
4727: checking for version `GLIBC_2.3' in file /lib/ld-linux.so.2 [0] required by file /usr/lib/libc.so.6 [0]
4727: checking for version `GLIBC_PRIVATE' in file /lib/ld-linux.so.2 [0] required by file /usr/lib/libc.so.6 [0]
4727: checking for version `GLIBC_2.1' in file /lib/ld-linux.so.2 [0] required by file /usr/lib/libc.so.6 [0]
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = **0xb75eb000**
mprotect(0xb7790000, 8192, PROT_READ) = 0
mprotect(0xb77db000, 4096, PROT_READ) = 0
munmap(0xb7796000, 139868) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = **0xb77b8000**

View File

@@ -0,0 +1,7 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-29T11:19:39+08:00
====== goagent ======
Created Saturday 29 December 2012

View File

@@ -0,0 +1,380 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-29T14:30:56+08:00
====== The-Python-Standard-Library ======
Created Thursday 29 November 2012
http://docs.python.org/2/library/index.html
While **The Python Language Reference** describes the exact syntax and semantics of the Python language, this library reference manual describes the standard library that is distributed with Python. It also describes some of the optional components that are commonly included in Python distributions.
Pythons standard library is very extensive, offering a wide range of facilities as indicated by the long table of contents listed below.
The library contains __built-in modules__ (written in C) that provide access to system functionality such as file I/O that would otherwise be inaccessible to Python programmers, as well as modules written in Python that provide __standardized solutions__ for many problems that occur in everyday programming. Some of these modules are explicitly designed to encourage and enhance the portability of Python programs by abstracting away platform-specifics into platform-neutral APIs.
The Python installers for the Windows platform usually includes the entire standard library and often also include many additional components. For Unix-like operating systems Python is normally provided as **a collection of packages**, so it may be necessary to use the packaging tools provided with the operating system to obtain some or all of the optional components.
In addition to the standard library, there is a growing collection of several thousand components (from individual programs and modules to packages and entire application development frameworks), available from the Python Package Index.
1. Introduction
2. Built-in Functions
3. Non-essential Built-in Functions
4. Built-in Constants
4.1. Constants added by the site module
5. Built-in Types
5.1. Truth Value Testing
5.2. Boolean Operations — and, or, not
5.3. Comparisons
5.4. Numeric Types — int, float, long, complex
5.5. Iterator Types
5.6. Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange
5.7. Set Types — set, frozenset
5.8. Mapping Types — dict
5.9. File Objects
5.10. memoryview type
5.11. Context Manager Types
5.12. Other Built-in Types
5.13. Special Attributes
6. Built-in Exceptions
6.1. Exception hierarchy
7. String Services
7.1. string — Common string operations
7.2. re — Regular expression operations
7.3. struct — Interpret strings as packed binary data
7.4. difflib — Helpers for computing deltas
7.5. StringIO — Read and write strings as files
7.6. cStringIO — Faster version of StringIO
7.7. textwrap — Text wrapping and filling
7.8. codecs — Codec registry and base classes
7.9. unicodedata — Unicode Database
7.10. stringprep — Internet String Preparation
7.11. fpformat — Floating point conversions
8. Data Types
8.1. datetime — Basic date and time types
8.2. calendar — General calendar-related functions
8.3. collections — High-performance container datatypes
8.4. heapq — Heap queue algorithm
8.5. bisect — Array bisection algorithm
8.6. array — Efficient arrays of numeric values
8.7. sets — Unordered collections of unique elements
8.8. sched — Event scheduler
8.9. mutex — Mutual exclusion support
8.10. Queue — A synchronized queue class
8.11. weakref — Weak references
8.12. UserDict — Class wrapper for dictionary objects
8.13. UserList — Class wrapper for list objects
8.14. UserString — Class wrapper for string objects
8.15. types — Names for built-in types
8.16. new — Creation of runtime internal objects
8.17. copy — Shallow and deep copy operations
8.18. pprint — Data pretty printer
8.19. repr — Alternate repr() implementation
9. Numeric and Mathematical Modules
9.1. numbers — Numeric abstract base classes
9.2. math — Mathematical functions
9.3. cmath — Mathematical functions for complex numbers
9.4. decimal — Decimal fixed point and floating point arithmetic
9.5. fractions — Rational numbers
9.6. random — Generate pseudo-random numbers
9.7. itertools — Functions creating iterators for efficient looping
9.8. functools — Higher-order functions and operations on callable objects
9.9. operator — Standard operators as functions
10. File and Directory Access
10.1. os.path — Common pathname manipulations
10.2. fileinput — Iterate over lines from multiple input streams
10.3. stat — Interpreting stat() results
10.4. statvfs — Constants used with os.statvfs()
10.5. filecmp — File and Directory Comparisons
10.6. tempfile — Generate temporary files and directories
10.7. glob — Unix style pathname pattern expansion
10.8. fnmatch — Unix filename pattern matching
10.9. linecache — Random access to text lines
10.10. shutil — High-level file operations
10.11. dircache — Cached directory listings
10.12. macpath — Mac OS 9 path manipulation functions
11. Data Persistence
11.1. pickle — Python object serialization
11.2. cPickle — A faster pickle
11.3. copy_reg — Register pickle support functions
11.4. shelve — Python object persistence
11.5. marshal — Internal Python object serialization
11.6. anydbm — Generic access to DBM-style databases
11.7. whichdb — Guess which DBM module created a database
11.8. dbm — Simple “database” interface
11.9. gdbm — GNUs reinterpretation of dbm
11.10. dbhash — DBM-style interface to the BSD database library
11.11. bsddb — Interface to Berkeley DB library
11.12. dumbdbm — Portable DBM implementation
11.13. sqlite3 — DB-API 2.0 interface for SQLite databases
12. Data Compression and Archiving
12.1. zlib — Compression compatible with gzip
12.2. gzip — Support for gzip files
12.3. bz2 — Compression compatible with bzip2
12.4. zipfile — Work with ZIP archives
12.5. tarfile — Read and write tar archive files
13. File Formats
13.1. csv — CSV File Reading and Writing
13.2. ConfigParser — Configuration file parser
13.3. robotparser — Parser for robots.txt
13.4. netrc — netrc file processing
13.5. xdrlib — Encode and decode XDR data
13.6. plistlib — Generate and parse Mac OS X .plist files
14. Cryptographic Services
14.1. hashlib — Secure hashes and message digests
14.2. hmac — Keyed-Hashing for Message Authentication
14.3. md5 — MD5 message digest algorithm
14.4. sha — SHA-1 message digest algorithm
15. Generic Operating System Services
15.1. os — Miscellaneous operating system interfaces
15.2. io — Core tools for working with streams
15.3. time — Time access and conversions
15.4. argparse — Parser for command-line options, arguments and sub-commands
15.5. optparse — Parser for command line options
15.6. getopt — C-style parser for command line options
15.7. logging — Logging facility for Python
15.8. logging.config — Logging configuration
15.9. logging.handlers — Logging handlers
15.10. getpass — Portable password input
15.11. curses — Terminal handling for character-cell displays
15.12. curses.textpad — Text input widget for curses programs
15.13. curses.ascii — Utilities for ASCII characters
15.14. curses.panel — A panel stack extension for curses
15.15. platform — Access to underlying platforms identifying data
15.16. errno — Standard errno system symbols
15.17. ctypes — A foreign function library for Python
16. Optional Operating System Services
16.1. select — Waiting for I/O completion
16.2. threading — Higher-level threading interface
16.3. thread — Multiple threads of control
16.4. dummy_threading — Drop-in replacement for the threading module
16.5. dummy_thread — Drop-in replacement for the thread module
16.6. multiprocessing — Process-based “threading” interface
16.7. mmap — Memory-mapped file support
16.8. readline — GNU readline interface
16.9. rlcompleter — Completion function for GNU readline
17. Interprocess Communication and Networking
17.1. subprocess — Subprocess management
17.2. socket — Low-level networking interface
17.3. ssl — TLS/SSL wrapper for socket objects
17.4. signal — Set handlers for asynchronous events
17.5. popen2 — Subprocesses with accessible I/O streams
17.6. asyncore — Asynchronous socket handler
17.7. asynchat — Asynchronous socket command/response handler
18. Internet Data Handling
18.1. email — An email and MIME handling package
18.2. json — JSON encoder and decoder
18.3. mailcap — Mailcap file handling
18.4. mailbox — Manipulate mailboxes in various formats
18.5. mhlib — Access to MH mailboxes
18.6. mimetools — Tools for parsing MIME messages
18.7. mimetypes — Map filenames to MIME types
18.8. MimeWriter — Generic MIME file writer
18.9. mimify — MIME processing of mail messages
18.10. multifile — Support for files containing distinct parts
18.11. rfc822 — Parse RFC 2822 mail headers
18.12. base64 — RFC 3548: Base16, Base32, Base64 Data Encodings
18.13. binhex — Encode and decode binhex4 files
18.14. binascii — Convert between binary and ASCII
18.15. quopri — Encode and decode MIME quoted-printable data
18.16. uu — Encode and decode uuencode files
19. Structured Markup Processing Tools
19.1. HTMLParser — Simple HTML and XHTML parser
19.2. sgmllib — Simple SGML parser
19.3. htmllib — A parser for HTML documents
19.4. htmlentitydefs — Definitions of HTML general entities
19.5. xml.etree.ElementTree — The ElementTree XML API
19.6. xml.dom — The Document Object Model API
19.7. xml.dom.minidom — Lightweight DOM implementation
19.8. xml.dom.pulldom — Support for building partial DOM trees
19.9. xml.sax — Support for SAX2 parsers
19.10. xml.sax.handler — Base classes for SAX handlers
19.11. xml.sax.saxutils — SAX Utilities
19.12. xml.sax.xmlreader — Interface for XML parsers
19.13. xml.parsers.expat — Fast XML parsing using Expat
20. Internet Protocols and Support
20.1. webbrowser — Convenient Web-browser controller
20.2. cgi — Common Gateway Interface support
20.3. cgitb — Traceback manager for CGI scripts
20.4. wsgiref — WSGI Utilities and Reference Implementation
20.5. urllib — Open arbitrary resources by URL
20.6. urllib2 — extensible library for opening URLs
20.7. httplib — HTTP protocol client
20.8. ftplib — FTP protocol client
20.9. poplib — POP3 protocol client
20.10. imaplib — IMAP4 protocol client
20.11. nntplib — NNTP protocol client
20.12. smtplib — SMTP protocol client
20.13. smtpd — SMTP Server
20.14. telnetlib — Telnet client
20.15. uuid — UUID objects according to RFC 4122
20.16. urlparse — Parse URLs into components
20.17. SocketServer — A framework for network servers
20.18. BaseHTTPServer — Basic HTTP server
20.19. SimpleHTTPServer — Simple HTTP request handler
20.20. CGIHTTPServer — CGI-capable HTTP request handler
20.21. cookielib — Cookie handling for HTTP clients
20.22. Cookie — HTTP state management
20.23. xmlrpclib — XML-RPC client access
20.24. SimpleXMLRPCServer — Basic XML-RPC server
20.25. DocXMLRPCServer — Self-documenting XML-RPC server
21. Multimedia Services
21.1. audioop — Manipulate raw audio data
21.2. imageop — Manipulate raw image data
21.3. aifc — Read and write AIFF and AIFC files
21.4. sunau — Read and write Sun AU files
21.5. wave — Read and write WAV files
21.6. chunk — Read IFF chunked data
21.7. colorsys — Conversions between color systems
21.8. imghdr — Determine the type of an image
21.9. sndhdr — Determine type of sound file
21.10. ossaudiodev — Access to OSS-compatible audio devices
22. Internationalization
22.1. gettext — Multilingual internationalization services
22.2. locale — Internationalization services
23. Program Frameworks
23.1. cmd — Support for line-oriented command interpreters
23.2. shlex — Simple lexical analysis
24. Graphical User Interfaces with Tk
24.1. Tkinter — Python interface to Tcl/Tk
24.2. ttk — Tk themed widgets
24.3. Tix — Extension widgets for Tk
24.4. ScrolledText — Scrolled Text Widget
24.5. turtle — Turtle graphics for Tk
24.6. IDLE
24.7. Other Graphical User Interface Packages
25. Development Tools
25.1. pydoc — Documentation generator and online help system
25.2. doctest — Test interactive Python examples
25.3. unittest — Unit testing framework
25.4. 2to3 - Automated Python 2 to 3 code translation
25.5. test — Regression tests package for Python
25.6. test.test_support — Utility functions for tests
26. Debugging and Profiling
26.1. bdb — Debugger framework
26.2. pdb — The Python Debugger
26.3. Debugger Commands
26.4. The Python Profilers
26.5. hotshot — High performance logging profiler
26.6. timeit — Measure execution time of small code snippets
26.7. trace — Trace or track Python statement execution
27. Python Runtime Services
27.1. sys — System-specific parameters and functions
27.2. sysconfig — Provide access to Pythons configuration information
27.3. __builtin__ — Built-in objects
27.4. future_builtins — Python 3 builtins
27.5. __main__ — Top-level script environment
27.6. warnings — Warning control
27.7. contextlib — Utilities for with-statement contexts
27.8. abc — Abstract Base Classes
27.9. atexit — Exit handlers
27.10. traceback — Print or retrieve a stack traceback
27.11. __future__ — Future statement definitions
27.12. gc — Garbage Collector interface
27.13. inspect — Inspect live objects
27.14. site — Site-specific configuration hook
27.15. user — User-specific configuration hook
27.16. fpectl — Floating point exception control
27.17. distutils — Building and installing Python modules
28. Custom Python Interpreters
28.1. code — Interpreter base classes
28.2. codeop — Compile Python code
29. Restricted Execution
29.1. rexec — Restricted execution framework
29.2. Bastion — Restricting access to objects
30. Importing Modules
30.1. imp — Access the import internals
30.2. importlib Convenience wrappers for __import__()
30.3. imputil — Import utilities
30.4. zipimport — Import modules from Zip archives
30.5. pkgutil — Package extension utility
30.6. modulefinder — Find modules used by a script
30.7. runpy — Locating and executing Python modules
31. Python Language Services
31.1. parser — Access Python parse trees
31.2. ast — Abstract Syntax Trees
31.3. symtable — Access to the compilers symbol tables
31.4. symbol — Constants used with Python parse trees
31.5. token — Constants used with Python parse trees
31.6. keyword — Testing for Python keywords
31.7. tokenize — Tokenizer for Python source
31.8. tabnanny — Detection of ambiguous indentation
31.9. pyclbr — Python class browser support
31.10. py_compile — Compile Python source files
31.11. compileall — Byte-compile Python libraries
31.12. dis — Disassembler for Python bytecode
31.13. pickletools — Tools for pickle developers
32. Python compiler package
32.1. The basic interface
32.2. Limitations
32.3. Python Abstract Syntax
32.4. Using Visitors to Walk ASTs
32.5. Bytecode Generation
33. Miscellaneous Services
33.1. formatter — Generic output formatting
34. MS Windows Specific Services
34.1. msilib — Read and write Microsoft Installer files
34.2. msvcrt Useful routines from the MS VC++ runtime
34.3. _winreg Windows registry access
34.4. winsound — Sound-playing interface for Windows
35. Unix Specific Services
35.1. posix — The most common POSIX system calls
35.2. pwd — The password database
35.3. spwd — The shadow password database
35.4. grp — The group database
35.5. crypt — Function to check Unix passwords
35.6. dl — Call C functions in shared objects
35.7. termios — POSIX style tty control
35.8. tty — Terminal control functions
35.9. pty — Pseudo-terminal utilities
35.10. fcntl — The fcntl() and ioctl() system calls
35.11. pipes — Interface to shell pipelines
35.12. posixfile — File-like objects with locking support
35.13. resource — Resource usage information
35.14. nis — Interface to Suns NIS (Yellow Pages)
35.15. syslog — Unix syslog library routines
35.16. commands — Utilities for running commands
36. Mac OS X specific services
36.1. ic — Access to the Mac OS X Internet Config
36.2. MacOS — Access to Mac OS interpreter features
36.3. macostools — Convenience routines for file manipulation
36.4. findertools — The finders Apple Events interface
36.5. EasyDialogs — Basic Macintosh dialogs
36.6. FrameWork — Interactive application framework
36.7. autoGIL — Global Interpreter Lock handling in event loops
36.8. Mac OS Toolbox Modules
36.9. ColorPicker — Color selection dialog
37. MacPython OSA Modules
37.1. gensuitemodule — Generate OSA stub packages
37.2. aetools — OSA client support
37.3. aepack — Conversion between Python variables and AppleEvent data containers
37.4. aetypes — AppleEvent objects
37.5. MiniAEFrame — Open Scripting Architecture server support
38. SGI IRIX Specific Services
38.1. al — Audio functions on the SGI
38.2. AL — Constants used with the al module
38.3. cd — CD-ROM access on SGI systems
38.4. fl — FORMS library for graphical user interfaces
38.5. FL — Constants used with the fl module
38.6. flp — Functions for loading stored FORMS designs
38.7. fm — Font Manager interface
38.8. gl — Graphics Library interface
38.9. DEVICE — Constants used with the gl module
38.10. GL — Constants used with the gl module
38.11. imgfile — Support for SGI imglib files
38.12. jpeg — Read and write JPEG files
39. SunOS Specific Services
39.1. sunaudiodev — Access to Sun audio hardware
39.2. SUNAUDIODEV — Constants used with sunaudiodev
40. Undocumented Modules
40.1. Miscellaneous useful utilities
40.2. Platform specific modules
40.3. Multimedia
40.4. Undocumented Mac OS modules
40.5. Obsolete
40.6. SGI-specific Extension modules
»
indexmodules |next |previous | Python » Documentation »
© Copyright 1990-2012, Python Software Foundation.
The Python Software Foundation is a non-profit corporation. Please donate.
Last updated on Dec 01, 2012. Found a bug?
Created using Sphinx 1.0.7.

View File

@@ -0,0 +1,22 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-02T16:34:03+08:00
====== 1. Introduction ======
Created Sunday 02 December 2012
===== 1. Introduction =====
The “Python library” contains several different kinds of components.
It contains __data types__ that would normally be considered part of the “core” of a language, such as **numbers and lists**. For these types, the Python language core defines the form of **literals** and places some constraints on their semantics, but does **not fully define** the semantics. (On the other hand, the language core does define syntactic properties like the spelling and priorities of operators.)
The library also contains __built-in functions and exceptions__ — objects that can be used by all Python code //without the need of an import statement//. Some of these are defined by the core language, but many are not essential for the core semantics and are only described here.
The bulk of the __library__, however, consists of a collection of modules. There are many ways to dissect this collection. Some modules are written in C and __built in__** to the Python interpreter**; others are written in Python and imported in source form.
Some modules provide interfaces that are highly specific to Python, like printing a stack trace; some provide interfaces that are specific to particular operating systems, such as access to specific hardware; others provide interfaces that are specific to a particular application domain, like the World Wide Web. Some modules are available in all versions and ports of Python; others are only available when the underlying system supports or requires them; yet others are available only when a particular configuration option was chosen at the time when Python was compiled and installed.
This manual is organized **“from the inside out:”** it first describes the built-in data types, then the built-in functions and exceptions, and finally the modules, grouped in chapters of related modules. The ordering of the chapters as well as the ordering of the modules within each chapter is roughly from most relevant to least important.
Let the show begin!

View File

@@ -0,0 +1,892 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-02T16:37:06+08:00
====== 2. Built-in Functions ======
Created Sunday 02 December 2012
The Python interpreter has a number of functions built into it that are __always available__. They are listed here in alphabetical order.
abs() divmod() input() open() staticmethod()
all() enumerate() int() ord() str()
any() eval() isinstance() pow() sum()
basestring() execfile() issubclass() print() super()
bin() file() iter() property() tuple()
bool() filter() len() range() type()
bytearray() float() list() raw_input() unichr()
callable() format() locals() reduce() unicode()
chr() frozenset() long() reload() vars()
classmethod() getattr() map() repr() xrange()
cmp() globals() max() reversed() zip()
compile() hasattr() memoryview() round() __import__()
complex() hash() min() set() apply()
delattr() help() next() setattr() buffer()
dict() hex() object() slice() coerce()
dir() id() oct() sorted() intern()
===== abs(x) =====
Return the absolute value of **a number**. The argument may be a plain or long integer or a floating point number. If the argument is a complex number, its magnitude is returned.
===== all(iterable) =====
Return True if **all elements** of the iterable are true (or if the iterable is empty). Equivalent to:
def all(iterable):
for element in iterable:
if not element:
return False
return True
New in version 2.5.
===== any(iterable) =====
Return True if **any element** of the iterable is true. If the iterable is empty, return False. Equivalent to:
def any(iterable):
for element in iterable:
if element:
return True
return False
New in version 2.5.
===== basestring() =====
__This abstract type is the superclass for str and unicode. It cannot be called or instantiated__, but it can be used to test whether an object is an instance of str or unicode. **isinstance(obj, basestring)** is equivalent to isinstance(obj, (str, unicode)).
basestring其实是一个抽象类它是str和unicode的基类不能被实例化。
New in version 2.3.
===== bin(x) =====
x需要为int或long类型否则需要定义__index__()方法。
Convert an __integer number__ to a binary string. The result is a valid Python expression. If x is not a Python int object, it has to define an **__index__()** method that returns an integer.
=== 实例: ===
**>>> bin(123.22)**
**Traceback (most recent call last):**
** File "<stdin>", line 1, in <module>**
**TypeError: 'float' object cannot be interpreted as an index**
**>>>**
New in version 2.6.
===== bool([x]) =====
Convert a value to a Boolean, using the standard truth testing procedure. If x is false or omitted, this returns **False**; otherwise it returns True. __bool is also a class__, which is a subclass of int. Class bool cannot be subclassed further. Its only instances are False and True.
__False和True时class bool的实例。__
New in version 2.2.1.
Changed in version 2.3: If no argument is given, this function returns False.
===== bytearray([source[, encoding[, errors]]]) =====
Return a new array of bytes. The bytearray type __is a mutable sequence of integers in the range 0 <= x < 256__. It has most of the usual methods of mutable sequences, described in Mutable Sequence Types, as well as most methods that the str type has, see String Methods.
The optional source parameter can be used to initialize the array in a few different ways:
* If it is a **string**, you must also give the encoding (and optionally, errors) parameters; bytearray() then converts the string to bytes using str.encode().
* If it is an **integer**, __the array will have that size__ and will be initialized with null bytes.
* If it is an **object** conforming to the buffer interface, a read-only buffer of the object will be used to initialize the bytes array.
* If it is an **iterable**, it must be an iterable of integers in the range 0 <= x < 256, which are used as the initial contents of the array.
Without an argument, an array of **size 0** is created.
New in version 2.6.
===== callable(object) =====
Return True if the object argument appears callable, False if not. If this returns true, it is still possible that a call fails, but if it is false, calling object will never succeed. Note that **classes are callable** (calling a class returns a new instance); class instances are callable if they have a __call__() method.
===== chr(i) =====
Return **a string of one character** whose ASCII code is the integer i. For example, chr(97) returns the string 'a'. This is the inverse of **ord()**. The argument must be in the range [0..255], inclusive; ValueError will be raised if i is outside that range. See also unichr().
===== classmethod(function) =====
Return a class method for function.
A class method receives the class as __implicit first argument__, just like an instance method receives the instance. To declare a class method, use this idiom:
class C:
**@classmethod //不可少否则调用时解释器不会自动将class传给f函数。**
def f(cls, arg1, arg2, ...): ...
The @classmethod form is a function **decorator** see the description of function definitions in Function definitions for details.
It can be called either on the **class (such as C.f()) or on an instance (such as C().f())**. The instance is **ignored** except for its class. If a class method is called for a derived class, the derived **class object** is passed as the implied first argument.
__classmethod修饰器用来修饰一个class method。可以通过class或实例来调用该class method解释器会将class或instance所属的class默认传给class method。__
Class methods are different than C++ or Java static methods. If you want those, see **staticmethod()** in this section.
For more information on class methods, consult the documentation on the standard type hierarchy in The standard type hierarchy.
New in version 2.2.
Changed in version 2.4: Function decorator syntax added.
===== cmp(x, y) =====
Compare the two objects x and y and __return an integer__ according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.
===== compile(source, filename, mode[, flags[, dont_inherit]]) =====
Compile the source into **a code object or AST object**. Code objects can be executed by an __exec__ statement or evaluated by a call to __eval().__ source can either be a string or an AST object. Refer to the ast module documentation for information on how to work with AST objects.
The filename argument should give the file from which the code was read; pass some recognizable value if it wasnt read from a file ('<string>' is commonly used).
The mode argument specifies **what kind of code** must be compiled; it can be __'exec'__ if source consists of a sequence of statements, __'eval'__ if it consists of a single expression, or __'single'__ if it consists of a single interactive statement (in the latter case, expression statements that evaluate to something other than None will be printed).
The optional arguments flags and dont_inherit control which future statements (see PEP 236) affect the compilation of source. If neither is present (or both are zero) the code is compiled with those future statements that are in effect in the code that is calling compile. If the flags argument is given and dont_inherit is not (or is zero) then the future statements specified by the flags argument are used in addition to those that would be used anyway. If dont_inherit is a non-zero integer then the flags argument is it the future statements in effect around the call to compile are ignored.
Future statements are specified by bits which can be bitwise ORed together to specify multiple statements. The bitfield required to specify a given feature can be found as the compiler_flag attribute on the _Feature instance in the __future__ module.
This function raises SyntaxError if the compiled source is invalid, and TypeError if the source contains null bytes.
Note When compiling **a string with multi-line code** in 'single' or 'eval' mode, input must be terminated by at least one newline character. This is to facilitate detection of incomplete and complete statements in the code module.
Changed in version 2.3: The flags and dont_inherit arguments were added.
Changed in version 2.6: Support for compiling AST objects.
Changed in version 2.7: Allowed use of Windows and Mac newlines. Also input in 'exec' mode does not have to end in a newline anymore.
===== complex([real[, imag]]) =====
Create a complex number with the value real + imag*j or convert a string or number to a complex number. If the first parameter is a string, it will be interpreted as a complex number and the function must be called without a second parameter. The second parameter can never be a string. Each argument may be any numeric type (including complex). If imag is omitted, it defaults to zero and the function serves as a numeric conversion function like int(), long() and float(). If both arguments are omitted, returns 0j.
Note When converting from a string, the string must not contain whitespace around the central + or - operator. For example, complex('1+2j') is fine, but complex('1 + 2j') raises ValueError.
The complex type is described in Numeric Types — int, float, long, complex.
===== delattr(object, name) =====
This is a relative of setattr(). The arguments are an object and a string. The string must be the name of one of the objects attributes. The function deletes the named attribute, provided the object allows it. For example, **delattr(x, 'foobar')** is equivalent to **del x.foobar**.
===== dict(**kwarg) =====
===== dict(mapping, **kwarg) =====
===== dict(iterable, **kwarg) =====
Create a new dictionary. The dict object is the dictionary class. See dict and Mapping Types — dict for documentation about this class.
For other containers see the built-in list, set, and tuple classes, as well as the collections module.
===== dir([object]) =====
Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.
If the object has a method named __dir__(), this method will be called and must return the list of attributes. This allows objects that implement a custom __getattr__() or __getattribute__() function to customize the way dir() reports their attributes.
If the object does not provide __dir__(), the function tries its best to gather information from the objects __dict__ attribute, if defined, and from its type object. The resulting list is not necessarily complete, and may be inaccurate when the object has a custom __getattr__().
The default dir() mechanism behaves differently with different types of objects, as it attempts to produce the most relevant, rather than complete, information:
* If the object is a module object, the list contains the names of the modules attributes.
* If the object is a type or class object, the list contains the names of its attributes, and recursively of the attributes of its bases.
* Otherwise, the list contains the objects attributes names, the names of its classs attributes, and recursively of the attributes of its classs base classes.
The resulting list is sorted alphabetically. For example:
>>>
>>> import struct
>>> dir() # show the names in the module namespace
['__builtins__', '__doc__', '__name__', 'struct']
>>> dir(struct) # show the names in the struct module
['Struct', '__builtins__', '__doc__', '__file__', '__name__',
'__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into',
'unpack', 'unpack_from']
>>> class Shape(object):
def __dir__(self):
return ['area', 'perimeter', 'location']
>>> s = Shape()
>>> dir(s)
['area', 'perimeter', 'location']
Note Because dir() is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases. For example, metaclass attributes are not in the result list when the argument is a class.
===== divmod(a, b) =====
Take two (non complex) numbers as arguments and return a pair of numbers consisting of their quotient and remainder when using long division. With mixed operand types, the rules for binary arithmetic operators apply. For plain and long integers, the result is the same as (a // b, a % b). For floating point numbers the result is (q, a % b), where q is usually math.floor(a / b) but may be 1 less than that. In any case q * b + a % b is very close to a, if a % b is non-zero it has the same sign as b, and 0 <= abs(a % b) < abs(b).
Changed in version 2.3: Using divmod() with complex numbers is deprecated.
===== enumerate(sequence, start=0) =====
Return an enumerate object. sequence must be a sequence, an iterator, or some other object which supports iteration. The next() method of the iterator returned by enumerate() returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over sequence:
>>>
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
Equivalent to:
def enumerate(sequence, start=0):
n = start
for elem in sequence:
**yield n, elem**
n += 1
New in version 2.3.
Changed in version 2.6: The start parameter was added.
===== eval(expression[, globals[, locals]]) =====
The arguments are a string and optional globals and locals. If provided, globals must be a dictionary. If provided, locals can be any mapping object.
Changed in version 2.4: formerly locals was required to be a dictionary.
The expression argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the globals and locals dictionaries as global and local namespace. If the globals dictionary is present and lacks __builtins__, the current globals are copied into globals before expression is parsed. This means that expression normally has full access to the standard __builtin__ module and restricted environments are propagated. If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where eval() is called. The return value is the result of the evaluated expression. Syntax errors are reported as exceptions. Example:
>>>
>>> x = 1
>>> print eval('x+1')
2
This function can also be used to execute arbitrary code objects (such as those created by compile()). In this case pass a code object instead of a string. If the code object has been compiled with 'exec' as the mode argument, eval()s return value will be None.
Hints: dynamic execution of statements is supported by the exec statement. Execution of statements from a file is supported by the execfile() function. The globals() and locals() functions returns the current global and local dictionary, respectively, which may be useful to pass around for use by eval() or execfile().
See ast.literal_eval() for a function that can safely evaluate strings with expressions containing only literals.
===== execfile(filename[, globals[, locals]]) =====
This function is similar to __the exec statement__, but parses a file instead of a string. It is different from the import statement in that it does not use the module administration — it reads the file unconditionally and does not create a new module. [1]
The arguments are a file name and two optional dictionaries. The file is parsed and evaluated as a sequence of Python statements (similarly to a module) using the globals and locals dictionaries as global and local namespace. If provided, locals can be any mapping object. Remember that **at module level, globals and locals are the same dictionary**. If two separate objects are passed as globals and locals, the code will be executed as if it were embedded in a class definition.
Changed in version 2.4: formerly locals was required to be a dictionary.
__If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where execfile() is called.__ The return value is None.
Note The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function execfile() returns. execfile() cannot be used reliably to modify a functions locals.
===== file(name[, mode[, buffering]]) =====
file其实时class file的构造函数。
Constructor function for the **file type**, described further in section File Objects. The constructors arguments are the same as those of the open() built-in function described below.
When opening a file, its preferable to use open() instead of invoking this constructor directly. file is more suited to type testing (for example, writing isinstance(f, file)).
New in version 2.2.
===== filter(function, iterable) =====
Construct a list from those elements of iterable __for which function returns true__. iterable may be either a sequence, a container which supports iteration, or an iterator.
**If iterable is a string or a tuple, the result also has that type; otherwise it is always a list.**
If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed.
**如果可迭代对象是字符串或tuple则结果也为字符串或tuple其它的都为list。**
**如果function为None则结果为iterable中去掉判断为False的元素。**
Note that **filter(function, iterable) is equivalent to [item for item in iterable if function(item)]** if function is not None and [item for item in iterable if item] if function is None.
See **itertools.ifilter() and itertools.ifilterfalse() f**or iterator versions of this function, including a variation that filters for elements where the function returns false.
===== float([x]) =====
Convert a string or a number to floating point.
If the argument is a string, it must contain a possibly signed decimal or floating point number, __possibly embedded in whitespace空格, \t, \r, \n, \v, \f__.
__如果x为string则x只能为十进制整型和浮点型字符串则是因为float函数不像int函数那样含有可选的base参数__
__可以猜测或指定数字的进制类型同时可以包含空字符。__The argument may also be **[+|-]nan or [+|-]inf**.
Otherwise, the argument may be **a plain** or long integer or a floating point number, and a floating point number with the same value (within Pythons floating point precision) is returned. If no argument is given, returns 0.0.
Note When passing in a string, values for **NaN** and **Infinity** may be returned, depending on the underlying C library. Float accepts the strings **nan, inf and -inf** for **NaN** and **positive or negative infinity**. The case and a leading + are ignored as well as a leading - is ignored for NaN. Float always represents NaN and infinity as nan, inf or -inf.
The float type is described in Numeric Types — int, float, long, complex.
>>> float(__0xff__)
255.0
>>> float(__'0xff'__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for float(): 0xff
>>>
>>> float('__+inf'__)
inf
>>> float('+nan')
nan
>>>
>>> float(__'123'__)
123.0
>>> float(__'123\n\r\v'__)
123.0
>>>
>>> float(__+nan__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name **'nan' is not defined**
>>>
===== format(value[, format_spec]) =====
Convert a value to a “formatted” representation, as controlled by **format_spec**. The interpretation of format_spec will depend on the type of the value argument, however there is a standard formatting syntax that is used by most built-in types: Format Specification Mini-Language.
Note format(value, format_spec) merely calls **value.__format__(format_spec)**.
New in version 2.6.
===== frozenset([iterable]) =====
Return a new frozenset object, optionally with elements taken from iterable. frozenset is a built-in class. See frozenset and Set Types — set, frozenset for documentation about this class.
For other containers see the built-in set, list, tuple, and dict classes, as well as the __collections__ module.
New in version 2.4.
===== getattr(object, name[, default]) =====
Return the value of the named attribute of object. **name must be a string**. If the string is the name of one of the objects attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.
===== globals() =====
Return a dictionary representing __the current global symbol table__. This is always the dictionary of the current module (inside a function or method, this is the module where it is **defined**, not the module from which it is called).
===== hasattr(object, name) =====
The arguments are an object and a string. The result is True if the string is the name of one of the objects attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.)
===== hash(object) =====
Return the hash value of the object (if it has one). **Hash values are integers**. They are used to quickly compare dictionary keys during a dictionary lookup. Numeric values that compare equal have the same hash value (even if they are of different types, as is the case for 1 and 1.0).
===== help([object]) =====
Invoke the built-in help system. (This function is intended for interactive use.) If no argument is given, the interactive help system starts on the interpreter console. If the argument is a string, then the string is looked up as the name of a module, function, class, method, keyword, or documentation topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated.
This function is added to the built-in namespace by the site module.
New in version 2.2.
===== hex(x) =====
Convert an integer number (of any size) to a hexadecimal string. The result is a valid Python expression.
Note To obtain a hexadecimal string representation for a float, use the __float.hex()__ method.
Changed in version 2.4: Formerly only returned an unsigned literal.
===== id(object) =====
Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
CPython implementation detail: This is **the address of the object in memory**.
===== input([prompt]) =====
Equivalent to **eval(raw_input(prompt))**.
This function does not catch user errors. If the input is not syntactically valid, a SyntaxError will be raised. Other exceptions may be raised if there is an error during evaluation.
If the __readline__ module was loaded, then input() will use it to provide elaborate line editing and history features.
Consider using the **raw_input()** function for general input from users.
===== int(x=0) =====
===== int(x, base=10) =====
Convert a number or string x to an integer, or return 0 if no arguments are given. If x is a number, it can be a plain integer, a long integer, or a floating point number. If x is floating point, the conversion __truncates towards zero__. If the argument is outside the integer range, the function returns a long object instead.
__如果x为number则不需要为其指定base参数因为int函数会根据x的前缀如0b, 0x等正确判断。如果x为float number则其必须为十进制。__
If x is not a number or if base is given, then x must be a string or Unicode object __representing an integer literal in radix base__.
__如果x为string则其必须为整型数字字符串不能为各种进制的小数字符串。__
Optionally, the literal can be preceded by + or - (with no space in between) and __surrounded by whitespace__. A base-n literal consists of the digits 0 to n-1, with **a to z (or A to Z)** having values __10 to 35__. The default base is 10. The allowed values are 0 and 2-36.
Base-2, -8, and -16 literals can be optionally **prefixed with 0b/0B, 0o/0O/0, or 0x/0X**, as with integer literals in code. __Base 0__ means to interpret the string exactly as an integer literal, so that the actual base is 2, 8, 10, or 16.
The integer type is described in Numeric Types — int, float, long, complex.
>>> int("0xfff") **//默认为Base 10, 所以解码错误。**
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with __base 10__: '0xfff'
>>> int("0xfff", 16)
4095
>>> int(0xfff.ff) __//如果x为float number则其必须为十进制。__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'ff'
>>> int(111.22)
111
>>> int(0b111.11)
File "<stdin>", line 1
int(0b111.11)
^
SyntaxError: invalid syntax
>>>
>>> int("**0xfff.ff"**, 16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 16: '0xfff.ff'
>>>
>>> int('22.33') __//如果x为string则必须为整型数字字符串。__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '22.33'
===== isinstance(object, classinfo) =====
Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. Also return true if classinfo is a type object (new-style class) and object is an object of that type or of a (direct, indirect or virtual) subclass thereof. If object is not a class instance or an object of the given type, the function always returns false. If classinfo is neither a class object nor a type object, it may be a tuple of class or type objects, or may recursively contain other such tuples (other sequence types are not accepted). If classinfo is not a class, type, or tuple of classes, types, and such tuples, a TypeError exception is raised.
Changed in version 2.2: Support for a tuple of type information was added.
===== issubclass(class, classinfo) =====
Return true if class is a subclass (direct, indirect or virtual) of classinfo. A class is considered a subclass of itself. classinfo may be a tuple of class objects, in which case every entry in classinfo will be checked. In any other case, a TypeError exception is raised.
Changed in version 2.3: Support for a tuple of type information was added.
===== iter(o[, sentinel]) =====
Return an iterator object. The first argument is interpreted very differently depending on the presence of the second argument. Without a second argument, o must be __a collection object__ which supports th**e iteration protocol** (the __iter__() method), or it must support **the sequence protocol** (the __getitem__() method with integer arguments starting at 0). If it does not support either of those protocols, TypeError is raised. If the second argument, sentinel, is given, then o must be __a callable object__. The iterator created in this case will **call o with no arguments for each call** to its next() method; if the value returned is __equal to sentinel__, StopIteration will be raised, otherwise the value will be returned.
如果没有使用第二个参数则o必须为容器对象。否则o必须为可调用对象。
One useful application of the second form of iter() is to read lines of a file until a certain line is reached. The following example reads a file until the readline() method returns an empty string:
with open('mydata.txt') as fp:
for line in iter(fp.readline, ''):
process_line(line)
New in version 2.2.
===== len(s) =====
Return the length (the number of items) of an object. The argument may be a sequence (string, tuple or list) or a mapping (dictionary).
===== list([iterable]) =====
Return a list whose items are the same and in the same order as iterables items. iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, **a copy is made** and returned, similar to iterable[:]. For instance, list('abc') returns ['a', 'b', 'c'] and list( (1, 2, 3) ) returns [1, 2, 3]. If no argument is given, returns a new empty list, [].
list is a mutable sequence type, as documented in Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange. For other containers see the built in dict, set, and tuple classes, and the collections module.
===== locals() =====
Update and return a dictionary representing the **current local symbol table**. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.
Note The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
===== long(x=0) =====
===== long(x, base=10) =====
Convert a string or number to a long integer. If the argument is a string, it must contain a possibly signed number of arbitrary size, possibly embedded in whitespace. The base argument is interpreted in the same way as for int(), and may only be given when x is a string. Otherwise, the argument may be a plain or long integer or a floating point number, and a long integer with the same value is returned. Conversion of floating point numbers to integers truncates (towards zero). If no arguments are given, returns 0L.
The long type is described in Numeric Types — int, float, long, complex.
===== map(function, iterable, ...) =====
Apply function to **every item of iterable** and return a list of the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be __extended with None items__. If function is None, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is __always a list__.
===== max(iterable[, key]) =====
===== max(arg1, arg2, *args[, key]) =====
Return the largest item in an iterable or the largest of two or more arguments.
If one positional argument is provided, iterable must be a non-empty iterable (such as a non-empty string, tuple or list). The largest item in the iterable is returned. If two or more positional arguments are provided, the largest of the positional arguments is returned.
The optional key argument specifies **a one-argument ordering function** like that used for list.sort(). The key argument, if supplied, must be __in keyword form__ (for example, max(a,b,c,key=func)).
Changed in version 2.5: Added support for the optional key argument.
===== memoryview(obj) =====
Return a “memory view” object created from the given argument. See memoryview type for more information.
===== min(iterable[, key]) =====
===== min(arg1, arg2, *args[, key]) =====
Return the smallest item in an iterable or the smallest of two or more arguments.
If one positional argument is provided, iterable must be a non-empty iterable (such as a non-empty string, tuple or list). The smallest item in the iterable is returned. If two or more positional arguments are provided, the smallest of the positional arguments is returned.
The optional key argument specifies a one-argument ordering function like that used for list.sort(). The key argument, if supplied, __must be in keyword form (__for example, min(a,b,c,key=func)).
Changed in version 2.5: Added support for the optional key argument.
===== next(iterator[, default]) =====
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.
New in version 2.6.
===== object() =====
Return a new featureless object. object is a base for all new style classes. It has the methods that are common to all instances of new style classes.
New in version 2.2.
Changed in version 2.3: This function does not accept any arguments. Formerly, it accepted arguments but ignored them.
===== oct(x) =====
Convert an integer number (of any size) to an octal string. The result is a valid Python expression.
Changed in version 2.4: Formerly only returned an unsigned literal.
===== open(name[, mode[, buffering]]) =====
Open a file, returning an object of the **file type** described in section File Objects. If the file cannot be opened, __IOError__ is raised. When opening a file, its preferable to use open() instead of invoking the file constructor directly.
The first two arguments are the same as for stdios fopen(): name is the file name to be opened, and mode is a string indicating how the file is to be opened.
The most commonly-used values of mode are __'r'__ for reading, __'w'__ for writing (**truncating the file** if it already exists), and __'a'__ for appending (which on some Unix systems means that all writes append to the end of the file regardless of the current seek position). If mode is omitted, __it defaults to 'r'__. The default is to use __text mode__, which may convert '\n' characters to a platform-specific representation on writing and back on reading. Thus, when opening a binary file, you should append __'b'__ to the mode value to open the file in binary mode, which will improve portability. (Appending 'b' is useful even on systems that dont treat binary and text files differently, where it serves as documentation.) See below for more possible values of mode.
The optional buffering argument specifies the files desired buffer size: __0 means unbuffered, 1 means line buffered, any other positive value means use a buffer of (approximately) that size.__ A negative buffering means to use **the system default**, which is usually line buffered for tty devices and fully buffered for other files. If omitted, the system default is used. [2]
Modes **'r+', 'w+' and 'a+'** open the file for updating (note that __'w+' truncates the file__). Append 'b' to the mode to open the file in binary mode, on systems that differentiate between binary and text files; on systems that dont have this distinction, adding the 'b' has no effect.
In addition to the standard **fopen()** values mode may be 'U' or 'rU'. Python is usually built with universal newlines support; supplying 'U' opens the file as a text file, but lines may be terminated by any of the following: the Unix end-of-line convention '\n', the Macintosh convention '\r', or the Windows convention '\r\n'. All of these external representations are seen as '\n' by the Python program. If Python is built without universal newlines support a mode with 'U' is the same as normal text mode. Note that file objects so opened also have an attribute called newlines which has a value of None (if no newlines have yet been seen), '\n', '\r', '\r\n', or a tuple containing all the newline types seen.
Python enforces that the mode, after stripping 'U', begins with 'r', 'w' or 'a'.
Python provides many file handling modules including __fileinput, os, os.path, tempfile, and shutil__.
Changed in version 2.5: Restriction on first letter of mode string introduced.
===== ord(c) =====
Given a string of length one, return an integer representing the Unicode code point of the character when the argument is a unicode object, or the value of the byte when the argument is an 8-bit string. For example, ord('a') returns the integer 97, ord(u'\u2020') returns 8224. This is the inverse of chr() for 8-bit strings and of unichr() for unicode objects. If a unicode argument is given and Python was built with UCS2 Unicode, then the characters code point must be in the range [0..65535] inclusive; otherwise the string length is two, and a TypeError will be raised.
===== pow(x, y[, z]) =====
Return x to the power y; if z is present, return **x to the power y, modulo z** (computed more efficiently than pow(x, y) % z). The two-argument form pow(x, y) is equivalent to using the power operator: **x**y**.
The arguments must have numeric types. With mixed operand types, the coercion rules for binary arithmetic operators apply. For int and long int operands, the result has the same type as the operands (after coercion) unless the second argument is negative; in that case, all arguments are converted to float and a float result is delivered. For example, 10**2 returns 100, but 10**-2 returns 0.01. (This last feature was added in Python 2.2. In Python 2.1 and before, if both arguments were of integer types and the second argument was negative, an exception was raised.) If the second argument is negative, the third argument must be omitted. If z is present, x and y must be of integer types, and y must be non-negative. (This restriction was added in Python 2.2. In Python 2.1 and before, floating 3-argument pow() returned platform-dependent results depending on floating-point rounding accidents.)
===== print(*objects, sep=' ', end='\n', file=sys.stdout) =====
Print objects to the stream file, separated by sep and followed by end. sep, end and file, if present, must be given as keyword arguments.
All non-keyword arguments are converted to strings like **str()** does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.
The file argument must be an object with a write(string) method; if it is not present or None, sys.stdout will be used. Output buffering is determined by file. Use **file.flush()** to ensure, for instance, immediate appearance on a screen.
Note This function is **not normally available as a built-in** since the name print is recognized as the **print statement**.
该函数一般不能直接使用因为pythn2中的print是一个statement。
To disable the statement and use the print() function, use this future statement at the top of your module:
__from __future__ import print_function__
New in version 2.6.
===== property([fget[, fset[, fdel[, doc]]]]) =====
Return a property attribute for new-style classes (classes that derive from object).
fget is a function for getting an attribute value, likewise fset is a function for setting, and fdel a function for deling, an attribute. Typical use is to define a managed attribute x:
class C(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
__x = property(getx, setx, delx, "I'm the 'x' property.")__
If then c is an instance of C, **c.x will invoke the getter, c.x = value will invoke the setter and del c.x the deleter**.
If given, doc will be the docstring of the property attribute例如上面的最后一行字符串. Otherwise, the property will copy fgets docstring (if it exists). This makes it possible to create **read-only properties** easily using property() as a decorator:
class Parrot(object):
def __init__(self):
self._voltage = 100000
__@property //生成一个read-only properity。__
def voltage(self):
"""Get the current voltage."""
return self._voltage
turns the voltage() method into a “getter” for a read-only attribute with the same name.
A property object has __getter, setter, and deleter__ methods usable as decorators that create a copy of the property with the corresponding accessor function set to the decorated function. This is best explained with an example:
class C(object):
def __init__(self):
self._x = None
@property //property装饰器使修饰的函数x变为property object默认生成一个read-only properity。
def x(self):
"""I'm the 'x' property."""
return self._x
__@x__.setter //调用property object的setter方法。
__def x__(self, value):
self._x = value
@x.deleter
def x(self): //注意没有参数x就暗示了属性的类型。
del self._x
This code is exactly equivalent to the first example. Be sure to give the additional functions **the same name as the original** property (x in this case.)
The returned property also has the attributes fget, fset, and fdel corresponding to the constructor arguments.
New in version 2.2.
Changed in version 2.5: Use fgets docstring if no doc given.
Changed in version 2.6: The getter, setter, and deleter attributes were added.
===== range(stop) =====
===== range(start, stop[, step]) =====
This is a versatile function to create lists containing arithmetic progressions. It is most often used in __for loops__. The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns a list of plain integers [start, start + step, start + 2 * step, ...]. If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised). Example:
>>>
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(0, -10, -1)
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]
===== raw_input([prompt]) =====
If the prompt argument is present, it is written to standard output __without a trailing newline__. The function then reads a line from input, __converts it to a string (stripping a trailing newline)__, and returns that. When EOF is read, EOFError is raised. Example:
>>>
>>> s = raw_input('--> ')
--> Monty Python's Flying Circus
>>> s
"Monty Python's Flying Circus"
If the readline module was loaded, then raw_input() will use it to provide elaborate line editing and history features.
===== reduce(function, iterable[, initializer]) =====
Apply function of __two arguments__ cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). **The left argument, x, is the **__accumulated value__** and the right argument, y, is the update value from the iterable**. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned. Roughly equivalent to:
def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
try:
initializer = next(it)
except StopIteration:
raise TypeError('reduce() of empty sequence with no initial value')
**accum_value** = initializer
for x in it:
accum_value = function(accum_value, x)
return accum_value
===== reload(module) =====
Reload a previously imported module. The argument must be **a module object**, so it must have been successfully imported before. This is useful if you have **edited the module source file** using an external editor and want to try out the new version without leaving the Python interpreter. The return value is the module object (the same as the module argument).
When reload(module) is executed:
Python modules code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the modules dictionary. The init function of extension modules is not called a second time.
As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.
The names in the module namespace are updated to point to any new or changed objects.
Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.
There are a number of other caveats:
If a module is syntactically correct but its initialization fails, the first import statement for it does not bind its name locally, but does store a (partially initialized) module object in sys.modules. To reload the module you must first import it again (this will bind the name to the partially initialized module object) before you can reload() it.
When a module is reloaded, its dictionary (containing the modules global variables) is retained. Redefinitions of names will override the old definitions, so this is generally not a problem. If the new version of a module does not define a name that was defined by the old version, the old definition remains. This feature can be used to the modules advantage if it maintains a global table or cache of objects — with a try statement it can test for the tables presence and skip its initialization if desired:
try:
cache
except NameError:
cache = {}
It is legal though generally not very useful to reload built-in or dynamically loaded modules, except for sys, __main__ and __builtin__. In many cases, however, extension modules are not designed to be initialized more than once, and may fail in arbitrary ways when reloaded.
If a module imports objects from another module using from ... import ..., calling reload() for the other module does not redefine the objects imported from it — one way around this is to re-execute the from statement, another is to use import and qualified names (module.*name*) instead.
If a module instantiates instances of a class, reloading the module that defines the class does not affect the method definitions of the instances — they continue to use the old class definition. The same is true for derived classes.
===== repr(object) =====
Return a string containing **a printable representation of an object**. This is the same value yielded by conversions (reverse quotes). It is sometimes useful to be able to access this operation as an ordinary function. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.
===== reversed(seq) =====
__Return a reverse iterator.__ seq must be an object which has a __reversed__() method or supports **the sequence protocol** (the __len__() method and the __getitem__() method with integer arguments starting at 0).
New in version 2.4.
Changed in version 2.6: Added the possibility to write a custom __reversed__() method.
===== round(number[, ndigits]) =====
Return the floating point value number rounded to **ndigits digits after the decimal point.** If ndigits is omitted, it defaults to zero. The result is a floating point number. Values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done away from 0 (so. for example, round(0.5) is 1.0 and round(-0.5) is -1.0).
Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: its a result of the fact that most decimal fractions cant be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.
===== set([iterable]) =====
Return a new set object, optionally with elements taken from iterable. set is a built-in class. See set and Set Types — set, frozenset for documentation about this class.
For other containers see the built-in frozenset, list, tuple, and dict classes, as well as the collections module.
New in version 2.4.
===== setattr(object, name, value) =====
This is the counterpart of getattr(). The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it. For example, setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.
===== slice(stop) =====
===== slice(start, stop[, step]) =====
Return a slice object representing the set of indices specified by **range(start, stop, step)**. The start and step arguments default to None. Slice objects have read-only data attributes start, stop and step which merely return the argument values (or their default). They have no other explicit functionality; however they are used by Numerical Python and other third party extensions. Slice objects are also generated when extended indexing syntax is used. For example: a[start:stop:step] or a[start:stop, i]. See itertools.islice() for an alternate version that returns an iterator.
===== sorted(iterable[, cmp[, key[, reverse]]]) =====
Return __a new sorted list__ from the items in iterable.
The optional arguments **cmp, key, and reverse** have the same meaning as those for the list.sort() method (described in section Mutable Sequence Types).
cmp specifies __a custom comparison function of two arguments__ (iterable elements) which should __return a negative, zero or positive number__ depending on whether the first argument is considered smaller than, equal to, or larger than the second argument: cmp=lambda x,y: cmp(x.lower(), y.lower()). The default value is None.
key specifies a function of one argument that is used to **extract a comparison key from each list element**: key=str.lower. The default value is None (compare the elements directly).
reverse is a boolean value. If set to True, then the list elements are sorted as if each comparison were reversed.
In general, the key and reverse conversion processes are much faster than specifying an equivalent cmp function. This is because cmp is called multiple times for each list element while key and reverse touch each element only once. Use **functools.cmp_to_key()** to convert an old-style cmp function to a key function.
For sorting examples and a brief sorting tutorial, see Sorting HowTo.
New in version 2.4.
===== staticmethod(function) =====
Return a static method for function.
A static method does not receive an implicit first argument. To declare a static method, use this idiom:
class C:
@staticmethod
def f(arg1, arg2, ...): ...
The @staticmethod form is a function decorator see the description of function definitions in Function definitions for details.
It can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class.
Static methods in Python are similar to those found in Java or C++. Also see classmethod() for a variant that is useful for creating alternate class constructors.
For more information on static methods, consult the documentation on the standard type hierarchy in The standard type hierarchy.
New in version 2.2.
Changed in version 2.4: Function decorator syntax added.
===== str(object='') =====
Return a string containing a nicely printable representation of an object. For strings, this returns the string itself. The difference with repr(object) is that str(object) does not always attempt to return a string that is acceptable to eval(); its goal is to return a printable string. If no argument is given, returns the empty string, ''.
For more information on strings see Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange which describes sequence functionality (strings are sequences), and also the string-specific methods described in the String Methods section. To output formatted strings use template strings or the % operator described in the String Formatting Operations section. In addition see the String Services section. See also unicode().
===== sum(iterable[, start]) =====
Sums start and the items of an iterable from left to right and returns the total. start defaults to 0. The iterables items are normally numbers, and the start value is not allowed to be a string.
For some use cases, there are good alternatives to sum(). The preferred, fast way to concatenate a sequence of strings is by calling __''.join(sequence)__. To add floating point values with extended precision, see math.fsum(). To concatenate a series of iterables, consider using itertools.chain().
New in version 2.3.
===== super(type[, object-or-type]) =====
Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.
The ____mro____ attribute of the type lists **the method resolution search order** used by both getattr() and super(). The attribute is dynamic and can change whenever the inheritance hierarchy is updated.
If the second argument is omitted, the super object returned is unbound. If the second argument is an object, isinstance(obj, type) must be true. If the second argument is a type, issubclass(type2, type) must be true (this is useful for classmethods).
Note super() only works for new-style classes.
There are two typical use cases for super. In a class hierarchy with single inheritance, **super can be used to refer to parent classes **__without naming them explicitly__, thus making the code more maintainable. This use closely parallels the use of super in other programming languages.
The second use case is to support __cooperative multiple inheritance in a dynamic execution environment__. This use case is unique to Python and is not found in statically compiled languages or languages that only support single inheritance. This makes it possible to implement “diamond diagrams” where multiple base classes implement the same method. Good design dictates that this method have the same calling signature in every case (because the order of calls is determined at runtime, because that order adapts to changes in the class hierarchy, and because that order can include sibling classes that are unknown prior to runtime).
For both use cases, a typical superclass call looks like this:
class C(B):
def method(self, arg):
super(C, self).method(arg)
Note that super() is implemented as part of the binding process for explicit dotted attribute lookups such as super().__getitem__(name). It does so by implementing its own __getattribute__() method for searching classes in a predictable order that supports cooperative multiple inheritance. Accordingly, super() is undefined for implicit lookups using statements or operators such as super()[name].
Also note that super() is not limited to use inside methods. The two argument form specifies the arguments exactly and makes the appropriate references.
For practical suggestions on how to design cooperative classes using super(), see guide to using super().
New in version 2.2.
===== tuple([iterable]) =====
Return a tuple whose items are the same and in the same order as iterables items. iterable may be a sequence, a container that supports iteration, or an iterator object. If iterable is already a tuple, it is returned unchanged. For instance, tuple('abc') returns ('a', 'b', 'c') and tuple([1, 2, 3]) returns (1, 2, 3). If no argument is given, returns a new empty tuple, ().
tuple is an immutable sequence type, as documented in Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange. For other containers see the built in dict, list, and set classes, and the collections module.
===== type(object) =====
===== type(name, bases, dict) =====
With one argument, return the type of an object. The return value is a type object. The isinstance() built-in function is recommended for testing the type of an object.
With three arguments, return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the __name__ attribute; the bases tuple itemizes the base classes and becomes the __bases__ attribute; and the dict dictionary is the namespace containing definitions for class body and becomes the __dict__ attribute. For example, the following two statements create identical type objects:
>>>
>>> class X(object):
... a = 1
...
>>> X = type('X', (object,), dict(a=1))
New in version 2.2.
===== unichr(i) =====
Return the Unicode string of one character whose Unicode code is the integer i. For example, unichr(97) returns the string u'a'. This is the inverse of ord() for Unicode strings. The valid range for the argument depends how Python was configured it may be either UCS2 [0..0xFFFF] or UCS4 [0..0x10FFFF]. ValueError is raised otherwise. For ASCII and 8-bit strings see chr().
New in version 2.0.
===== unicode(object='') =====
===== unicode(object[, encoding[, errors]]) =====
Return the Unicode string version of object using one of the following modes:
If encoding and/or errors are given, unicode() will decode the object which can either be an 8-bit string or a character buffer using the codec for encoding. The encoding parameter is a string giving the name of an encoding; if the encoding is not known, LookupError is raised. Error handling is done according to errors; this specifies the treatment of characters which are invalid in the input encoding. If errors is 'strict' (the default), a ValueError is raised on errors, while a value of 'ignore' causes errors to be silently ignored, and a value of 'replace' causes the official Unicode replacement character, U+FFFD, to be used to replace input characters which cannot be decoded. See also the codecs module.
If no optional parameters are given, unicode() will mimic the behaviour of str() except that it returns Unicode strings instead of 8-bit strings. More precisely, if object is a Unicode string or subclass it will return that Unicode string without any additional decoding applied.
For objects which provide a __unicode__() method, it will call this method without arguments to create a Unicode string. For all other objects, the 8-bit string version or representation is requested and then converted to a Unicode string using the codec for the default encoding in 'strict' mode.
For more information on Unicode strings see Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange which describes sequence functionality (Unicode strings are sequences), and also the string-specific methods described in the String Methods section. To output formatted strings use template strings or the % operator described in the String Formatting Operations section. In addition see the String Services section. See also str().
New in version 2.0.
Changed in version 2.2: Support for __unicode__() added.
===== vars([object]) =====
Return the __dict__ attribute for a module, class, instance, or any other object with a __dict__ attribute.
Objects such as modules and instances have an updateable __dict__ attribute; however, other objects may have write restrictions on their __dict__ attributes (for example, new-style classes use a dictproxy to prevent direct dictionary updates).
Without an argument, vars() acts like locals(). Note, the locals dictionary is only useful for reads since updates to the locals dictionary are ignored.
===== xrange(stop) =====
===== xrange(start, stop[, step]) =====
This function is very similar to range(), but returns an xrange object instead of a list. This is an opaque sequence type which yields the same values as the corresponding list, without actually storing them all simultaneously. The advantage of xrange() over range() is minimal (since xrange() still has to create the values when asked for them) except when a very large range is used on a memory-starved machine or when all of the ranges elements are never used (such as when the loop is usually terminated with break). For more information on xrange objects, see XRange Type and Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange.
CPython implementation detail: xrange() is intended to be simple and fast. Implementations may impose restrictions to achieve this. The C implementation of Python restricts all arguments to native C longs (“short” Python integers), and also requires that the number of elements fit in a native C long. If a larger range is needed, an alternate version can be crafted using the itertools module: islice(count(start, step), (stop-start+step-1+2*(step<0))//step).
===== zip([iterable, ...]) =====
This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip() is similar to map() with an initial argument of None. With a single sequence argument, it returns a list of 1-tuples. With no arguments, it returns an empty list.
The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n).
zip() in conjunction with the * operator can be used to unzip a list:
>>>
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zipped)
>>> x == list(x2) and y == list(y2)
True
New in version 2.0.
Changed in version 2.4: Formerly, zip() required at least one argument and zip() raised a TypeError instead of returning an empty list.
===== __import__(name[, globals[, locals[, fromlist[, level]]]]) =====
Note This is an advanced function that is not needed in everyday Python programming, unlike importlib.import_module().
This function is invoked by the import statement. It can be replaced (by importing the __builtin__ module and assigning to __builtin__.__import__) in order to change semantics of the import statement, but nowadays it is usually simpler to use import hooks (see PEP 302). Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.
The function imports the module name, potentially using the given globals and locals to determine how to interpret the name in a package context. The fromlist gives the names of objects or submodules that should be imported from the module given by name. The standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.
level specifies whether to use absolute or relative imports. The default is -1 which indicates both absolute and relative imports will be attempted. 0 means only perform absolute imports. Positive values for level indicate the number of parent directories to search relative to the directory of the module calling __import__().
When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned.
For example, the statement import spam results in bytecode resembling the following code:
spam = __import__('spam', globals(), locals(), [], -1)
The statement import spam.ham results in this call:
spam = __import__('spam.ham', globals(), locals(), [], -1)
Note how __import__() returns the toplevel module here because this is the object that is bound to a name by the import statement.
On the other hand, the statement from spam.ham import eggs, sausage as saus results in
_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
eggs = _temp.eggs
saus = _temp.sausage
Here, the spam.ham module is returned from __import__(). From this object, the names to import are retrieved and assigned to their respective names.
If you simply want to import a module (potentially within a package) by name, use importlib.import_module().
Changed in version 2.5: The level parameter was added.
Changed in version 2.5: Keyword support for parameters was added.
===== 3. Non-essential Built-in Functions =====
There are several built-in functions that are no longer essential to learn, know or use in modern Python programming. They have been kept here to maintain backwards compatibility with programs written for older versions of Python.
Python programmers, trainers, students and book writers should feel free to bypass these functions without concerns about missing something important.
apply(function, args[, keywords])
The function argument must be a callable object (a user-defined or built-in function or method, or a class object) and the args argument must be a sequence. The function is called with args as the argument list; the number of arguments is the length of the tuple. If the optional keywords argument is present, it must be a dictionary whose keys are strings. It specifies keyword arguments to be added to the end of the argument list. Calling apply() is different from just calling function(args), since in that case there is always exactly one argument. The use of apply() is equivalent to function(*args, **keywords).
Deprecated since version 2.3: Use function(*args, **keywords) instead of apply(function, args, keywords) (see Unpacking Argument Lists).
buffer(object[, offset[, size]])
The object argument must be an object that supports the buffer call interface (such as strings, arrays, and buffers). A new buffer object will be created which references the object argument. The buffer object will be a slice from the beginning of object (or from the specified offset). The slice will extend to the end of object (or will have a length given by the size argument).
coerce(x, y)
Return a tuple consisting of the two numeric arguments converted to a common type, using the same rules as used by arithmetic operations. If coercion is not possible, raise TypeError.
intern(string)
Enter string in the table of “interned” strings and return the interned string which is string itself or a copy. Interning strings is useful to gain a little performance on dictionary lookup if the keys in a dictionary are interned, and the lookup key is interned, the key comparisons (after hashing) can be done by a pointer compare instead of a string compare. Normally, the names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes have interned keys.
Changed in version 2.3: Interned strings are not immortal (like they used to be in Python 2.2 and before); you must keep a reference to the return value of intern() around to benefit from it.
Footnotes
[1] It is used relatively rarely so does not warrant being made into a statement.
[2] Specifying a buffer size currently has no effect on systems that dont have setvbuf(). The interface to specify the buffer size is not done using a method that calls setvbuf(), because that may dump core when called after any I/O has been performed, and theres no reliable way to determine whether this is the case.
[3] In the current implementation, local variable bindings cannot normally be affected this way, but variables retrieved from other scopes (such as modules) can be. This may change.
»
indexmodules |next |previous | Python » Documentation » The Python Standard Library »
© Copyright 1990-2012, Python Software Foundation.
The Python Software Foundation is a non-profit corporation. Please donate.
Last updated on Dec 01, 2012. Found a bug?
Created using Sphinx 1.0.7.

View File

@@ -0,0 +1,57 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-02T20:49:44+08:00
====== 4. Built-in Constants ======
Created Sunday 02 December 2012
A small number of constants live in the built-in namespace. They are:
===== False =====
The false value of the bool type.
New in version 2.3.
===== True =====
The true value of the bool type.
New in version 2.3.
===== None =====
The sole value of types.NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function.
Changed in version 2.4: Assignments to None are illegal and raise a SyntaxError.
===== NotImplemented =====
Special value which can be returned by the “rich comparison” special methods (__eq__(), __lt__(), and friends), to indicate that the comparison is not implemented with respect to the other type.
===== Ellipsis =====
Special value used in conjunction with extended slicing syntax.
===== __debug__ =====
This constant is true if Python was __not started with an -O option__. See also the assert statement.
Note The names None and __debug__ cannot be reassigned (assignments to them, even as an attribute name, raise SyntaxError), so they can be considered “true” constants.
Changed in version 2.7: Assignments to __debug__ as an attribute became illegal.
===== 4.1. Constants added by the site module =====
The site module (which is __imported automatically during startup__, except if the -S command-line option is given) adds several constants to the built-in namespace. They are useful for the interactive interpreter shell and should not be used in programs.
===== quit([code=None]) =====
===== exit([code=None]) =====
Objects that when printed, print a message like “Use quit() or Ctrl-D (i.e. EOF) to exit”, and when called, raise SystemExit with the specified exit code.
==== copyright ====
==== license ====
==== credits ====
Objects that when printed, print a message like “Type license() to see the full license text”, and when called, display the corresponding text in a pager-like fashion (one screen at a time).
»
indexmodules |next |previous | Python » Documentation » The Python Standard Library »
© Copyright 1990-2012, Python Software Foundation.
The Python Software Foundation is a non-profit corporation. Please donate.
Last updated on Dec 02, 2012. Found a bug?
Created using Sphinx 1.0.7.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-02T10:31:10+08:00
====== int ======
Created Sunday 02 December 2012
In [12]: lst = '123\n' //如果字符串中包含__空字符(如空格, \t, \v, \f, \n, \r)等__int(), float()等函数仍然有效。
In [13]: lst
Out[13]: '123\n'
__In [14]: int(lst)__
__Out[14]: 123__
In [15]: lst = '123\n\t'
In [16]: lst
Out[16]: '123\n\t'
In [18]: int(lst)
Out[18]: 123
In [19]: lst = '123\nstr' //字符串中包含除了数字外的非空字符,转换时提示错误。
In [20]: lst
Out[20]: '123\nstr'
In [21]: int(lst)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-21-7fdf78d62dad> in <module>()
----> 1 int(lst)
__ValueError:__ invalid literal for int() with **base 10**: '123\nstr'
In [22]:

View File

@@ -0,0 +1,74 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-02T09:40:06+08:00
====== list ======
Created Sunday 02 December 2012
~ $ ipython2
Python 2.7.3 (default, Apr 24 2012, 00:06:13)
Type "copyright", "credits" or "license" for more information.
In [1]: lst = ['sdfds', 'dsfsd', 1, 3, [123, 22, 33, 'dsfds']]
__In [2]: lst[0]=[1, 2, 3] //为列表的某个成员赋值时python不会对右边的值进行迭代。__
In [3]: lst
Out[3]: 1, 2, 3], 'dsfsd', 1, 3, [123, 22, 33, 'dsfds'
__In [8]: lst[0:0] = 'dffds' //为列表的成员列表赋值时python会对右边的值进行迭代。__
In [9]: lst
Out[9]: [__'d', 'f', 'f', 'd', 's',__ 'dffds', 2, 3, 'dsfsd', 1, 3, [123, 22, 33, 'dsfds']] //可见python对等式右边序列进行了迭代。
In [4]: lst[0:1] = [1, 2, 3]
In [5]: lst
Out[5]: [1, 2, 3, 'dsfsd', 1, 3, [123, 22, 33, 'dsfds']] //同上
In [10]:
__In [10]: lst[0:0] = ['dffds'] //将字符序列外加[和]就可以阻止迭代(因为这时字符串时列表的唯一成员)__
In [11]: lst
Out[11]:
['dffds',
'd',
'f',
'f',
'd',
's',
'dffds',
2,
3,
'dsfsd',
1,
3,
[123, 22, 33, 'dsfds']]
In [12]:
In [24]: lst
Out[24]: '123\nstr'
In [25]: lst = [1, 2, 3]
In [26]: lst = lst + [4, 5, 6] //列表相+时python会对第二个列表进行__迭代__。
In [27]: lst
Out[27]: [1, 2, 3, **4, 5, 6]**
__In [28]: lst = lst + 'fdf' //只能list间相加__
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-0818686a3a7d> in <module>()
----> 1 lst = lst + 'fdf'
TypeError: **can only concatenate list** (not "str") to list
In [29]: lst = lst + list('fdf')
In [30]: lst
Out[30]: [1, 2, 3, 4, 5, 6, 'f', 'd', 'f']
In [31]:

View File

@@ -6,10 +6,6 @@ Creation-Date: 2012-01-05T15:16:44+08:00
Created Thursday 05 January 2012
http://www.noah.org/wiki/Pexpect
pexpect
(Redirected from Pexpect)
Contents
1 Pexpect version 2.3
@@ -59,22 +55,12 @@ Download the current version here from the SourceForge site here: pexpect curren
===== Description of Pexpect =====
Pexpect is a **pure Python module** that makes Python a better tool for__ controlling and automating other programs__. Pexpect is similar to the Don Libes `Expect` system, but Pexpect as a different interface that is easier to understand.
Pexpect is__ basically a pattern matching system__. It runs programs and watches output. When output matches a given pattern Pexpect can **respond** as if a human were typing responses. Pexpect can be used for** automation, testing, and screen scraping**.
Pexpect can be used for__ automating interactive console applications __such as ssh, ftp, passwd, telnet, etc.
It can also be used to__ control web applications__ via `lynx`, `w3m`, or some other **text-based **web browser. Pexpect is pure Python. Unlike other Expect-like modules for Python Pexpect does not require TCL or Expect nor does it require C extensions to be compiled. It should work on any platform that supports the standard Python pty module.
Pexpect can be used for__ automating interactive console applications __such as ssh, ftp, passwd, telnet, etc. It can also be used to__ control web applications__ via `lynx`, `w3m`, or some other **text-based **web browser. Pexpect is pure Python. Unlike other Expect-like modules for Python Pexpect does not require TCL or Expect nor does it require C extensions to be compiled. It should work on any platform that supports the standard Python __pty__ module.
Send questions to: noah@noah.org Put 'pexpect' in the subject.
License
MIT style -- Free, open source, and all that good stuff.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Pexpect Copyright (c) 2010 Noah Spurrier
===== Download and Installation =====

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-30T20:55:38+08:00
====== string的操作函数 ======
Created Friday 30 November 2012
转自:http://www.91linux.com/html/article/program/python/20090804/17759.htm
在python有各种各样的string操作函数。在历史上string类在python中经历了一段轮回的历史。在最开始的时候python有**一个专门的string的module**要使用string的方法要先import但后来由于众多的python使用者的建议从python2.0开始string方法改为用S.method()的形式调用只要S是一个字符串对象就可以这样使用而不用import。同时__为了保持向后兼容__现在的python中仍然保留了一个string的module其中定义的方法与S.method()是相同的,这些方法都**最后都指向了**用S.method()调用的函数。要注意S.method()能调用的方法比string的module中的多比如isdigit()、istitle()等就只能用S.method()的方式调用。
对一个字符串对象首先想到的操作可能就是计算它有多少个字符组成很容易想到用S.len()但这是错的应该是__len(S)__。因为len()是内置函数包括在__builtin__模块中。python不把len()包含在string类型中乍看起来好像有点不可理解其实一切有其合理的逻辑在里头。len()不仅可以计算字符串中的字符数还可以计算list的成员数tuple的成员数等等因此**单单把len()算在string里是不合适**因此一是可以__把len()作为通用函数__用重载实现对不同类型的操作还有就是可以在每种有len()运算的类型中都要包含一个len()函数。python选择的是第一种解决办法。类似的还有str(arg)函数它把arg用string类型表示出来。
===== 字符串中字符大小写的变换: =====
S.lower() #小写
S.upper() #大写
S.swapcase() #大小写互换
S.capitalize() #首字母大写
String.capwords(S)
#这是模块中的方法。它把S用split()函数分开然后用capitalize()把首字母变成大写最后用join()合并到一起
S.title() #只有首字母大写,其余为小写,模块中没有这个方法
===== 字符串在输出时的对齐: =====
S.ljust(width,[fillchar])
#输出width个字符S左对齐不足部分用fillchar填充默认的为空格。
S.rjust(width,[fillchar]) #右对齐
S.center(width, [fillchar]) #中间对齐
S.zfill(width) #把S变成width长并在右对齐不足部分用0补足
===== 字符串中的搜索和替换: =====
S.find(substr, [start, [end]])
#返回S中出现substr的第一个字母的标号如果S中没有substr则返回-1。start和end作用就相当于在S[start:end]中搜索
S.index(substr, [start, [end]])
#与find()相同只是在S中没有substr时会返回一个运行时错误
S.rfind(substr, [start, [end]])
#返回S中最后出现的substr的第一个字母的标号如果S中没有substr则返回-1也就是说从右边算起的第一次出现的substr的首字母标号
S.rindex(substr, [start, [end]])
S.count(substr, [start, [end]]) #计算substr在S中出现的次数
S.replace(oldstr, newstr, [count])
#把S中的oldstar替换为newstrcount为替换次数。这是替换的通用形式还有一些函数进行特殊字符的替换
S.strip([chars])
#把S中前后chars中有的字符全部去掉可以理解为把S前后chars替换为None
S.lstrip([chars])
S.rstrip([chars])
S.expandtabs([tabsize])
#把S中的tab字符替换没空格每个tab替换为tabsize个空格默认是8个
===== 字符串的分割和组合: =====
S.split([sep, [maxsplit]])
#以sep为分隔符把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符
S.rsplit([sep, [maxsplit]])
S.splitlines([keepends])
#把S按照行分割符分为一个listkeepends是一个bool值如果为真每行后而会保留行分割符。
S.join(seq) #把seq代表的序列──字符串序列用S连接起来
===== 字符串的mapping这一功能包含两个函数 =====
String.maketrans(from, to)
#返回一个256个字符组成的翻译表其中from中的字符被一一对应地转换成to所以from和to必须是等长的。
S.translate(table[,deletechars])
#使用上面的函数产后的翻译表把S进行翻译并把deletechars中有的字符删掉。需要注意的是如果S为unicode字符串那么就不支持deletechars参数可以使用把某个字符翻译为None的方式实现相同的功能。此外还可以使用codecs模块的功能来创建更加功能强大的翻译表。
===== 字符串还有一对编码和解码的函数: =====
S.encode([encoding,[errors]])
#其中encoding可以有多种值比如gb2312 gbk gb18030 bz2 zlib big5 bzse64等都支持。errors默认值为"strict"意思是UnicodeError。可能的值还有'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 和所有的通过codecs.register_error注册的值。这一部分内容涉及codecs模块不是特明白
S.decode([encoding,[errors]])
===== 字符串的测试函数这一类函数在string模块中没有这些函数返回的都是bool值 =====
S.startwith(prefix[,start[,end]])
#是否以prefix开头
S.endwith(suffix[,start[,end]])
#以suffix结尾
S.isalnum()
#是否全是字母和数字,并至少有一个字符
S.isalpha() #是否全是字母,并至少有一个字符
S.isdigit() #是否全是数字,并至少有一个字符
S.isspace() #是否全是空白字符,并至少有一个字符
S.islower() #S中的字母是否全是小写
S.isupper() #S中的字母是否便是大写
S.istitle() #S是否是首字母大写的
===== 字符串类型转换函数这几个函数只在string模块中有 =====
**string.atoi(s[,base])**
#base默认为10如果为0,那么s就可以是012或0x23这种形式的字符串如果是16那么s就只能是0x23或0X12这种形式的字符串
string.atol(s[,base]) #转成long
string.atof(s[,base]) #转成float
这里再强调一次字符串对象是不可改变的也就是说在python创建一个字符串后你不能把这个字符中的某一部分改变。任何上面的函数改变了字符串后都会返回一个__新的字符串__原字串并没有变。其实这也是有变通的办法的__可以用S=list(S)这个函数把S变为由单个字符为成员的list这样的话就可以使用S[3]='a'的方式改变值然后再使用S=" ".join(S)还原成字符串__

View File

@@ -39,13 +39,13 @@ __subprocess.STDOUT__
[*] subprocess.__call__(**args**, *, stdin=None, stdout=None, stderr=None, shell=False)
Run the command described by __args__. __Wait __for command to complete, then return the **returncode** attribute.
适合非交互式进程执行args指定的程序直到其结束返回退出码即使命令执行失败也不产生异常。stdin,stdout,stderr一般不使用PIPE因为调用进程一般不读这种非交互式进程的输出。stdin为None表示子进程的stdin将__继承__调用进程的描述符。
适合非交互式进程执行args指定的程序直到其结束返回退出码即使命令执行失败也不产生异常。stdin,stdout,stderr一般不使用PIPE因为调用进程一般不读这种非交互式进程的输出。stdin为None表示子进程的stdin将__继承__调用进程的描述符。
The arguments shown above are merely the most common ones, described below in Frequently Used Arguments (hence the slightly odd notation in the abbreviated signature). The full function signature is the same as that of the __Popen__ constructor - this functions passes all supplied arguments directly through to that interface.
Examples:
>>>
__#如果shell=False(默认)则python调用os.execlp()来执行args因此如果args是字符串则只能包含命令名如果是序列则可以包含命令参数(参数不支持shell的特性如文件名扩展等。),而且每个元素一般包括一个参数(否则调用程序可能会产生解析错误)。__
__#如果shell=False(默认)则python调用os.exelp()来执行args因此如果args是字符串则只能包含命令名如果是序列则可以包含命令参数(参数不支持shell的特性如文件名扩展等。)。__
>>> subprocess.call(__["ls", "-l"]__)
0
__#如果shell=True则python调用system shell来执行args调用形式为: execlp("/bin/sh", '-c', 'arg1', 'arg2', ....)因此如果args是字符串则其中可以包含命令参数而且支持各种shell特性如文件名扩展、命令扩展等如果args是序列则其第一个元素为命令名其它元素为被当作shell本身的参数。__
@@ -53,14 +53,14 @@ __#如果shell=True则python调用system shell来执行args调用形式为
>>> subprocess.call("exit 1", shell=True)
1
__总的来说__****如果shell=False, python使用os.execvp(...)来执行args因此如果args是一个string则该string只能是命令名称, 如果要为命令附加参数,则只能使用序列类型; 如果shell=True则python使用shell来执行行args因此args最好是一个string该string可以包含命令名及其参数如果使用序列则从第二个元素开始作为shell本身的参数(而非命令的参数。)。
__总的来说__****如果shell=False, python使用os.execvp(...)来执行args因此如果args是一个string则该string__只能是__命令名称, 如果要为命令附加参数,则只能使用序列类型; 如果shell=True则python使用shell来执行行args因此args最好是一个string该string可以包含命令名及其参数如果使用序列则从第二个元素开始作为shell本身的参数(而非命令的参数。)。
Invoking the system shell with shell=True can be **a security hazard** if combined with untrusted input. See the warning under Frequently Used Arguments for details.
__Do not use stdout=PIPE or stderr=PIPE with this function__. As the pipes are not being read in the current process, the child process may block if it generates enough output to a pipe to fill up the OS pipe buffer.
当使用stdout=PIPE时如果子进程填满了管道而调用进程没有读该管道时__子进程就会被阻塞__。因此使用上面三个函数时一般不使用这个参数。
The standard input and output channels for the process started by call() are__ bound to the parents input and output__. That means the calling programm cannot capture the output of the command. Use check_output() to capture the output for later processing.
The standard input and output channels for the process started by call() are__ bound to the parents input and output__. That means the calling programm __cannot capture the output__ of the command. Use check_output() to capture the output for later processing.
[*] subprocess.**check_call**(args, *, stdin=None, stdout=None, stderr=None, shell=False)
和call类似但是对返回值进行检查如果非0则引发异常。
@@ -152,9 +152,10 @@ __class subprocess.Popen__(args, bufsize=0, **executable**=None, stdin=None, std
Arguments are:
* args should be a string, or a sequence of program arguments. The program to execute is normally the **first item** in the args sequence or the string if a string is given, but can be **explicitly set **by using the __executable__ argument. When executable is given, the first item in the args sequence is still treated by most programs as the** command name**, which can then be different from the actual executable name. On Unix, it becomes the** display name** for the executing program in utilities such as ps.
* args should be a string, or a sequence of program arguments. The program to execute is normally the **first item** in the args sequence or the string(string作为命令名不能有参数) if a string is given, but can be **explicitly set **by using the __executable__ argument. When executable is given, the first item in the args sequence is still treated by most programs as the** command name**, which can then be different from the actual executable name. On Unix, it becomes the** display name** for the executing program in utilities such as ps. 如果ecutable被设置则其值将作为__实际执行__的命令名。args的第一个元素将作为命令的显示名称。
On Unix, with shell=False (default): In this case, the __Popen class uses os.execvp()__ to execute the child program. args should **normally be a sequence.** If a string is specified for args, it will be used as the **name or path of the program **to execute; this will only work if the program is being given __no__ arguments.
默认情况下shell=False这样args通常为sequence其第一个元素为待执行的命令其它元素为命令参数。如果args为string则其**只能为命令名或命令路径,不能带任何参数**。这时因为python使用os.execvp()来执行这个string。
Note
@@ -172,22 +173,22 @@ __class subprocess.Popen__(args, bufsize=0, **executable**=None, stdin=None, std
Note in particular that options (such as -input) and arguments (such as eggs.txt) that are separated by whitespace in the shell go in **separate list elements**, while arguments that need quoting or backslash escaping when used in the shell (such as filenames containing spaces or the echo command shown above) are single list elements.
On Unix, with shell=True: __If args is a string, it specifies the command string to execute through the shell.__ This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments __to the shell itself__. That is to say, Popen does the equivalent of:
在shell=True的情况下args最好是一个字符串。如果是序列则从第二个元素开始是__作为shell本身的参数__而非命令的参数。
在shell=True的情况下args**最好是一个字符串**。如果是序列则从第二个元素开始是__作为shell本身的参数__而非命令的参数。
__ Popen(['/bin/sh', '-c', args[0], args[1], ...])__
On Windows: the Popen class uses CreateProcess() to execute the child child program, which __operates on strings.__ If args is a sequence, it will be converted to a string in a manner described in Converting an argument sequence to a string on Windows.
**总的来说如果shell=False, python使用os.execvp(...)来执行args因此如果args是一个string则该string只能是命令名称, 如果要为命令执行参数,则只能使用序列类型; 如果shell=True则python使用shell来执行行args因此args最好是一个string该string可以包含命令名及其参数如果使用序列则从第二个元素开始作为**__shell本身__**的参数(而非命令的参数。)。**
* bufsize, if given, has the same meaning as the corresponding argument to the built-in open() function: **0 means **__unbuffered__**, 1 means**__ line buffered__**, any other positive value means use a buffer of (approximately) that size**. A negative bufsize means to use the system **default**, which usually means__ fully__ buffered. The** default value for bufsize is 0** (unbuffered).
控制打开文件的缓冲方式。
* bufsize, if given, has the same meaning as the corresponding argument to the built-in open() function: **0 means **__unbuffered__**, 1 means**__ line buffered__**, any other positive value means use a buffer of (approximately) that size**. A negative bufsize means to use the system **default**, which usually means__ fully__ buffered. The** default value for bufsize is 0** __(unbuffered)__.
控制打开文件的缓冲方式默认为unbuffered
Note
If you experience performance issues, it is recommended that you try to enable buffering by setting bufsize to either -1 or a large enough positive value (such as 4096).
* The executable argument **specifies the program** to execute. It is very seldom needed: Usually, the program to execute is defined by the **args** argument. If shell=True, the executable argument specifies __which shell to use__. On Unix, the default shell is /bin/sh. On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you would need to specify shell=True on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You dont need shell=True to run a batch file, nor to run a console-based executable.
* The executable argument **specifies the program** to execute. It is very seldom needed: Usually, the program to execute is defined by the **args** argument. If shell=True, the executable argument specifies __which shell to use__. On Unix, the default shell is **/bin/sh**. On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you would need to specify shell=True on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You dont need shell=True to run a batch file, nor to run a console-based executable.
* stdin, stdout and stderr specify the __executed programs __standard input, standard output and standard error file handles, respectively. Valid values are __PIPE, an existing file descriptor (a positive integer), an existing file object, and None__. PIPE indicates that a new pipe to the child should be created. With the **default settings of None**, no redirection will occur; the childs file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.
* stdin, stdout and stderr specify the __executed programs __standard input, standard output and standard error file handles, respectively. Valid values are __PIPE, an existing file descriptor (a positive integer), an existing file object, and None__. PIPE indicates that a new pipe to the child should be created. With the **default settings of None**, no redirection will occur; the childs file handles will be **inherited from the parent**. Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.
* If__ preexec_fn__ is set to a callable object, this object will be called in the child process just **before** the child is executed. (Unix only)
@@ -210,7 +211,8 @@ __class subprocess.Popen__(args, bufsize=0, **executable**=None, stdin=None, std
Note
This feature is only available if Python is built with universal newline support (the default). Also, the newlines attribute of the file objects stdout, stdin and stderr are not updated by the communicate() method.
* If given, startupinfo will be a STARTUPINFO object, which is passed to the underlying __CreateProcess __function. creationflags, if given, can be CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP. (Windows only)
* If given, startupinfo will be a STARTUPINFO object, which is passed to the underlying __CreateProcess __function.
* creationflags, if given, can be CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP. (Windows only)
==== 17.1.1.3. Exceptions ====
@@ -232,11 +234,11 @@ Popen()函数返回一个__Popen对象__。
Instances of the Popen class have the following methods:
**Popen.poll()**
Check if child process __has terminated__. Set and return returncode attribute.
Check if child process __has terminated__. Set and return **returncode** attribute.
**Popen.wait()**
Wait for child process to terminate. Set and return returncode attribute.
Wait for child process to terminate. Set and return **returncode** attribute.
Warning
This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.
@@ -247,7 +249,7 @@ __Popen.communicate__(input=None)
communicate() returns __a tuple__ (stdoutdata, stderrdata).
Note that if you want to send data to the processs stdin, you need to create the Popen object with__ stdin=PIPE__. Similarly, to get anything other than None in the result tuple, you need to give__ stdout=PIPE__ and/or stderr=PIPE too.
Note that if you want to send data to the processs stdin, you need to create the Popen object with__ stdin=PIPE__. Similarly, to get anything other than None in the result tuple, you need to give__ stdout=PIPE__ and/or __stderr=PIPE__ too.
Note
The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
@@ -262,7 +264,7 @@ __Popen.communicate__(input=None)
**Popen.terminate()**
Stop the child. On Posix OSs the method sends SIGTERM to the child. On Windows the Win32 API function TerminateProcess() is called to stop the child.
Stop the child. On Posix OSs the method sends __SIGTERM__ to the child. On Windows the Win32 API function TerminateProcess() is called to stop the child.
**Popen.kill()**
@@ -271,7 +273,7 @@ __Popen.communicate__(input=None)
===== The following attributes are also available: =====
**Popen对象**具有下列属性:
Warning
Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.
Use communicate() rather than //.stdin.write, .stdout.read or .stderr.read// to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.
Popen.stdin #对Popen调用stdin属性将返回一个**写打开的文件对象**。
If the stdin argument was PIPE, this attribute is **a file object** that provides input to the child process. Otherwise, it is__ None__.
@@ -287,7 +289,7 @@ Popen.__pid__
Popen.__returncode__
The child return code, **set by poll() and wait()** (and indirectly by communicate()). A __None__ value indicates that the process hasnt terminated yet. A negative value -N indicates that the child was **terminated by signal N** (Unix only).
The child return code, **set by poll() and wait()** (and indirectly by communicate()). A __None__ value indicates that the process hasnt terminated yet. A negative value __-N__ indicates that the child was **terminated by signal N** (Unix only).
===== 17.1.3.1. Constants =====
@@ -314,7 +316,7 @@ subprocess.STARTF_USESHOWWINDOW
subprocess.CREATE_NEW_CONSOLE
The new process ha**s a new console**, instead of inheriting its parents console (the default).
The new process ha**s a new console**, instead of inheriting its parents console __(the default)__.
This flag is always set when Popen is created with shell=True.
subprocess.CREATE_NEW_PROCESS_GROUP
@@ -345,12 +347,20 @@ output=`dmesg | grep hda`
# becomes
p1 = Popen(["dmesg"], __stdout=PIPE__)
p2 = Popen(["grep", "hda"], stdin=__p1.stdout__, stdout=PIPE) #p1是Popen对象其stdout返回一个读打开的文件对象因为p1的stdout为PIPE
__p1.stdout__.close() # Allow p1 to receive a SIGPIPE if p2 exits.
__p1.stdout__.close() # Allow p1 to receive a SIGPIPE if p2 exits**关键!!!**
output = __p2.communicate()__[0] #communicate()返回一个__元组__这里只取出第一个元素即子进程的标准输出。
The p1.stdout.close() call after starting the p2 is __important in order__ for p1 to receive a SIGPIPE if p2 exits before p1.
具体解释如下stackoverflow.com/q/7391689
From Wikipedia, SIGPIPE is the signal sent to a process when it attempts to **write** to a pipe without a process connected to the other end.
When you first create p1 using **stdout=PIPE**, there is one process connected to the pipe, which is __your Python process__, and you can read the output using p1.stdout.
最开始Popen()时python解释器会连接到p1.stdout管道这样在p2没有创建前p1的cmd就可以执行了输出将临时地放入管道中。
When you create p2 using stdin=p1.stdout there are now __two processes__ connected to the pipe p1.stdout.
Generally when you are running processes in a pipeline you want **all processes** to end when any of the processes end. For this to happen automatically __you need to close p1.stdout so p2.stdin is the only process attached to that pipe__, this way if p2 ends and p1 writes additional data to stdout, it will receive a SIGPIPE since there are no longer any processes attached to that pipe.
Alternatively, for trusted input, the shells own pipeline support may still be used directly:
Alternatively, for **trusted input**, the shells own pipeline support may still be used directly:
output=`dmesg | grep hda` # becomes output=__check_output__(“dmesg | grep hda”,__ shell=True__)
@@ -432,7 +442,7 @@ p = Popen("cmd", shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, __stderr=STDOUT__, close_fds=True) #STDOUT标示子进程的标准出错和__它的__标准输出__重定向到同一个__文件。
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
On Unix, os.popen2, os.popen3 and os.popen4 also accept __a sequence__ as the command to execute, in which case arguments will be passed directly to the program without shell intervention. This usage can be replaced as follows:
On Unix, os.popen2, os.popen3 and os.popen4 also accept __a sequence__ as the command to execute, in which case arguments will be passed **directly to the program** without shell intervention. This usage can be replaced as follows:
(child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode,
bufsize)
@@ -444,13 +454,13 @@ Return code handling translates as follows:
pipe = os.popen("cmd", 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
rc = pipe.close() //"cmd"进程读管道时收到EOF程序一般将终止。
if rc is not None and rc **>> 8**:
print "There were some errors"
==>
process = Popen("cmd", 'w', shell=True, stdin=PIPE)
...
process.stdin.close()
process.stdin.close() //**同样使'cmd'读到EOF**,而自动终止。
if **process.wait()** != 0:
print "There were some errors"
@@ -473,19 +483,19 @@ p = Popen(["mycmd", "myarg"], bufsize=bufsize,
popen2.Popen3 and popen2.Popen4 basically work as subprocess.Popen, except that:
Popen raises an exception if the execution fails.
the capturestderr argument is replaced with the stderr argument.
stdin=PIPE and stdout=PIPE must be specified.
popen2 closes all file descriptors by default, but you have to specify close_fds=True with Popen.
* Popen raises an exception if the execution fails.
* the capturestderr argument is replaced with the stderr argument.
* stdin=PIPE and stdout=PIPE must be specified.
* popen2 closes all file descriptors by default, but you have to specify close_fds=True with Popen.
===== 17.1.5. Notes =====
17.1.5.1. Converting an argument sequence to a string on Windows
On Windows, an args sequence is converted to a string that can be parsed using the following rules (which correspond to the rules used by the MS C runtime):
Arguments are delimited by white space, which is either a space or a tab.
A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.
Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
If backslashes immediately precede a double quotation mark, every pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash escapes the next double quotation mark as described in rule 3.
* Arguments are delimited by white space, which is either a space or a tab.
* A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
* A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.
* Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
* If backslashes immediately precede a double quotation mark, every pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash escapes the next double quotation mark as described in rule 3.

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -38,7 +38,7 @@ The interpreter acts as a simple calculator: you can type an expression at it an
>>> #__ Integer division returns the floor__:
... 7/3
2
>>> 7/-3
>>> 7/-3 //对于整型出发结果也是整数而且结果总是rounded towards minus infinity。也就是说__结果总是取小于小数的最大整数值。__例如7/-3= -2.25...,而小于-2.25的最大整数为-3.
-3
The equal sign ('=') is used to assign a value to a variable. Afterwards, no result is displayed before the next interactive prompt:

View File

@@ -1,7 +0,0 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-05T15:16:40+08:00
====== library ======
Created Thursday 05 January 2012

View File

@@ -13,7 +13,7 @@ class dict(object)
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for **k, v** in iterable: #迭代器对象每次返回的元素必须是一个容器类型__容器中元素的个数为2__.**如[a,b], "ab",(a,b)**
| for **k, v** in iterable: #迭代器对象每次返回的元素必须是一个容器类型__容器中元素的个数为2__.**如[a,b], **~~"ab"~~**,(a,b)**
| d[k] = v
| dict(__**kwargs)__ -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)

View File

@@ -36,3 +36,39 @@ unpack一个顺序容器类型时左边变量的数目必须要与容器中
>>> print k,v
d f
>>>
In [9]: for k,v in 'dfdf': //对于字符串的迭代迭代其每次只返回__一个字符__所以赋值给k,v时出错
...: print k,v
...:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-9-5ba17a6181e2> in <module>()
----> 1 for k,v in 'dfdf':
2 print k,v
3
ValueError: need more than 1 value to unpack
In [10]: k,v='ff' __//对于可迭代对象展开后的元素个数必须与等式左边的相等。__
In [11]: print k,v
**f f**
In [13]: k,v='fff'
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-13-0aecd2a10b05> in <module>()
----> 1 k,v='fff'
ValueError: too many values to unpack
In [14]:
In [12]:
In [12]: for k,v in ['df',[1,2],(3,4)]: __//每次迭代器返回列表中的一个元素每个元素都可以展开为2个变量。__
print k,v
....:
d f
1 2
3 4
In [13]:

View File

@@ -0,0 +1,130 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-25T16:49:56+08:00
====== gdb debugging ======
Created Tuesday 25 December 2012
[geekard@geekard elf]$ **gdb demo**
GNU gdb (GDB) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
**(gdb) info source **//查看当前使用的source file name
**(gdb) info args **
name = 0x80486a3 "geekard"
age = 23
friends = 0xbffff920
**(gdb) info locals**
a = -1209680176
nm = 0xbffff914 "\027"
fr = {0xbffff948 "",
0xb7e5beff <printf+47> "\203\304\030[\303f\220f\220f\220f\220f\220f\220S\203\354\030\215D$,\211D$\f\213D$(讷\r",
0xb7fb5a00 <_IO_2_1_stdout_> "\204*\255", <incomplete sequence \373>, 0x80486b4 "\tThe globalVarStatic is:%d\n"}
//从上面两次的反汇编结果可以得出如下结论:
//1. break function-name 设置的断点并不位于function的入口处而break *function-name才是。
//2. break function-name设置的断点位于function的prologue指令之后auto variable初始化指令之前。
//3. 当执行到前面设置的断点时函数的args已经由caller通过stack传入但是函数的auto variable还没有被初始化
**(gdb) bt **//查看函数调用信息即backtrap。callee的编号小于其caller。
#0 greeting (name=0x80486a3 "geekard", age=23, friends=0xbffff920) at demo.c:13
#1 0x08048578 in main (argc=5, argv=0xbffff9e4) at demo.c:50
**(gdb) info f 1 **//查看stack frame编号为1的函数帧信息
Stack frame at 0xbffff950:
eip = 0x8048578 in main (demo.c:50); saved eip 0xb7e28605
caller of frame at 0xbffff910
source language c.
Arglist at 0xbffff948, args: argc=5, argv=0xbffff9e4
Locals at 0xbffff948, Previous frame's sp is 0xbffff950
Saved registers:
ebp at 0xbffff948, eip at 0xbffff94c
**(gdb) info f 0**
Stack frame at 0xbffff910:
eip = 0x804842c in greeting (demo.c:13); saved eip 0x8048578
called by frame at 0xbffff950
source language c.
Arglist at 0xbffff908, args: name=0x80486a3 "geekard", age=23, friends=0xbffff920
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
Saved registers:
eip at 0xbffff90c
**(gdb) disassemble main **//反汇编main函数
Dump of assembler code for function main:
//从info f 1的输出可知call main前esp的值为 0xbffff950。
0x080484f0 <+0>: push %ebp
0x080484f1 <+1>: mov %esp,%ebp //main函数的prologue指令break main时停止在下一条指令处。
0x080484f3 <+3>: and $0xfffffff0,%esp //SystemV i386 ABI规定esp必须word对齐。
0x080484f6 <+6>: sub $0x30,%esp //为main的auto variables预留空间此后esp的值为0xbffff10。
0x080484f9 <+9>: mov 0x8049918,%eax
0x080484fe <+14>: mov %eax,0x2c(%esp) //int autoVar = globVar;
0x08048502 <+18>: mov 0x8049924,%eax
0x08048507 <+23>: mov %eax,0x28(%esp) //i = externVar;
0x0804850b <+27>: movl $0x80486a3,0x24(%esp) // char *name = "geekard"
0x08048513 <+35>: movl $0x17,0x20(%esp) // int age = 23
0x0804851b <+43>: movl $0x8048639,0x10(%esp) //"Tom"
0x08048523 <+51>: movl $0x804863d,0x14(%esp) //"John"
0x0804852b <+59>: movl $0x8048642,0x18(%esp) //"Pi"
0x08048533 <+67>: movl $0x0,0x1c(%esp) //NULL
//char **friends = {x, x, NUU}friends是一个指向字符指针的指针__变量(占有内存单元)__其指向的数组有4个元素。
//变量friends的地址为0xbffff918即0x8($esp)处可以用print &friends命令打印出。
//变量friends的值为0xbffff920指向栈上"Tom"所在的内参单元地址。对于指针数组变量friends有以下调试信息
**(gdb) p &friends **
$21 = (char ***) 0xbffff918
**(gdb) p friends**
$17 = (char **) 0xbffff920
**(gdb) p friends@4**
$18 = {0xbffff920, 0x80485f2 <__libc_csu_init+82>, 0x8048639, 0x804863d}
**(gdb) p *friends@4**
$19 = {0x8048639 "Tom", 0x804863d "John", 0x8048642 "Pi", 0x0}
**(gdb) x /4wx friends@4**
0xbffff918: 0xbffff920 0x080485f2 0x08048639 0x0804863d
**(gdb) x /4wx *friends@4**
0xbffff920: 0x08048639 0x0804863d 0x08048642 0x00000000
**(gdb) p *friends@4**
$20 = {0x8048639 "Tom", 0x804863d "John", 0x8048642 "Pi", 0x0}
//从main函数的auto variable初始化指令可以得出如下结论
//1. main函数的auto variable是保存在stack中其layourt的顺序与定义的顺序一致即先定义的变量先入栈。
//2.static variable定义在全局数据段(.data section)中而不是stack中(int static staticVar并没有在stack中初始化)。
//3.数组的各元素入栈顺序与定义顺序相反,即索引越大越先入栈; 指针数组变量最后入栈。
//auto variable初始化完成后的main栈分配如下
{{./stack.png?height=544}}
0x0804853b <+75>: movl $0x80486ab,(%esp)
0x08048542 <+82>: call 0x8048300 <puts@plt>
0x08048547 <+87>: mov 0x804991c,%eax
0x0804854c <+92>: mov %eax,0x4(%esp)
0x08048550 <+96>: movl $0x80486b4,(%esp)
0x08048557 <+103>: call 0x80482f0 <printf@plt>
0x0804855c <+108>: lea 0x10(%esp),%eax
0x08048560 <+112>: mov %eax,0x8(%esp)
0x08048564 <+116>: mov 0x20(%esp),%eax
0x08048568 <+120>: mov %eax,0x4(%esp)
0x0804856c <+124>: mov 0x24(%esp),%eax
0x08048570 <+128>: mov %eax,(%esp)
0x08048573 <+131>: call 0x804842c <greeting>
__0x08048578__ <+136>: movl $0x3,0x4(%esp)
0x08048580 <+144>: movl $0x2,(%esp)
0x08048587 <+151>: call 0x8048590 <add>
0x0804858c <+156>: leave
0x0804858d <+157>: ret
End of assembler dump.
//greeting函数的argumets是由main函数通过栈传入的。下面代码节选至main函数的反汇编输出。
//函数的auto variable是保存在其stack中的。下面时main函数的auto variable初始化代码。
0x0804850b <+27>: movl $0x80486a3,0x24(%esp) //name
0x08048513 <+35>: movl $0x17,0x20(%esp) //age
0x0804851b <+43>: movl $0x8048639,0x10(%esp) //friends
//将greeting函数的friends参数圧入栈中注意friends参数的值是main的auto variable所以它保存在main的stack frame中。
0x0804855c <+108>: lea 0x10(%esp),%eax
0x08048560 <+112>: mov %eax,0x8(%esp) //frinnds
0x08048564 <+116>: mov 0x20(%esp),%eax
0x08048568 <+120>: mov %eax,0x4(%esp) //通过栈传入age参数
0x0804856c <+124>: mov 0x24(%esp),%eax
0x08048570 <+128>: mov %eax,(%esp) //通过栈传入name参数
0x08048573 <+131>: call 0x804842c <greeting>

View File

@@ -0,0 +1,174 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-25T22:10:21+08:00
====== gdb demo ======
Created Tuesday 25 December 2012
[geekard@geekard elf]$ **cat demo.c**
#include <stdio.h>
#include <stdlib.h>
int globalVar = 1;
int globalVarUninit;
static int globalVarStatic = 3;
extern int externVar;
extern int add(int, int);
void greeting(char *name, int age, char** friends)
{
int a = 23;
char *nm = "zhangjun";
char *fr[] = {"Tom", "John", "Pi", NULL}; //fr为__数组名称__它指向一块内存单元但是本身不咱用内存单元。
char **fr = {"Tom", "John", "Pi", NULL}; //fr为__指针变量指向一个保存有4个字符指针的内存单元(位于greeting的栈中)。__
if (name == NULL)
name = nm;
if (age == 0)
age = a;
if (friends == NULL)
friends = fr;
printf("In greeting:\n");
printf("\tHello, %s:\n", name);
printf("\tYourt age is:%d.\n", age);
printf("\tYourt friends are:\n");
while (*friends != NULL) {
printf("\t\t%s\n", *friends);
friends += 1;
}
printf("Goodbye from greeting.\n");
}
int main(int argc, char *argv[])
{
int autoVar = globalVar;
static int staticVar = 2;
int i = externVar;
char *name = "geekard";
int age = 23;
char *friends[] = {"Tom", "John", "Pi", NULL};
printf("In main:\n");
printf("\tThe globalVarStatic is:%d\n",globalVarStatic);
greeting(name, age, friends);
add(2, 3);
}
[geekard@geekard elf]$ **cat foo.c**
int externVar = 1;
int static staticVarStatic = 2;
int add(int a, int b)
{
return a + b;
}
[geekard@geekard elf]$ **gcc -g demo.c foo.c -o demo**
demo.c: In function greeting:
demo.c:18:3: warning: initialization from incompatible pointer type [enabled by default]
demo.c:18:3: warning: (near initialization for fr) [enabled by default]
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
demo.c:18:3: warning: (near initialization for fr) [enabled by default]
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
demo.c:18:3: warning: (near initialization for fr) [enabled by default]
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
demo.c:18:3: warning: (near initialization for fr) [enabled by default]
[geekard@geekard elf]$ **gdb demo**
GNU gdb (GDB) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
。。。。。。
**(gdb) info source**
Current source file is demo.c
Compilation directory is /home/geekard/Code/elf
Located in /home/geekard/Code/elf/demo.c
Contains 53 lines.
Source language is c.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
**(gdb) info sources**
Source files for which symbols have been read in:
/home/geekard/Code/elf/demo.c
Source files for which symbols will be read in on demand:
/home/geekard/Code/elf/foo.c
**(gdb) set args -a aa --bb=bbb ccc ** //设置dmo程序的默认命令行参数执行run命令时会传入该参数。
**(gdb) show args **//查看demo程序的命令行参数
Argument list to give program being debugged when it is started is "-a aa --bb=bbb ccc".
**(gdb) info args ** //查看当前stack frame对应函数的参数列表信息。
No frame selected.
(gdb) show env
XDG_VTNR=1
。。。。。
**(gdb) shell clear ** //执行shell命令这里为clear。
**(gdb) info address greeting** //在symbol table中查找greeting函数的入口地址
Symbol "greeting" is a function at address 0x804842c.
**(gdb) b 0x804842c //在某个地址处设置断点时地址前应该加星号否则gdb认为它为函数名称。**
Function "0x804842c" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
**(gdb) b *0x804842c **
Breakpoint 1 at 0x804842c: file demo.c, line 13.
**(gdb) b *greeting**
Note: breakpoint 1 also set at pc 0x804842c.
Breakpoint 2 at 0x804842c: file demo.c, line 13.
**(gdb) b greeting** //在greeting函数入口处设一个断点
Breakpoint 3 at 0x8048432: file demo.c, line 15.
**(gdb) info b**
Num Type Disp Enb Address What
1 breakpoint keep y 0x0804842c in greeting at demo.c:13
2 breakpoint keep y 0x0804842c in greeting at demo.c:13
3 breakpoint keep y 0x08048432 in greeting at demo.c:15
**(gdb) delete 2 //删除编号为2的断点**
**(gdb) list 12,16 //查看当前文件的12至16行。**
12 void greeting(char *name, int age, char** friends)
13 {
14
15 int a = 23;
16 char *nm = "zhangjun";
**(gdb) r**
Starting program: /home/geekard/Code/elf/demo -a aa --bb=bbb ccc //gdb将set args命令的参数传给demo。
Breakpoint 1, greeting (name=0x804868b "geekard", age=23, friends=0xbffff950) at demo.c:13
13 {
**(gdb) disassemble greeting** //反汇编greeting函数。如果disassmble没有参数则默认反汇编当前所执行的函数。
Dump of assembler code for function greeting:
=> 0x0804842c <+0>: push %ebp //demo停止在greeting函数的入口处函数的prologue指令还没有执行。
0x0804842d <+1>: mov %esp,%ebp
0x0804842f <+3>: sub $0x28,%esp
(gdb) c //继续执行,直到下一个断点处。
Continuing.
Breakpoint 3, greeting (name=0x804868b "geekard", age=23, friends=0xbffff950) at demo.c:15
15 int a = 23;
**(gdb) disassemble** //反汇编当前执行的函数
Dump of assembler code for function greeting:
0x0804842c <+0>: push %ebp
0x0804842d <+1>: mov %esp,%ebp
0x0804842f <+3>: sub $0x28,%esp
=> 0x08048432 <+6>: movl $0x17,-0xc(%ebp) //指令前的"=>"表示下一条**待执行**的指令位置。
//可见greeting的prologue指令已经执行这意味着greeting的栈帧已经建立。但是greeting的auto variable初始化指令还没有执行。
0x08048439 <+13>: movl $0x8048620,-0x10(%ebp)
0x08048440 <+20>: movl $0x8048629,-0x14(%ebp)
0x08048447 <+27>: cmpl $0x0,0x8(%ebp)
0x0804844b <+31>: jne 0x8048453 <greeting+39>
0x0804844d <+33>: mov -0x10(%ebp),%eax
0x08048450 <+36>: mov %eax,0x8(%ebp)
。。。。。
**(gdb) info args //查看当前stack frame对应函数的参数列表。**
name = 0x804868b "geekard"
age = 23
friends = 0xbffff950 //传经来的时指针
**(gdb) info locals** //greeting函数的auto variables还没有初始化所以下列为无效值
a = -1209680176
nm = 0xbffff944 "\027"
fr = 0x80486a4 //
(gdb)

View File

@@ -0,0 +1,82 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-25T21:45:29+08:00
====== gdb pointer ======
Created Tuesday 25 December 2012
[geekard@geekard elf]$ **cat array.c**
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ia[3] = {1,2,3};
char *cpa[3] = {"Tom", "John", NULL};
char *cpa2[] = {"Tom", "John", NULL};
char **cpa3 = {"Tom", "John", NULL};
}
[geekard@geekard elf]$ **gcc -g array.c -o array**
array.c: In function main:
array.c:9:4: warning: initialization from incompatible pointer type [enabled by default]
array.c:9:4: warning: (near initialization for cpa3) [enabled by default]
array.c:9:4: warning: excess elements in scalar initializer [enabled by default]
array.c:9:4: warning: (near initialization for cpa3) [enabled by default]
array.c:9:4: warning: excess elements in scalar initializer [enabled by default]
array.c:9:4: warning: (near initialization for cpa3) [enabled by default]
[geekard@geekard elf]$ **gdb array**
GNU gdb (GDB) 7.5.1
。。。。。
**(gdb) list main**
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 int ia[3] = {1,2,3};
7 char *cpa[3] = {"Tom", "John", NULL};
8 char *cpa2[] = {"Tom", "John", NULL}; //ia, cpa, cpa2为数组首地址的引用名称而非变量不占用
9 char **cpa3 = {"Tom", "John", NULL};
10 }
**(gdb) b 10**
Breakpoint 1 at 0x8048418: file array.c, line 10.
**(gdb) r**
Starting program: /home/geekard/Code/elf/array
warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Breakpoint 1, main () at array.c:10
10 }
**(gdb) disassemble main**
Dump of assembler code for function main:
0x080483cc <+0>: push %ebp
0x080483cd <+1>: mov %esp,%ebp
0x080483cf <+3>: sub $0x30,%esp
0x080483d2 <+6>: movl $0x1,-0x10(%ebp)
0x080483d9 <+13>: movl $0x2,-0xc(%ebp)
0x080483e0 <+20>: movl $0x3,-0x8(%ebp)
0x080483e7 <+27>: movl $0x80484b0,-0x1c(%ebp)
0x080483ee <+34>: movl $0x80484b4,-0x18(%ebp)
0x080483f5 <+41>: movl $0x0,-0x14(%ebp)
0x080483fc <+48>: movl $0x80484b0,-0x28(%ebp)
0x08048403 <+55>: movl $0x80484b4,-0x24(%ebp)
0x0804840a <+62>: movl $0x0,-0x20(%ebp)
0x08048411 <+69>: movl $0x80484b0,-0x4(%ebp)
=> 0x08048418 <+76>: leave
0x08048419 <+77>: ret
End of assembler dump.
**(gdb) bt**
#0 main () at array.c:10
**(gdb) info f 0**
Stack frame at 0xbffff980:
eip = 0x8048418 in main (array.c:10); saved eip 0xb7e28605
source language c.
Arglist at 0xbffff978, args:
Locals at 0xbffff978, Previous frame's sp is 0xbffff980
Saved registers:
ebp at 0xbffff978, eip at 0xbffff97c
**(gdb) info locals**
ia = {1, 2, 3}
cpa = {0x80484b0 "Tom", 0x80484b4 "John", 0x0}
cpa2 = {0x80484b0 "Tom", 0x80484b4 "John", 0x0}
__cpa3 = 0x80484b0__
//可见ia, cpa, cpa2为数组名称而cpa3为一指针变量其值为0x80484b0。

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

250
Zim/Utils/gdb/gdb_frame.txt Normal file
View File

@@ -0,0 +1,250 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-12-25T10:31:03+08:00
====== gdb frame ======
Created Tuesday 25 December 2012
char **friends = {"Tom", "John", "Pi", \0};
等价于 char *friends[ ] = {"Tom", "John", "Pi", \0};
等价于 char *friends[4] = {"Tom", "John", "Pi", \0};
[geekard@geekard rel]$ gdb rel2
GNU gdb (GDB) 7.5.1
**(gdb) b greeting**
Breakpoint 1 at 0x8048432: file rel2.c, line 8.
**(gdb) r**
Starting program: /home/geekard/Code/elf/rel/rel2
warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?
3
Breakpoint 1, greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
8 printf("Hello, %s:\n", name);
**(gdb) disassemble**
Dump of assembler code for function greeting:
0x0804842c <+0>: push %ebp
0x0804842d <+1>: mov %esp,%ebp
0x0804842f <+3>: sub $0x18,%esp
上面这三条指令称为prologue由gcc自动添加。break fuction会在执行完function的prologue后停止这样
=> 0x08048432 <+6>: mov 0x8(%ebp),%eax
0x08048435 <+9>: mov %eax,0x4(%esp)
0x08048439 <+13>: movl $0x8048590,(%esp)
0x08048440 <+20>: call 0x80482f0 <printf@plt>
**(gdb) si //多次执行si直到输出如下字符串**
0x080482f0 in printf@plt ()
**(gdb) bt**
#0 0x080482f0 in printf@plt ()
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
#2 0x080484fd in main () at [[rel2.c:28]]
**(gdb) info frame 2**
Stack frame at 0xbffff970:
eip = 0x80484fd in main (rel2.c:28); saved eip 0xb7e28605
caller of frame at 0xbffff930
source language c.
Arglist at 0xbffff968, args:
Locals at 0xbffff968, Previous frame's sp is 0xbffff970
Saved registers:
ebp at 0xbffff968, eip at 0xbffff96c
**(gdb) info frame 1**
Stack frame at 0xbffff930:
eip = 0x8048445 in greeting (rel2.c:8); saved eip 0x80484fd
called by frame at 0xbffff970, caller of frame at 0xbffff910
source language c.
Arglist at 0xbffff928, args: name=0x80485c9 "geekard", age=23, friends=0xbffff944
Locals at 0xbffff928, Previous frame's sp is 0xbffff930
Saved registers:
ebp at 0xbffff928, eip at 0xbffff92c
**(gdb) info frame 0**
Stack frame at 0xbffff910:
eip = 0x80482f0 in printf@plt; saved eip 0x8048445
called by frame at 0xbffff930
Arglist at 0xbffff908, args:
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
Saved registers: //没有保存ebp, esi, edi, ebx寄存器的值。
eip at 0xbffff90c
**(gdb) disassemble main**
Dump of assembler code for function main:
0x0804848a <+0>: push %ebp
0x0804848b <+1>: mov %esp,%ebp
0x0804848d <+3>: and $0xfffffff0,%esp
0x08048490 <+6>: sub $0x30,%esp
0x08048493 <+9>: mov 0x8049804,%eax
0x08048498 <+14>: mov %eax,0x2c(%esp)
0x0804849c <+18>: movl $0x80485c9,0x28(%esp)
0x080484a4 <+26>: movl $0x17,0x24(%esp)
0x080484ac <+34>: movl $0x80485d1,0x14(%esp)
0x080484b4 <+42>: movl $0x80485d5,0x18(%esp)
0x080484bc <+50>: movl $0x80485da,0x1c(%esp)
0x080484c4 <+58>: movl $0x0,0x20(%esp)
0x080484cc <+66>: mov 0x8049808,%eax
0x080484d1 <+71>: mov %eax,0x4(%esp)
0x080484d5 <+75>: movl $0x80485dd,(%esp)
0x080484dc <+82>: call 0x80482f0 <printf@plt>
0x080484e1 <+87>: lea 0x14(%esp),%eax
0x080484e5 <+91>: mov %eax,0x8(%esp)
0x080484e9 <+95>: mov 0x24(%esp),%eax
0x080484ed <+99>: mov %eax,0x4(%esp)
0x080484f1 <+103>: mov 0x28(%esp),%eax
0x080484f5 <+107>: mov %eax,(%esp)
0x080484f8 <+110>: call __0x804842c__ <greeting>
__0x080484fd__ <+115>: leave
0x080484fe <+116>: ret
End of assembler dump.
**(gdb) disassemble greeting**
Dump of assembler code for function greeting:
0x0804842c <+0>: push %ebp
0x0804842d <+1>: mov %esp,%ebp
0x0804842f <+3>: sub $0x18,%esp
0x08048432 <+6>: mov 0x8(%ebp),%eax
0x08048435 <+9>: mov %eax,0x4(%esp)
0x08048439 <+13>: movl $0x8048590,(%esp)
0x08048440 <+20>: call __0x80482f0__ <printf@plt>
__0x08048445__ <+25>: mov 0xc(%ebp),%eax
0x08048448 <+28>: mov %eax,0x4(%esp)
0x0804844c <+32>: movl $0x804859c,(%esp)
0x08048453 <+39>: call 0x80482f0 <printf@plt>
0x08048458 <+44>: movl $0x80485af,(%esp)
0x0804845f <+51>: call 0x8048300 <puts@plt>
0x08048464 <+56>: jmp 0x804847f <greeting+83>
0x08048466 <+58>: mov 0x10(%ebp),%eax
0x08048469 <+61>: mov (%eax),%eax
0x0804846b <+63>: mov %eax,0x4(%esp)
0x0804846f <+67>: movl $0x80485c3,(%esp)
0x08048476 <+74>: call 0x80482f0 <printf@plt>
0x0804847b <+79>: addl $0x4,0x10(%ebp)
0x0804847f <+83>: mov 0x10(%ebp),%eax
0x08048482 <+86>: mov (%eax),%eax
0x08048484 <+88>: test %eax,%eax
0x08048486 <+90>: jne 0x8048466 <greeting+58>
0x08048488 <+92>: leave
0x08048489 <+93>: ret
End of assembler dump.
**(gdb) x /8wx 0x80482f0**
0x80482f0 <printf@plt>: 0x97ec25ff 0x00680804 0xe9000000 0xffffffe0
0x8048300 <puts@plt>: 0x97f025ff 0x08680804 0xe9000000 0xffffffd0
**(gdb) x /8wi 0x80482f0**
__0x80482f0__ <printf@plt>: jmp *__0x80497ec__
0x80482f6 <printf@plt+6>: push $0x0
0x80482fb <printf@plt+11>: jmp 0x80482e0
0x8048300 <puts@plt>: jmp *0x80497f0
0x8048306 <puts@plt+6>: push $0x8
0x804830b <puts@plt+11>: jmp 0x80482e0
0x8048310 <__gmon_start__@plt>: jmp *0x80497f4
0x8048316 <__gmon_start__@plt+6>: push $0x10
**(gdb) x /wx 0x80497ec**
0x80497ec <printf@got.plt>: 0xb7e5bed0
**(gdb) si**
0xb7e5bed0 in printf () from [[/usr/lib/libc.so.6]]
**(gdb) disassemble *0x80497ec**
Dump of assembler code for function __printf__:
=> __0xb7e5bed0__ <+0>: push %ebx
0xb7e5bed1 <+1>: sub $0x18,%esp
0xb7e5bed4 <+4>: call 0xb7f376d3 <__x86.get_pc_thunk.bx>
0xb7e5bed9 <+9>: add $0x159127,%ebx
0xb7e5bedf <+15>: lea 0x24(%esp),%eax
0xb7e5bee3 <+19>: mov %eax,0x8(%esp)
0xb7e5bee7 <+23>: mov 0x20(%esp),%eax
0xb7e5beeb <+27>: mov %eax,0x4(%esp)
0xb7e5beef <+31>: mov -0x68(%ebx),%eax
0xb7e5bef5 <+37>: mov (%eax),%eax
0xb7e5bef7 <+39>: mov %eax,(%esp)
0xb7e5befa <+42>: call 0xb7e520f0 <vfprintf>
0xb7e5beff <+47>: add $0x18,%esp
0xb7e5bf02 <+50>: pop %ebx
0xb7e5bf03 <+51>: ret
End of assembler dump.
**(gdb) bt**
#0 0xb7e5bed0 in printf () from /usr/lib/libc.so.6
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
#2 0x080484fd in main () at rel2.c:28
**(gdb) info f 0**
Stack frame at 0xbffff910:
eip = 0xb7e5bed0 in printf; saved eip 0x8048445
called by frame at 0xbffff930
Arglist at 0xbffff908, args:
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
Saved registers:
eip at 0xbffff90c
没有保存ebp, esi, edi, ebx等寄存器的值所以它们的值与frame 1中的相等。在编译时如果指定-fomit-frame-pointer选项
编译器为函数调用生成栈帧时不会圧入ebp寄存器的值而且对arguments和auto variables的引用是通过esp进行的。这样可以将
ebp寄存器节省出来用作其它用途。但缺点是无法对函数调用进行frame backtrace如果目标文件中有.eh_frame section则gdb可以
从中提取出frame backtrace信息
**(gdb) info registers**
eax 0x80485c9 134514121
ecx 0x0 0
edx 0x0 0
ebx 0xb7fb5000 -1208266752 //继续保存的是frame 1中的值
esp 0xbffff90c 0xbffff90c
ebp 0xbffff928 0xbffff928 //继续保存的是frame 1中的值
esi 0x0 0
edi 0x0 0
eip 0xb7e5bed0 0xb7e5bed0 <printf>
eflags 0x200282 [ SF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
**(gdb) f 1 //切换frame到#1, 这样可以查看greeting函数的参数和自动变量值。**
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
8 printf("Hello, %s:\n", name);
**(gdb) info registers** //打印frame 1的寄存器
eax 0x80485c9 134514121
ecx 0x0 0
edx 0x0 0
ebx **0xb7fb5000** -1208266752
esp 0xbffff910 0xbffff910
ebp **0xbffff928** 0xbffff928
esi 0x0 0
edi 0x0 0
eip 0x8048445 0x8048445 <greeting+25>
eflags 0x200282 [ SF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
(gdb)
**(gdb) info args**
name = 0x80485c9 "geekard"
age = 23
friends = 0xbffff944
**(gdb) ptype friends**
type = char **
**(gdb) p friends**
$1 = (char **) 0xbffff944
**(gdb) p *friends**
$6 = 0x80485d1 "Tom"
**(gdb) p friends+1**
$2 = (char **) 0xbffff948
**(gdb) x /4wx friends**
0xbffff944: 0x080485d1 0x080485d5 0x080485da 0x00000000
**(gdb) p *friends@4**
$4 = {0x80485d1 "Tom", 0x80485d5 "John", 0x80485da "Pi", 0x0}
**(gdb) p &friends**
$5 = (char ***) 0xbffff938
(**gdb) x /4wx friends+1**
0xbffff948: 0x080485d5 0x080485da 0x00000000 0x00000017
**(gdb) x /4wx &friends**
0xbffff938: 0xbffff944 0x08048552 0x00000001 0x080485d1
**(gdb) p friends@4**
$3 = {0xbffff944, 0x8048552 <__libc_csu_init+82>, 0x1, 0x80485d1}
**(gdb) x /wx friends**
0xbffff944: 0x080485d1
**(gdb) x /wx friends+1**
0xbffff948: 0x080485d5
**(gdb) x /wx &friends**
0xbffff938: 0xbffff944
**(gdb) x /wx *friends**
0x80485d1: 0x006d6f54

View File

@@ -49,7 +49,7 @@ TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | can | __bridge__ }
link/ether c8:60:00:8a:db:e7 brd ff:ff:ff:ff:ff:ff
[geekard@kb310 man]$ __sudo ip link add link eth0 name demo-bridge type bridge; ip link show__
**#命令行中的link eth0其实不用加。**
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 576 qdisc pfifo_fast state __UP__ mode DEFAULT qlen 1000
@@ -148,6 +148,11 @@ rtt min/avg/max/mdev = 0.385/0.546/0.959/0.239 ms
Password:
RTNETLINK answers: No such file or directory
[geekard@kb310 ~]$ __sudo ip route add default via 192.168.1.1 dev demo-bridge__
注意添加路由的格式为ip route add PREFIX via ADDRESS dev DEV
其中PREFIX表示目标网络如果为缺省路由则因为default。
via ADDRESS是可选的表示到到PREFIX目标网络需要经过ADDRESS表示的路由器__ADDRESS不用前缀形式__。
[geekard@geekard rel]$ sudo ip route add default via 192.168.1.1/24 dev demo
Error: an inet address is expected rather than "192.168.1.1/24".
[geekard@kb310 ~]$ __ip route show table all__
**default via 192.168.1.1 dev demo-bridge **
**default via 192.168.1.1 dev eth0 metric 202**

2628
Zim/Utils/systemd.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-20T20:10:35+08:00
====== Booting up-Tools and tips for systemd a Linux init tool ======
Created Tuesday 20 November 2012
http://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html
15 May 2012, 10:00
Booting up: Tools and tips for systemd, a Linux init tool
by Lennart Poettering, Kay Sievers, Thorsten Leemhuis
These days, Fedora, openSUSE, Mandriva and a few other distributions use the **systemd init tool** for system starts. It includes its own tools for configuration and diagnosis, and the tricks it needs when the system doesn't start are different from sysvinit's.
The following article about systemd was first published in the German magazine c't 13/11 and has been updated in various places before appearing in The H Open. An article from the same issue of c't on systemd's ideas, approach and functionality was also recently published on The H Open.
The systemd init tool, just over two years old, is already the default in some distributions; a few more include it as an alternative to **upstart** and the outdated **sysvinit**. Thanks to __compatibility features__, some of the commands and tricks familiar from distributions with sysvinit and upstart work with systemd too. To really take advantage of the much newer init system's capabilities, however, administrators should get to know systemd's tools and parameters as well.
The main tool for interacting with systemd is **systemctl**, a command-line program. The tool requires root privileges to make changes to the configuration or to restart background services, but even non-root users can use some diagnostic requests. If you launch the program without any parameters, you will see a list of the "units" that execute tasks when the system is started, including mounting and checking disks, starting background services and configuring hardware.
For a standard Fedora 15 installation, systemctl lists around 160 active units, divided into ten types. __Service units__ are one of the most important types of units as they take care of background services, which a sysvinit distribution typically starts using init scripts. __Mount and automount units__ mount filesystems. __Socket units__ create sockets and, as soon as a socket is accessed, indirectly start another unit using dependencies. You can use a parameter to tell systemctl to only list certain types of unit, for example all service units:
**systemctl --type=service**
Systemctl automatically forwards its task to less; you can use the arrow keys to scroll not just up and down but also to the right, since more information is occasionally "hidden" there.
To boot a system, systemd uses units, which are divided into types that systemctl can list separately. The first column in the list tells you the name of the unit; the second column, whether systemd was able to **load the unit definition**. The third column says whether the unit is active. If you include the -a parameter, the program only displays **inactive units** that is, units that are installed but not used during boot-up; the same applies to unit files that the init system wasn't able to load, most likely because of an error in the unit file.
The fourth column gives the current status: "exited" means that the process **completed without any errors**. This is the case for, say, services that don't continue in the background after they've been launched for example, the service unit that, for compatibility reasons, executes the /etc/rc.d/rc.local file, familiar from sysvinit, at system start. "Running" is for services that are running in the background, such as cron, dbus, sshd and udev.
The sixth column describes the unit. Units labelled "LSB" or "SYSV" have been automatically created by systemd to take care of traditional init scripts.
Services that could not be started or that crashed later are marked as "failed" in the fifth column, in red, if the console can display colours. You can find out when the crash happened and which error code the program provided when it ended using commands such as:
systemctl status ntpd.service
Systemctl's status command provides a time and error code for crashed services Zoom For a newly installed Fedora 15, systemctl lists about 60 service units, including the login processes for the text consoles (agetty), since unlike sysvinit systemd uses service units to manage these like a normal background service.
Next: Unit files and targets
===== Working with units =====
The system configuration files for creating units are in **/lib/systemd/system/**, but a file with the same name in **/etc/systemd/system** will take priority.
Unit definitions are usually much shorter than the classic sysvinit scripts. For example, a unit file for the service for synchronising network time via NTP is just a few lines long:
[Unit]
Description=Network Time Service
[Service]
ExecStart=/usr/bin/ntpd -n -u ntp:ntp -g
[Install]
WantedBy=multi-user.target
All unit files include a section, starting with __[Unit]__, with general settings and a short description. The __[Service]__ section has service-specific tasks for NTP, just the command-line to launch the service. If a specific command is required to end the program, you can set it using **ExecStop=**. This step is unnecessary for the NTP daemon, since, following Unix tradition, it can be ended with a simple "SIGTERM" signal, which tells systemd to end if no other command has been specified.
The **[Install]** section contains instructions for systemd to interpret during (de-)installation; the entry in the NTP example means that the time should be synchronised when the "Multi-User" target is activated.
===== Targets =====
**The concept of "targets" units is similar to that of sysvinit's runlevels;** indeed, for compatibility, systemd even understands runlevel names for equivalent targets. In Fedora 15, you can therefore enter the familiar single as a parameter in the kernel's boot-loader; systemd then activates **rescue.target**, which provides a minimal interface comparable to single-user mode.
Along the same lines, 3 can be used to activate a multi-user mode that is, to fully start the system without using the graphical login interface. In systemd, this mode is represented by the **multi-user.target uni**t, which can be set as the standard with this link:
ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
If, at a later point, you do want the graphical login interface to be a standard part of boot-up, you can set **graphical.target** as the standard target in the same way; this is the equivalent of runlevel 5 in older versions of Fedora and openSUSE. As an alternative to the old runlevels, you can also give the kernel the names of the target units to be started:
__systemd.unit=multi-user.target__
**To activate a different target unit during operation**, you can use systemctl's isolate command, which requires root privileges:
systemctl isolate rescue.target
The change to the rescue target is interesting for administration tasks, since systemd now ends all user logins and background services so that only system services run, such as the one monitoring logical volumes (lvm2-monitor). Sometimes, even these services need to be ended for rebuilds; you can then use **emergency.target** to go to emergency mode, where only the process for the input prompt runs, along with the kernel threads.
===== Wants and needs =====
Systemctl's show command delivers some internal information on running units and the tasks they execute, as well as information about which units systemd calls on to enable the multi-user target:
**systemctl show -p Wants multi-user.target**
Other targets can also be in the output, such as **basic.target** in multi-user.target. In turn, the former depends on **sysinit.target**, which requires **local-fs.target**. These three targets take care of the system's basic configuration, including mounting filesystems and starting udev. To specify dependency on the basic target, the unit configuration file multi-user.target contains the following statements:
Requires=basic.target
After=basic.target
With After in addition to Requires, systemd knows that it must __not only enable the target but also wait for that target__ to completely start.
__Wants is a weaker alternative to Requires__. Systemd enables these units as well, but continues starting the system even if one of them doesn't start. This kind of dependency can also be specified with links to unit files in directories consisting of the unit file's path and name and a .wants in order to determine which units are retrieved when a target is accessed.__(也就是说这种依赖关系可以通过在unit name +.wants目录中建立被依赖unit的link方式创建。)__ You can use ls or systemctl's show command:
ls /*/systemd/system/multi-user.target.wants/
systemctl show -p Wants multi-user.target
===== Shutting down =====
If you want to deactivate the NTPD service unit so the system time is not synchronised via NTP upon boot-up, you can use the following style of command:
systemctl disable ntpd.service
Here, systemctl is simply removing the link to the service unit file **in the Wants directories**; it creates a link when a service is activated with **enable**. Both steps can also be done manually in order to (de)activate units without using systemctl.
__也就是说systemctl disable ntpd.service会将该unit file 的链接从/etc/systemd/system/multi-user.targets.wants目录中删除。__
__systemctl enable ntpd.service会将该unit file的链接建立在上面的目录中。__
If a service is started by a traditional init script rather than a unit, __systemctl forwards the activation request to the chkconfig program__. With Fedora 15, for example, this can occur when you install Apache and activate it using systemctl. In turn, chkconfig can also delegate tasks to systemctl in Fedora 15 but only some, so you're better off not using it at all or only with caution.
The (de)activation of a service takes effect the next time it is started or when the system is shut down; the following command starts a service immediately:
systemctl start ntpd.service
For sysvinit distributions, the equivalent to this command is **service ntpd start**. A systemctl command with the **stop** parameter instead of start ends the service. With the **status** command, systemctl delivers information about the unit, including its current status and the name of the file that specifies it. The program also says whether the service is currently running and, if so, for how long it has been running as well as which processes belong to it, with the main process explicitly displayed.
Group affiliation can be used to determine which service a process belongs to. It is quite easy to find out which service started which processes by looking at the control groups created by systemd. The command __systemd-cgls__ displays the cgroup hierarchy created by systemd; alternatively, ps shows group affiliation:
ps xaw -eo pid,args,cgroup
Next: Fixing problems
===== Stopped at the starting line =====
If there are problems during boot-up that systemd seems to be directly or indirectly involved in, start the kernel with the following parameters:
**systemd.log_target=kmsg systemd.log_level=debug**
Systemd recognises the parameters and provides extensive troubleshooting information on the console. At the same time, the information is saved for later analysis in the kernel notification buffer created by dmesg.
The "systemd-cgls" tool can display the control groups and the processes belonging to them.
The command line programs __poweroff, halt and reboot are part of systemd,__ but the system can also be shut down or restarted using systemctl commands, which are the same. The system can also be restarted this way:
systemctl kexec
After all services have been stopped, systemd tells the running kernel to directly start a previously configured Linux kernel, which allows for fast restarts, since it bypasses BIOS and boot-loader. If no kexec kernel is configured, systemd executes a normal restart.
===== Deep down =====
For standard administration tasks, you will usually only come into contact with **service and target units**; the others are primarily important for deeper systemd functions or, during boot-up, take care of everything that __distribution-specific scripts__ took care of in sysvinit and upstart distributions. These tasks include mounting the filesystems specified in /etc/fstab, activating the swap space and occasionally cleaning up directories for temporary files.
For some of these tasks, systemd has an **automount** function that can create pseudo mount points for filesystems configured in /etc/fstab; they are not really mounted until they are first accessed. Adding **comment=systemd.automount** in /etc/fstab changes any mount point into an automount point, which can speed up the boot-up process and be interesting for access to network shares, since the WLAN connection is not created until the user uses NetworkManager.
===== Looking for answers =====
Systemctl can be used to tell systemd to **send a signal without knowing the service's process ID**. For example, the following command puts rsyslogd in debug mode, which is ended when you enter the command a second time.
**systemctl kill** --signal=USR1 rsyslogd.service
If you don't specify which signal to send, systemctl sends a normal term signal, which ends all processes belonging to a service.
Systemd includes a program that __visualises the boot processes__; the dark red areas signal services' start phases .The command systemd-analyze tells you how long the system took to boot and how much of that time was due to the kernel, initramfs and the systemd-controlled configuring of the userland. If you want to look more closely into the latter factor, use **systemd-analyze blame** to get individual units' start times. For more detailed information on the boot process, the program can create an SVG file that visualises the units' starts:
__systemd-analyze plot > plot.svg__
Sometimes, this can be used to track down units that excessively prolong boot-up. The seventh part of the "Systemd for Administrators" blog series has a few tips on correctly interpreting these results. The series, with twelve sections at the moment, also includes many other tips and notes on using systemd:
* Verifying Bootup
* Which Service Owns Which Processes?
* How Do I Convert A SysV Init Script Into A systemd Service File?
* Killing Services
* The Three Levels of "Off"
* Changing Roots
* The Blame Game
* The New Configuration Files
* On /etc/sysconfig and /etc/default
* Instantiated Services
* Converting inetd Services
* Securing Your Services
Lennart Poettering's homepage also has many other articles with more background information on the init system. In addition, Poettering recently listed some of the changes made to systemd in the last year and a half in his third "Systemd Status Update".

View File

@@ -0,0 +1,273 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-21T19:33:39+08:00
====== systemd for Administrators, Part 1 ======
Created Wednesday 21 November 2012
http://www.0pointer.de/blog/projects/systemd-for-admins-1.html
レナート Wunschkonzert, Ponyhof und Abenteuerspielplatz ﻟﻴﻨﺎﺭﺕ
Mon, 23 Aug 2010
systemd for Administrators, Part 1
As many of you know, systemd is the new Fedora init system, starting with F14, and it is also on its way to being adopted in a number of other distributions as well (for example, OpenSUSE). For administrators systemd provides a variety of new features and changes and enhances the administrative process substantially. This blog story is the first part of a series of articles I plan to post roughly every week for the next months. In every post I will try to explain one new feature of systemd. Many of these features are small and simple, so these stories should be interesting to a broader audience. However, from time to time we'll dive a little bit deeper into the great new features systemd provides you with.
===== Verifying Bootup =====
Traditionally, when booting up a Linux system, you see a lot of little messages passing by on your screen. As we work on speeding up and parallelizing the boot process these messages are becoming visible for a shorter and shorter time only and be less and less readable -- if they are shown at all, given we use __graphical boot splash__ technology like **Plymouth** these days. Nonetheless the information of the boot screens was and still is very relevant, because it shows you for each service that is being started as part of bootup, wether it managed to start up successfully or failed (with those green or red [ OK ] or [ FAILED ] indicators). To improve the situation for machines that boot up fast and parallelized and to make this information more nicely available during runtime, we added a feature to systemd that tracks and remembers for each service whether it started up successfully, whether it exited with a non-zero exit code, whether it timed out, or whether it terminated abnormally (by segfaulting or similar), both during start-up and runtime. By simply typing systemctl in your shell you can query the state of all services, both **systemd native and SysV/LSB services**:
[root@lambda] ~# systemctl
UNIT LOAD ACTIVE SUB JOB DESCRIPTION
dev-hugepages.automount loaded active running Huge Pages File System Automount Point
dev-mqueue.automount loaded active running POSIX Message Queue File System Automount Point
proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point
sys-kernel-debug.automount loaded active waiting Debug File System Automount Point
sys-kernel-security.automount loaded active waiting Security File System Automount Point
sys-devices-pc...0000:02:00.0-net-eth0.device loaded active plugged 82573L Gigabit Ethernet Controller
[...]
sys-devices-virtual-tty-tty9.device loaded active plugged /sys/devices/virtual/tty/tty9
-.mount loaded active mounted /
boot.mount loaded active mounted /boot
dev-hugepages.mount loaded active mounted Huge Pages File System
dev-mqueue.mount loaded active mounted POSIX Message Queue File System
home.mount loaded active mounted /home
proc-sys-fs-binfmt_misc.mount loaded active mounted Arbitrary Executable File Formats File System
abrtd.service loaded active running ABRT Automated Bug Reporting Tool
accounts-daemon.service loaded active running Accounts Service
acpid.service loaded active running ACPI Event Daemon
atd.service loaded active running Execution Queue Daemon
auditd.service loaded active running Security Auditing Service
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
bluetooth.service loaded active running Bluetooth Manager
console-kit-daemon.service loaded active running Console Manager
cpuspeed.service loaded active exited LSB: processor frequency scaling support
crond.service loaded active running Command Scheduler
cups.service loaded active running CUPS Printing Service
dbus.service loaded active running D-Bus System Message Bus
getty@tty2.service loaded active running Getty on tty2
getty@tty3.service loaded active running Getty on tty3
getty@tty4.service loaded active running Getty on tty4
getty@tty5.service loaded active running Getty on tty5
getty@tty6.service loaded active running Getty on tty6
haldaemon.service loaded active running Hardware Manager
hdapsd@sda.service loaded active running sda shock protection daemon
irqbalance.service loaded active running LSB: start and stop irqbalance daemon
iscsi.service loaded active exited LSB: Starts and stops login and scanning of iSCSI devices.
iscsid.service loaded active exited LSB: Starts and stops login iSCSI daemon.
livesys-late.service loaded active exited LSB: Late init script for live image.
livesys.service loaded active exited LSB: Init script for live image.
lvm2-monitor.service loaded active exited LSB: Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
mdmonitor.service loaded active running LSB: Start and stop the MD software RAID monitor
modem-manager.service loaded active running Modem Manager
netfs.service loaded active exited LSB: Mount and unmount network filesystems.
NetworkManager.service loaded active running Network Manager
ntpd.service loaded maintenance maintenance Network Time Service
polkitd.service loaded active running Policy Manager
prefdm.service loaded active running Display Manager
rc-local.service loaded active exited /etc/rc.local Compatibility
rpcbind.service loaded active running RPC Portmapper Service
rsyslog.service loaded active running System Logging Service
rtkit-daemon.service loaded active running RealtimeKit Scheduling Policy Service
sendmail.service loaded active running LSB: start and stop sendmail
sshd@172.31.0.53:22-172.31.0.4:36368.service loaded active running SSH Per-Connection Server
sysinit.service loaded active running System Initialization
systemd-logger.service loaded active running systemd Logging Daemon
udev-post.service loaded active exited LSB: Moves the generated persistent udev rules to /etc/udev/rules.d
udisks.service loaded active running Disk Manager
upowerd.service loaded active running Power Manager
wpa_supplicant.service loaded active running Wi-Fi Security Service
avahi-daemon.socket loaded active listening Avahi mDNS/DNS-SD Stack Activation Socket
cups.socket loaded active listening CUPS Printing Service Sockets
dbus.socket loaded active running dbus.socket
rpcbind.socket loaded active listening RPC Portmapper Socket
sshd.socket loaded active listening sshd.socket
systemd-initctl.socket loaded active listening systemd /dev/initctl Compatibility Socket
systemd-logger.socket loaded active running systemd Logging Socket
systemd-shutdownd.socket loaded active listening systemd Delayed Shutdown Socket
dev-disk-by\x1...x1db22a\x1d870f1adf2732.swap loaded active active /dev/disk/by-uuid/fd626ef7-34a4-4958-b22a-870f1adf2732
basic.target loaded active active Basic System
bluetooth.target loaded active active Bluetooth
dbus.target loaded active active D-Bus
getty.target loaded active active Login Prompts
graphical.target loaded active active Graphical Interface
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User
network.target loaded active active Network
remote-fs.target loaded active active Remote File Systems
sockets.target loaded active active Sockets
swap.target loaded active active Swap
sysinit.target loaded active active System Initialization
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
JOB = Pending job for the unit.
221 units listed. Pass --all to see inactive units, too.
[root@lambda] ~#
(I have shortened the output above a little, and removed a few lines not relevant for this blog post.)
Look at the **ACTIVE** column, which shows you the high-level state of a service (or in fact of any kind of unit systemd maintains, which can be more than just services, but we'll have a look on this in a later blog posting), whether it is active (i.e. running), inactive (i.e. not running) or in any other state. If you look closely you'll see one item in the list that is marked maintenance and highlighted in red. This informs you about a service that failed to run or otherwise encountered a problem. In this case this is ntpd. Now, let's find out what actually happened to ntpd, with the systemctl status command:
[root@lambda] ~# **systemctl status ntpd**__.service__
ntpd.service - Network Time Service
Loaded: loaded (/etc/systemd/system/ntpd.service)
**Active: maintenance**
Main: 953 (code=exited, status=255)
CGroup: name=systemd:/systemd-1/ntpd.service
[root@lambda] ~#
This shows us that NTP terminated during runtime (when it ran as **PID 953**), and tells us exactly the error condition: the process exited with an exit status of 255.
In a later systemd version, we plan to hook this up to ABRT, as soon as this enhancement request is fixed. Then, if systemctl status shows you information about a service that crashed it will direct you right-away to the appropriate crash dump in ABRT.
Summary: use systemctl and systemctl status as modern, more complete replacements for the traditional boot-up status messages of SysV services. systemctl status not only captures in more detail the error condition but also shows runtime errors in addition to start-up errors.
That's it for this week, make sure to come back next week, for the next posting about systemd for administrators!
posted at: 10:22 | path: /projects | permanent link to this entry | 40 comments
Posted by bochecha at Mon Aug 23 11:20:20 2010
Thanks, this serie of article will no doubt be very interesting. :)
About this one, I don't really get the **LOAD, ACTIVE and SUB** columns.
As I understood it, the first one indicates whether a unit **configuration** was loaded or not into systemd. But if it wasn't loaded, then it would not appear in the output of systemctl, right?
You say that ACTIVE is a high-level generalization of SUB. In this case, why is that necessary? Isn't SUB already enough information?
Maybe if you could give the list of the possible values for each columns then that would help me understand the differences. :)
Or maybe just point to the appropriate documentation if that is all already documented somewhere, I must admit I haven't had the time yet to look at Systemd as closely as I wanted.
Posted by Lennart at Mon Aug 23 11:35:34 2010
bochecha: well, there are many reasons why a service might **show up as failed** to load in the systemctl output: for example, it was referenced as required dependency of another service, but we couldn't find neither a native service definition file nor a SysV init script for it. Or, there was a parsing failure while reading it. Or, because the file was incomplete. And that might even happen while a service is active, for example, because the user requested **a configuration file reload** from systemd after changing a service file, and a service that is already running suddenly has an invalid configuration file. That effectively means that the LOAD and the ACTIVE state are mostly orthogonal(正交、互相垂直): you may have a running service where configuration loaded fine, you may have a stopped service where it loaded fine, but you may also have a running service where configuration failed to load.
**LOAD和ACTIVE具有不同的功能LOAD表明该service的configure file是否正常读取而ACTIVE表明该serive是否在运行。一般来说LOAD失败时service也是failed但是有可能正常运行的service在reload configration file时出错。**
And yes, ACTIVE and SUB show you the same information, though ACTIVE in a more generalized form. While SUB has states that are __specific to each unit type__ (e.g. **"running", "exited", "dead" for services; "plugged" and "dead" for devices; or "mounted" and "dead" for mount points**), ACTIVE exposes the same high-level states for all units.
ACTIVE较SUB表示的是一个更一般、抽象的状态而SUB与具体的unit类型相关表达的是更具体的信息。例如ACTIVE的状态是active但是SUB的内容可能是running或plugged或exited。
We only distuingish __6 ACTIVE states__ (to list them: **active, reloading, inactive, maintenance, activating, deactivating**), which are mapped from the lower-level states, which might be many more. For example __services have 15 low-level states__: **dead, start-pre, start, start-post, running, exited, reload, stop, stop-sigterm, stop-sigkill, stop-post, final-sigterm, final-sigkill, maintenance, auto-restart.**
Posted by John Drinkwater at Mon Aug 23 12:23:36 2010
Why systemctl status ntpd.service and not systemctl status ntpd?
Why does systemctl display names like getty@tty2.service and not as getty@tty2 ?
Do we really need to have .mount, .service, etc on all our config files now?
IMO, horrible to have file extensions, equally to have them as long as the file name.
Posted by Lennart at Mon Aug 23 13:36:52 2010
John, we support **different kinds of units**. We manage __sockets, mount points, services, devices, automount points, timers, paths, targets, swap files/devices and snapshots__ with the same tools, with the same commands. For example "dbus.service" and "dbus.socket" are both used by the D-Bus system, but can be controlled and introspected __independently__. To distuingish them, we hence write their full name everywhere, so that you explicitly state that you mean the D-Bus socket instead of the D-Bus service, or vice versa.
Also, I actually find this one of the pretty things in this design: the unit names are actually __identical__ to the file names they are configured in.
Posted by Shane Falco at Mon Aug 23 14:19:27 2010
I'm with Mr. Drinkwater on this. Extensions (especially long extensions) are one symptom of a bad design. All this feels very rushed and hacked together.
It looks like this core systemctl function won't display cleanly in a standard 80 character wide terminal? Are we trying to change linux so much that we no longer care about those sorts of things? It may be different for gnome developers, but unix admins I know have lots of windows open and usually they're 80 characters wide.
Finally, why choose a name so close to another common utility? systemctl? Seriously? When another core system utility called sysctl already exists?
Posted by Lennart at Mon Aug 23 14:26:44 2010
Shane, I am sorry but I guess we just have to agree to disagree to this. The points you raise are in the category "matter of taste" or even "bike shedding", and so I guess we should leave it as that.
systemctl shortens the output dependening the terminal size. If you use a tiny terminal, the description string might even be suppressed entirely. The bigger your terminal/screen is, the more output we can stick on it. That should not surprise anybody. Or to put it in other words: we support 80ch terminals just fine, but if you use bigger termiansl we'll make use of it.
Posted by Shane Falco at Mon Aug 23 14:49:26 2010
Sounds reasonable and I appreciate the response. It looks like you are taking your own personal experience (which is all anyone can ask) and creating something that you think is appropriate. But I fear that you don't really see the bigger picture of unix admins out there...there are a lot of guys I work with who are junior/middle guys who just work for a paycheck. They're __not linux geeks__. I dare say they're the majority. They could be doing AIX or Solaris or linux for all they care. I think they're going to have trouble with systemd. It just does too much and it's too baroque. Too confusing.
I finally, finally got them going with services/chkconfig and now this...
Posted by Michael at Mon Aug 23 15:00:08 2010
Just a quick question, can the description be translated ?
I assume that this is not planned, as they are config file, not software, but as we are able to translate .desktop, it would be great to have some way of doing it cleanly.
Posted by Lennart at Mon Aug 23 15:10:54 2010
Shane, well, what makes you think that we haven't looked around ourselves? Also, we managed to get systemd accepted by Fedora, in particular FESCO. We managed to convince this technical committee that systemd is a good thing. Do you really want to say that Fedora as a whole is incapable of "seeing the big picture", but you are the only one who is? Maybe things are the other way round? Ever thought about that?
Also, note that systemd actually brings Linux administration much closer to how many of these things are done on Solaris. Much of what we added is inspired by SMF, and other init systems. That means the administrators should enjoy how we make things on Linux work much more like the other big server operating systems.
Posted by Lennart at Mon Aug 23 15:13:46 2010
Michael: it currently isn't translated, but the plan is to copy very closely the mechanism how .desktop files are translated (our unit definition files also use an .ini inspired format), so that we can reuse existing tools for this. This hasn't been implemented yet however.
Posted by Simon at Mon Aug 23 16:07:24 2010
Shane Falco, you are being dishonest.
Your concern is that this change would require you to learn new things and have to teach new things.
The way you should rephrase your questions is:
&#8220;Sorry for being off-topic; I am posting this on the For Admins post while my concern is really about "Does systemd offer so many nice things that justifies the change?". I would like to see the question answered: "What are the advantages of systemd that justify this big change? I did not search your previous posts on this subjest."&#8221;
Posted by Diego at Mon Aug 23 16:21:50 2010
What about gettext support?
Posted by Lennart at Mon Aug 23 16:42:09 2010
Diego: it's unlikely we'll use the gettext APIs inside of PID 1, simply because i18n data tends to be stored in /usr, and we try to avoid accesses to that, since some folks still have that one a seperate partition (even though it is crazy and misses the point). However, for the client tools this is differentely and w'll certainly reuse the framworks currently used by other projects, be it gettext or intltool, or the hacks to make .desktop files translatable.
ure people would hate me if i'd start moving i18n data to /lib...
Posted by Nagilum at Mon Aug 23 20:45:09 2010
If ntpd.service would have emitted some error message while starting up, how would I display that using systemd?
Posted by Lennart at Mon Aug 23 20:49:05 2010
Nagilum: by checking the logs. The long term plan is to hook up "systemctl status" to the logs, so that you'll see the most recent log messages generated by a service next to the service. But until that happened we need to beef up syslog considerable, i.e. make it indexable and stuff like that.
Posted by Denice at Tue Aug 24 00:43:45 2010
I'm a little worried that anyone thinks Solaris' SMF is something worthy of copying. I find it horribly over-engineered. These days it is common to run virtual servers which do really only one thing (web server, or a mysql slave, or an ldap server). I have a number of xen guests that list perhaps 15 'chkconfig-ed on' services:
chkconfig --list|grep :on
So from a system administrator's point of view, speaking of managing targeted servers and not multimedia desktops, I don't need anything complicated to manage runtime services.
You might want to seriously think about writing a tutorial for a typical small server (apache only, for example - no graphics, no bluetooth, no atd, no iscsi, etc.), and then convince us that systemd provides any value.
cheers, etc.
Posted by Shane at Tue Aug 24 01:49:13 2010
Denice said it better than I ever could. As someone stuck with over a hundred Solaris 10 servers, I agree completely with her assessment.
Here's a nice little commentary on Apple's launchd which I feel is just as appropriate for systemd:
http://lowendmac.com/ed/winston/10kw/launchd.html
It's monolithic, it's "over engineered", and it does too many things. In a nutshell, it's anti-unix.
Posted by Karellen at Tue Aug 24 14:02:45 2010
@Shane:
[systemd] does too many things
It manages the startup and lifetime of system processes. That's it.
From the article you linked:
Merging periodically run jobs into the main system process doesn't make sense.
Why not? "cron" and "at" manage the startup of periodic system processes. The only thing they do different from "init" is that they start the processes at a time other than bootup. Everything else is common between them. So why not de-duplicate the effort involved in starting, tracking and logging, and just allow "init" to start other processes at times other than boot?
Replacing a simple /etc/crontab text file with multiple, awkwardly named XML plist files scattered among no less than four different directories is taking two big steps toward complexity.
There's no reason that systemd would be implemented that badly. In fact, I'm pretty sure that systemd reads existing "crontab" files just fine. So systemd doesn't require any changes there.
Starting infrequently used on-demand socket-based daemons from launchd seems like it could open the main system process to a potential denial of service attack. I have not explored this idea or researched to see if it has already been tried,
Well, I haven't researched it, that looks like nothing more than FUD and making-shit-up to me.
One of the core principles of Unix programing is do one thing and do it well.
Like having one and only one place to consistently manage the startup and monitoring of system processes? Oh yeah, that's totally anti-Unix-philosophy.
Posted by Lennart at Tue Aug 24 19:37:50 2010
Denice, __Linux is a scalabale operating system__. It is used on big irons to tiniest devices. With systemd we try to cover the whole bandwidth, and please understand that your specific use case is not the only one we need to cover.
Shane, you are right, systemd is nothing like traditional Unix. And that is a good thing. Unix has been designed 41 years ago. You honestly believe that its design is perfect and flawless and 41 years after it was designed still should be followed in all detail? No, computers changed, and Unix never was perfect. It probably was a better design than most other operating systems, but this does not mean it is perfect and we should never depart from it. systemd is inspired by Unix, but also from what has been done on MacOS and even on the Windows world, and on Solaris. We didn't copy any of the existing services 1:1, we just let us inspire by their best features and translated them to Linux and added quite a bit of new stuff on top. And that's how it should be done. Unix is an inspiration, it is not the holy grail. Not 41y after it was designed.
The fact that on traditional Unix the init system was seperate from cron, from at, from inetd, from the dbus service activator and from everything else meant that all of them reimplemented a big chunk of their code, i.e. what was involved with spawning processes. It was a useless code duplication, and all implementations sucked at it in one way or another. Also, you could not run the same thing from more than one of these systems without manually ensuring that things would happen race-freely and properly ordered. In systemd we unified all of this. We use the same codepaths for spawning processes, regardless if they are started via timers, via sockets, via busses, at boot-up, via devices and so on. This allows us to reduce the amount of code duplication, and provide the same awesome process babysitting to all triggers. And that is a big big advantage. If you look at the systemd source code you will notice that the remaining amount of code, for example for doing timer-based spawning is actually very very short, less than 500 lines (including comments and whitespace!). So overall, we simplify things drastically, we get rid of immense code duplication, and we still are a lot more powerful than what came before.
So, in summary: just because we do things differently doesn't mean we do it worse.
And if you tell me that systemd is not Unixy, then I can only agree, and I don't feel ashamed at all of that. Because my horizon is much further than just Unix.
Posted by Lennart at Mon Jul 11 15:22:01 2011
Rob, this would surprise me too if it was true. But... I actually wrote such a blog article:
http://0pointer.de/blog/projects/systemd-for-admins-3.html

View File

@@ -0,0 +1,333 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-21T20:12:53+08:00
====== systemd for Administrators, Part II ======
Created Wednesday 21 November 2012
レナート Wunschkonzert, Ponyhof und Abenteuerspielplatz ﻟﻴﻨﺎﺭﺕ
Wed, 08 Sep 2010
systemd for Administrators, Part II
Here's the second installment of my ongoing series about systemd for administrators.
===== Which Service Owns Which Processes? =====
On most Linux systems the number of processes that are running by default is substantial. Knowing __which process does what and where it belongs to__ becomes increasingly difficult. Some services even maintain a couple of worker processes which clutter the "ps" output with many additional processes that are often not easy to recognize. This is further complicated if daemons spawn arbitrary 3rd-party processes, as Apache does with CGI processes, or cron does with user jobs.
A slight remedy for this is often the __process inheritance tree__, as shown by "ps xaf". However this is usually not reliable, as processes whose parents die get reparented to PID 1, and hence all information about inheritance gets lost. If a process "double forks" it hence loses its relationships to the processes that started it. (This actually is supposed to be a feature and is relied on for the traditional Unix daemonizing logic.) Furthermore processes can freely change their names with PR_SETNAME or by patching argv[0], thus making it harder to recognize them. In fact they can play hide-and-seek with the administrator pretty nicely this way.
In systemd we __place every process that is spawned in a control group named after its service__. Control groups (or cgroups) at their most basic are simply groups of processes that can be arranged in a hierarchy and labelled individually. When processes spawn other processes these children are automatically made members of the parents cgroup. Leaving a cgroup is not possible for unprivileged processes. Thus, cgroups can be used as **an effective way to label processes** after the service they belong to and be sure that the service cannot escape from the label, regardless how often it forks or renames itself. Furthermore this can be used to safely __kill a service and all processes it created__, again with no chance of escaping.
In today's installment I want to introduce you to two commands you may use to relate systemd services and processes. The first one, is the well known ps command which has been updated to show cgroup information along the other process details. And this is how it looks:
**$ ps xawf -eo pid,user,cgroup,args**
PID USER CGROUP COMMAND
2 root - [kthreadd]
3 root - \_ [ksoftirqd/0]
[...]
4281 root - \_ [flush-8:0]
1 root name=systemd:/systemd-1 /sbin/init
455 root name=systemd:/systemd-1/sysinit.service /sbin/udevd -d
28188 root name=systemd:/systemd-1/sysinit.service \_ /sbin/udevd -d
28191 root name=systemd:/systemd-1/sysinit.service \_ /sbin/udevd -d
1096 dbus name=systemd:/systemd-1/dbus.service /bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation
1131 root name=systemd:/systemd-1/auditd.service auditd
1133 root name=systemd:/systemd-1/auditd.service \_ /sbin/audispd
1135 root name=systemd:/systemd-1/auditd.service \_ /usr/sbin/sedispatch
1171 root name=systemd:/systemd-1/NetworkManager.service /usr/sbin/NetworkManager --no-daemon
4028 root name=systemd:/systemd-1/NetworkManager.service \_ /sbin/dhclient -d -4 -sf /usr/libexec/nm-dhcp-client.action -pf /var/run/dhclient-wlan0.pid -lf /var/lib/dhclient/dhclient-7d32a784-ede9-4cf6-9ee3-60edc0bce5ff-wlan0.lease -
1175 avahi name=systemd:/systemd-1/avahi-daemon.service avahi-daemon: running [epsilon.local]
1194 avahi name=systemd:/systemd-1/avahi-daemon.service \_ avahi-daemon: chroot helper
1193 root name=systemd:/systemd-1/rsyslog.service /sbin/rsyslogd -c 4
1195 root name=systemd:/systemd-1/cups.service cupsd -C /etc/cups/cupsd.conf
1207 root name=systemd:/systemd-1/mdmonitor.service mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
1210 root name=systemd:/systemd-1/irqbalance.service irqbalance
1216 root name=systemd:/systemd-1/dbus.service /usr/sbin/modem-manager
1219 root name=systemd:/systemd-1/dbus.service /usr/libexec/polkit-1/polkitd
1242 root name=systemd:/systemd-1/dbus.service /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
1249 68 name=systemd:/systemd-1/haldaemon.service hald
1250 root name=systemd:/systemd-1/haldaemon.service \_ hald-runner
1273 root name=systemd:/systemd-1/haldaemon.service \_ hald-addon-input: Listening on /dev/input/event3 /dev/input/event9 /dev/input/event1 /dev/input/event7 /dev/input/event2 /dev/input/event0 /dev/input/event8
1275 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-rfkill-killswitch
1284 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-leds
1285 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-generic-backlight
1287 68 name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-acpi
1317 root name=systemd:/systemd-1/abrtd.service /usr/sbin/abrtd -d -s
1332 root name=systemd:/systemd-1/getty@.service/tty2 /sbin/mingetty tty2
1339 root name=systemd:/systemd-1/getty@.service/tty3 /sbin/mingetty tty3
1342 root name=systemd:/systemd-1/getty@.service/tty5 /sbin/mingetty tty5
1343 root name=systemd:/systemd-1/getty@.service/tty4 /sbin/mingetty tty4
1344 root name=systemd:/systemd-1/crond.service crond
1346 root name=systemd:/systemd-1/getty@.service/tty6 /sbin/mingetty tty6
1362 root name=systemd:/systemd-1/sshd.service /usr/sbin/sshd
1376 root name=systemd:/systemd-1/prefdm.service /usr/sbin/gdm-binary -nodaemon
1391 root name=systemd:/systemd-1/prefdm.service \_ /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 --force-active-vt
1394 root name=systemd:/systemd-1/prefdm.service \_ /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-f2KUOh/database -nolisten tcp vt1
1495 root name=systemd:/user/lennart/1 \_ pam: gdm-password
1521 lennart name=systemd:/user/lennart/1 \_ gnome-session
1621 lennart name=systemd:/user/lennart/1 \_ metacity
1635 lennart name=systemd:/user/lennart/1 \_ gnome-panel
1638 lennart name=systemd:/user/lennart/1 \_ nautilus
1640 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/polkit-gnome-authentication-agent-1
1641 lennart name=systemd:/user/lennart/1 \_ /usr/bin/seapplet
1644 lennart name=systemd:/user/lennart/1 \_ gnome-volume-control-applet
1646 lennart name=systemd:/user/lennart/1 \_ /usr/sbin/restorecond -u
1652 lennart name=systemd:/user/lennart/1 \_ /usr/bin/devilspie
1662 lennart name=systemd:/user/lennart/1 \_ nm-applet --sm-disable
1664 lennart name=systemd:/user/lennart/1 \_ gnome-power-manager
1665 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/gdu-notification-daemon
1670 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/evolution/2.32/evolution-alarm-notify
1672 lennart name=systemd:/user/lennart/1 \_ /usr/bin/python /usr/share/system-config-printer/applet.py
1674 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/deja-dup/deja-dup-monitor
1675 lennart name=systemd:/user/lennart/1 \_ abrt-applet
1677 lennart name=systemd:/user/lennart/1 \_ bluetooth-applet
1678 lennart name=systemd:/user/lennart/1 \_ gpk-update-icon
1408 root name=systemd:/systemd-1/console-kit-daemon.service /usr/sbin/console-kit-daemon --no-daemon
1419 gdm name=systemd:/systemd-1/prefdm.service /usr/bin/dbus-launch --exit-with-session
1453 root name=systemd:/systemd-1/dbus.service /usr/libexec/upowerd
1473 rtkit name=systemd:/systemd-1/rtkit-daemon.service /usr/libexec/rtkit-daemon
1496 root name=systemd:/systemd-1/accounts-daemon.service /usr/libexec/accounts-daemon
1499 root name=systemd:/systemd-1/systemd-logger.service /lib/systemd/systemd-logger
1511 lennart name=systemd:/systemd-1/prefdm.service /usr/bin/gnome-keyring-daemon --daemonize --login
1534 lennart name=systemd:/user/lennart/1 dbus-launch --sh-syntax --exit-with-session
1535 lennart name=systemd:/user/lennart/1 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
1603 lennart name=systemd:/user/lennart/1 /usr/libexec/gconfd-2
1612 lennart name=systemd:/user/lennart/1 /usr/libexec/gnome-settings-daemon
1615 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd
1626 lennart name=systemd:/user/lennart/1 /usr/libexec//gvfs-fuse-daemon /home/lennart/.gvfs
1634 lennart name=systemd:/user/lennart/1 /usr/bin/pulseaudio --start --log-target=syslog
1649 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/pulse/gconf-helper
1645 lennart name=systemd:/user/lennart/1 /usr/libexec/bonobo-activation-server --ac-activate --ior-output-fd=24
1668 lennart name=systemd:/user/lennart/1 /usr/libexec/im-settings-daemon
1701 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfs-gdu-volume-monitor
1707 lennart name=systemd:/user/lennart/1 /usr/bin/gnote --panel-applet --oaf-activate-iid=OAFIID:GnoteApplet_Factory --oaf-ior-fd=22
1725 lennart name=systemd:/user/lennart/1 /usr/libexec/clock-applet
1727 lennart name=systemd:/user/lennart/1 /usr/libexec/wnck-applet
1729 lennart name=systemd:/user/lennart/1 /usr/libexec/notification-area-applet
1733 root name=systemd:/systemd-1/dbus.service /usr/libexec/udisks-daemon
1747 root name=systemd:/systemd-1/dbus.service \_ udisks-daemon: polling /dev/sr0
1759 lennart name=systemd:/user/lennart/1 gnome-screensaver
1780 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd-trash --spawner :1.9 /org/gtk/gvfs/exec_spaw/0
1864 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfs-afc-volume-monitor
1874 lennart name=systemd:/user/lennart/1 /usr/libexec/gconf-im-settings-daemon
1903 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd-burn --spawner :1.9 /org/gtk/gvfs/exec_spaw/1
1909 lennart name=systemd:/user/lennart/1 gnome-terminal
1913 lennart name=systemd:/user/lennart/1 \_ gnome-pty-helper
1914 lennart name=systemd:/user/lennart/1 \_ bash
29231 lennart name=systemd:/user/lennart/1 | \_ ssh tango
2221 lennart name=systemd:/user/lennart/1 \_ bash
4193 lennart name=systemd:/user/lennart/1 | \_ ssh tango
2461 lennart name=systemd:/user/lennart/1 \_ bash
29219 lennart name=systemd:/user/lennart/1 | \_ emacs systemd-for-admins-1.txt
15113 lennart name=systemd:/user/lennart/1 \_ bash
27251 lennart name=systemd:/user/lennart/1 \_ empathy
29504 lennart name=systemd:/user/lennart/1 \_ ps xawf -eo pid,user,cgroup,args
1968 lennart name=systemd:/user/lennart/1 ssh-agent
1994 lennart name=systemd:/user/lennart/1 gpg-agent --daemon --write-env-file
18679 lennart name=systemd:/user/lennart/1 /bin/sh /usr/lib64/firefox-3.6/run-mozilla.sh /usr/lib64/firefox-3.6/firefox
18741 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/firefox-3.6/firefox
28900 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/nspluginwrapper/npviewer.bin --plugin /usr/lib64/mozilla/plugins/libflashplayer.so --connection /org/wrapper/NSPlugins/libflashplayer.so/18741-6
4016 root name=systemd:/systemd-1/sysinit.service /usr/sbin/bluetoothd --udev
4094 smmsp name=systemd:/systemd-1/sendmail.service sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
4096 root name=systemd:/systemd-1/sendmail.service sendmail: accepting connections
4112 ntp name=systemd:/systemd-1/ntpd.service /usr/sbin/ntpd -n -u ntp:ntp -g
27262 lennart name=systemd:/user/lennart/1 /usr/libexec/mission-control-5
27265 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-haze
27268 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-logger
27270 lennart name=systemd:/user/lennart/1 /usr/libexec/dconf-service
27280 lennart name=systemd:/user/lennart/1 /usr/libexec/notification-daemon
27284 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-gabble
27285 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-salut
27297 lennart name=systemd:/user/lennart/1 /usr/libexec/geoclue-yahoo
(Note that this output is shortened, I have removed most of the kernel threads here, since they are not relevant in the context of this blog story)
In the third column you see the cgroup systemd assigned to each process. You'll find that the udev processes are in the **name=systemd:/systemd-1/sysinit.service** cgroup, which is where systemd places **all processes started by the sysinit.service** service, which covers early boot.
My personal recommendation is to set the shell alias psc to the ps command line shown above:
**alias psc='ps xawf -eo pid,user,cgroup,args'**
With this service information of processes is just four keypresses away!
A different way to present the same information is the __systemd-cgls__ tool we ship with systemd. It shows the cgroup hierarchy in a pretty tree. Its output looks like this:
$ systemd-cgls
+ 2 [kthreadd]
[...]
+ 4281 [flush-8:0]
+ user
| \ lennart
| \ 1
| + 1495 pam: gdm-password
| + 1521 gnome-session
| + 1534 dbus-launch --sh-syntax --exit-with-session
| + 1535 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
| + 1603 /usr/libexec/gconfd-2
| + 1612 /usr/libexec/gnome-settings-daemon
| + 1615 /ushr/libexec/gvfsd
| + 1621 metacity
| + 1626 /usr/libexec//gvfs-fuse-daemon /home/lennart/.gvfs
| + 1634 /usr/bin/pulseaudio --start --log-target=syslog
| + 1635 gnome-panel
| + 1638 nautilus
| + 1640 /usr/libexec/polkit-gnome-authentication-agent-1
| + 1641 /usr/bin/seapplet
| + 1644 gnome-volume-control-applet
| + 1645 /usr/libexec/bonobo-activation-server --ac-activate --ior-output-fd=24
| + 1646 /usr/sbin/restorecond -u
| + 1649 /usr/libexec/pulse/gconf-helper
| + 1652 /usr/bin/devilspie
| + 1662 nm-applet --sm-disable
| + 1664 gnome-power-manager
| + 1665 /usr/libexec/gdu-notification-daemon
| + 1668 /usr/libexec/im-settings-daemon
| + 1670 /usr/libexec/evolution/2.32/evolution-alarm-notify
| + 1672 /usr/bin/python /usr/share/system-config-printer/applet.py
| + 1674 /usr/lib64/deja-dup/deja-dup-monitor
| + 1675 abrt-applet
| + 1677 bluetooth-applet
| + 1678 gpk-update-icon
| + 1701 /usr/libexec/gvfs-gdu-volume-monitor
| + 1707 /usr/bin/gnote --panel-applet --oaf-activate-iid=OAFIID:GnoteApplet_Factory --oaf-ior-fd=22
| + 1725 /usr/libexec/clock-applet
| + 1727 /usr/libexec/wnck-applet
| + 1729 /usr/libexec/notification-area-applet
| + 1759 gnome-screensaver
| + 1780 /usr/libexec/gvfsd-trash --spawner :1.9 /org/gtk/gvfs/exec_spaw/0
| + 1864 /usr/libexec/gvfs-afc-volume-monitor
| + 1874 /usr/libexec/gconf-im-settings-daemon
| + 1882 /usr/libexec/gvfs-gphoto2-volume-monitor
| + 1903 /usr/libexec/gvfsd-burn --spawner :1.9 /org/gtk/gvfs/exec_spaw/1
| + 1909 gnome-terminal
| + 1913 gnome-pty-helper
| + 1914 bash
| + 1968 ssh-agent
| + 1994 gpg-agent --daemon --write-env-file
| + 2221 bash
| + 2461 bash
| + 4193 ssh tango
| + 15113 bash
| + 18679 /bin/sh /usr/lib64/firefox-3.6/run-mozilla.sh /usr/lib64/firefox-3.6/firefox
| + 18741 /usr/lib64/firefox-3.6/firefox
| + 27251 empathy
| + 27262 /usr/libexec/mission-control-5
| + 27265 /usr/libexec/telepathy-haze
| + 27268 /usr/libexec/telepathy-logger
| + 27270 /usr/libexec/dconf-service
| + 27280 /usr/libexec/notification-daemon
| + 27284 /usr/libexec/telepathy-gabble
| + 27285 /usr/libexec/telepathy-salut
| + 27297 /usr/libexec/geoclue-yahoo
| + 28900 /usr/lib64/nspluginwrapper/npviewer.bin --plugin /usr/lib64/mozilla/plugins/libflashplayer.so --connection /org/wrapper/NSPlugins/libflashplayer.so/18741-6
| + 29219 emacs systemd-for-admins-1.txt
| + 29231 ssh tango
| \ 29519 systemd-cgls
\ systemd-1
+ 1 /sbin/init
+ ntpd.service
| \ 4112 /usr/sbin/ntpd -n -u ntp:ntp -g
+ systemd-logger.service
| \ 1499 /lib/systemd/systemd-logger
+ accounts-daemon.service
| \ 1496 /usr/libexec/accounts-daemon
+ rtkit-daemon.service
| \ 1473 /usr/libexec/rtkit-daemon
+ console-kit-daemon.service
| \ 1408 /usr/sbin/console-kit-daemon --no-daemon
+ prefdm.service
| + 1376 /usr/sbin/gdm-binary -nodaemon
| + 1391 /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 --force-active-vt
| + 1394 /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-f2KUOh/database -nolisten tcp vt1
| + 1419 /usr/bin/dbus-launch --exit-with-session
| \ 1511 /usr/bin/gnome-keyring-daemon --daemonize --login
+ getty@.service
| + tty6
| | \ 1346 /sbin/mingetty tty6
| + tty4
| | \ 1343 /sbin/mingetty tty4
| + tty5
| | \ 1342 /sbin/mingetty tty5
| + tty3
| | \ 1339 /sbin/mingetty tty3
| \ tty2
| \ 1332 /sbin/mingetty tty2
+ abrtd.service
| \ 1317 /usr/sbin/abrtd -d -s
+ crond.service
| \ 1344 crond
+ sshd.service
| \ 1362 /usr/sbin/sshd
+ sendmail.service
| + 4094 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
| \ 4096 sendmail: accepting connections
+ haldaemon.service
| + 1249 hald
| + 1250 hald-runner
| + 1273 hald-addon-input: Listening on /dev/input/event3 /dev/input/event9 /dev/input/event1 /dev/input/event7 /dev/input/event2 /dev/input/event0 /dev/input/event8
| + 1275 /usr/libexec/hald-addon-rfkill-killswitch
| + 1284 /usr/libexec/hald-addon-leds
| + 1285 /usr/libexec/hald-addon-generic-backlight
| \ 1287 /usr/libexec/hald-addon-acpi
+ irqbalance.service
| \ 1210 irqbalance
+ avahi-daemon.service
| + 1175 avahi-daemon: running [epsilon.local]
+ NetworkManager.service
| + 1171 /usr/sbin/NetworkManager --no-daemon
| \ 4028 /sbin/dhclient -d -4 -sf /usr/libexec/nm-dhcp-client.action -pf /var/run/dhclient-wlan0.pid -lf /var/lib/dhclient/dhclient-7d32a784-ede9-4cf6-9ee3-60edc0bce5ff-wlan0.lease -cf /var/run/nm-dhclient-wlan0.conf wlan0
+ rsyslog.service
| \ 1193 /sbin/rsyslogd -c 4
+ mdmonitor.service
| \ 1207 mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
+ cups.service
| \ 1195 cupsd -C /etc/cups/cupsd.conf
+ auditd.service
| + 1131 auditd
| + 1133 /sbin/audispd
| \ 1135 /usr/sbin/sedispatch
+ dbus.service
| + 1096 /bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation
| + 1216 /usr/sbin/modem-manager
| + 1219 /usr/libexec/polkit-1/polkitd
| + 1242 /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
| + 1453 /usr/libexec/upowerd
| + 1733 /usr/libexec/udisks-daemon
| + 1747 udisks-daemon: polling /dev/sr0
| \ 29509 /usr/libexec/packagekitd
+ dev-mqueue.mount
+ dev-hugepages.mount
\ sysinit.service
+ 455 /sbin/udevd -d
+ 4016 /usr/sbin/bluetoothd --udev
+ 28188 /sbin/udevd -d
\ 28191 /sbin/udevd -d
(This too is shortened, the same way)
As you can see, this command shows the processes by their cgroup and hence service, as systemd labels the cgroups after the services. For example, you can easily see that the auditing service auditd.service spawns three individual processes, auditd, audisp and sedispatch.
If you look closely you will notice that a number of processes have been assigned to the cgroup **/user/1**. At this point let's simply leave it at that __systemd not only maintains services in cgroups, but user session processes as well__. In a later installment we'll discuss in more detail what this about.
So much for now, come back soon for the next installment!
posted at: 00:52 | path: /projects | permanent link to this entry | 13 comments
Posted by liam at Wed Sep 8 04:51:28 2010
Thanks for these posts.
I'm a bit uncertain as to how far cgroups can be pushed for administrative purposes. Can you have nested cgroups? For instance, a Gnome/X/whatever group that one could kill? Can the end user create alias' for cgroups which could then aggregate them into more manageable units?
thanks
Posted by Lennart at Wed Sep 8 11:36:25 2010
Liam, cgroups are fully recursive, you may split every cgroup into sub-cgroups. And as soon as __systemd is used for session management__ the same way it is used for system management session services will be arranged the same way in subgroups of the group the session manager happened to be executed under.
Posted by Perry Lorier at Sun Sep 12 19:57:12 2010
So, you've reinvented process groups?
Posted by Lennart at Sun Sep 12 20:21:43 2010
Perry, no, not at all. process groups you can escape. They aren't hierarchical, they cannot be labelled. Process groups are very very different from cgroups, and useful for little more than pipeline building in shells.
Posted by Ken Stailey at Sat Nov 10 20:45:39 2012
The ps "ax" and "-e" options both enable displaying "everything", i.e. all processes. It is not necessary to use both.

View File

@@ -0,0 +1,250 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-21T20:36:45+08:00
====== systemd for Administrators, Part III ======
Created Wednesday 21 November 2012
レナート Wunschkonzert, Ponyhof und Abenteuerspielplatz ﻟﻴﻨﺎﺭﺕ
Fri, 01 Oct 2010
systemd for Administrators, Part III
Here's the third installment of my ongoing series about systemd for administrators.
===== How Do I Convert A SysV Init Script Into A systemd Service File? =====
Traditionally, Unix and Linux services (daemons) are started via __SysV init scripts__. These are Bourne Shell scripts, usually residing in a directory such as __/etc/rc.d/init.d/__ which when called with one of a few standardized arguments (verbs) such as __start, stop or restart__ controls, i.e. starts, stops or restarts the service in question. For starts this usually involves invoking the daemon binary, which then forks a background process (more precisely daemonizes).
Shell scripts tend to be slow, needlessly hard to read, very verbose and fragile. Although they are __immensly flexible__ (after all, they are just code) some things are very hard to do properly with shell scripts, such as ordering parallized execution, correctly supervising processes or just **configuring execution contexts** in all detail. systemd provides __compatibility__ with these shell scripts, but due to the shortcomings pointed out it is recommended to install native systemd service files for all daemons installed. Also, in contrast to SysV init scripts which have to be adjusted to the distribution systemd service files are compatible with any kind of distribution running systemd (which become more and more these days...).
What follows is a terse guide how to take a SysV init script and translate it into a native systemd service file. Ideally, upstream projects should ship and install systemd service files in their tarballs. If you have successfully converted a SysV script according to the guidelines it might hence be a good idea to submit the file as patch to upstream. How to prepare a patch like that will be discussed in a later installment, suffice to say at this point that the daemon(7) manual page shipping with systemd contains a lot of useful information regarding this.
So, let's jump right in. As an example we'll convert the init script of the **ABRT** daemon into a systemd service file. ABRT is a standard component of every Fedora install, and is an acronym for Automatic Bug Reporting Tool, which pretty much describes what it does, i.e. it is a service for collecting crash dumps. Its SysV script I have uploaded here.
The first step when converting such a script is to read it (surprise surprise!) and distill the useful information from the usually pretty long script. In almost all cases the script consists of mostly boilerplate code that is identical or at least very similar in all init scripts, and usually copied and pasted from one to the other. So, let's extract the interesting information from the script linked above:
* A description string for the service is "Daemon to detect crashing apps". As it turns out, the header comments include a redundant number of description strings, some of them describing less the actual service but the init script to start it. systemd services include a description too, and it should describe the service and not the service file.
* The __LSB header__[1] contains dependency information. systemd due to its design around socket-based activation usually needs __no__ (or very little) manually configured dependencies. (For details regarding socket activation see the original announcement blog post.) In this case the dependency on $syslog (which encodes that abrtd requires a syslog daemon), is the only valuable information. While the header lists another dependency ($local_fs) this one is redundant with systemd as normal system services are always started with all local file systems available.
* The LSB header suggests that this service should be started in runlevels 3 (multi-user) and 5 (graphical).
* The daemon binary is /usr/sbin/abrtd
And that's already it. The entire remaining content of this 115-line shell script is simply boilerplate or otherwise redundant code: code that deals with synchronizing and serializing startup (i.e. the code regarding lock files) or that outputs status messages (i.e. the code calling echo), or simply parsing of the verbs (i.e. the big case block).
From the information extracted above we can now write our systemd service file:
**[Unit]**
**Description=Daemon to detect crashing apps**
**After=syslog.target**
**[Service]**
**ExecStart=/usr/sbin/abrtd**
**Type=forking**
**[Install]**
**WantedBy=multi-user.target**
A little explanation of the contents of this file: The [Unit] section contains generic information about the service. systemd not only manages system services, but also devices, mount points, timer, and other components of the system. The generic term for all these objects in systemd is a unit, and the [Unit] section encodes information about it that might be applicable not only to services but also in to the other unit types systemd maintains. In this case we set the following unit settings: we set the description string and configure that the daemon shall be **started after** Syslog[2], similar to what is encoded in the LSB header of the original init script. For this Syslog dependency we create a dependency of type __After=__ on a systemd unit syslog.target. The latter is **a special target unit** in systemd and is the standardized name to pull in a syslog implementation. For more information about these standardized names see the systemd.special(7). Note that a dependency of type After= only encodes the suggested ordering, but does not actually cause syslog to be started when abrtd is -- and this is exactly what we want, since abrtd actually works fine even without syslog being around. However, if both are started (and usually they are) then the order in which they are is controlled with this dependency.
The next section is [Service] which encodes information about the service itself. It contains all those settings that apply only to services, and not the other kinds of units systemd maintains (mount points, devices, timers, ...). Two settings are used here: __ExecStart=__ takes the path to the binary to execute when the service shall be started up. And with __Type=__ we configure **how the service notifies the init system that it finished starting up.** Since traditional Unix daemons do this by returning to the parent process after having forked off and initialized the background daemon we set the type to forking here. That tells systemd to wait until the start-up binary returns and then consider the processes still running afterwards the daemon processes.
The final section is [Install]. It encodes information about how the suggested installation should look like, i.e. under which circumstances and by which triggers the service shall be started. In this case we simply say that __this service shall be started when the multi-user.target unit is activated__. This is a special unit (see above) that basically takes the role of the classic SysV Runlevel 3[3]. The setting WantedBy= has little effect on the daemon during runtime. It is only read by the systemctl enable command, which is the recommended way to enable a service in systemd. This command will simply ensure that our little service gets automatically activated as soon as multi-user.target is requested, which it is on all normal boots[4].
And that's it. Now we already have a minimal working systemd service file. To test it we copy it to /etc/systemd/system/abrtd.service and invoke systemctl daemon-reload. This will make systemd take notice of it, and now we can start the service with it: systemctl start abrtd.service. We can verify the status via systemctl status abrtd.service. And we can stop it again via systemctl stop abrtd.service. Finally, we can enable it, so that it is activated by default on future boots with systemctl enable abrtd.service.
The service file above, while sufficient and basically a 1:1 translation (feature- and otherwise) of the SysV init script still has room for improvement. Here it is a little bit updated:
[Unit]
Description=ABRT Automated Bug Reporting Tool
After=syslog.target
[Service]
Type=dbus
BusName=com.redhat.abrt
ExecStart=/usr/sbin/abrtd -d -s
[Install]
WantedBy=multi-user.target
So, what did we change? Two things: we improved the description string a bit. More importantly however, we changed the type of the service to dbus and configured the D-Bus bus name of the service. Why did we do this? As mentioned classic SysV services daemonize after startup, which usually involves double forking and detaching from any terminal. While this is useful and necessary when daemons are invoked via a script, this is unnecessary (and slow) as well as counterproductive when a proper process babysitter such as systemd is used. The reason for that is that the forked off daemon process usually has little relation to the original process started by systemd (after all the daemonizing scheme's whole idea is to remove this relation), and hence it is difficult for systemd to figure out after the fork is finished which process belonging to the service is actually the main process and which processes might just be auxiliary. But that information is crucial to implement advanced babysitting, i.e. supervising the process, automatic respawning on abnormal termination, collectig crash and exit code information and suchlike. In order to make it easier for systemd to figure out the main process of the daemon we changed the service type to dbus. The semantics of this service type are appropriate for all services that take a name on the D-Bus system bus as last step of their initialization[5]. ABRT is one of those. With this setting systemd will spawn the ABRT process, which will no longer fork (this is configured via the -d -s switches to the daemon), and systemd will consider the service fully started up as soon as com.redhat.abrt appears on the bus. This way the process spawned by systemd is the main process of the daemon, systemd has a reliable way to figure out when the daemon is fully started up and systemd can easily supervise it.
And that's all there is to it. We have a simple systemd service file now that encodes in 10 lines more information than the original SysV init script encoded in 115. And even now there's a lot of room left for further improvement utilizing more features systemd offers. For example, we could set Restart=restart-always to tell systemd to automatically restart this service when it dies. Or, we could use OOMScoreAdjust=-500 to ask the kernel to please leave this process around when the OOM killer wreaks havoc. Or, we could use CPUSchedulingPolicy=idle to ensure that abrtd processes crash dumps in background only, always allowing the kernel to give preference to whatever else might be running and needing CPU time.
For more information about the configuration options mentioned here, see the respective man pages systemd.unit(5), systemd.service(5), systemd.exec(5). Or, browse all of systemd's man pages.
Of course, not all SysV scripts are as easy to convert as this one. But gladly, as it turns out the vast majority actually are.
That's it for today, come back soon for the next installment in our series.
Footnotes
[1] The LSB header of init scripts is a convention of including meta data about the service in comment blocks at the top of SysV init scripts and is defined by the Linux Standard Base. This was intended to standardize init scripts between distributions. While most distributions have adopted this scheme, the handling of the headers varies greatly between the distributions, and in fact still makes it necessary to adjust init scripts for every distribution. As such the LSB spec never kept the promise it made.
[2] Strictly speaking, this dependency does not even have to be encoded here, as it is redundant in a system where the Syslog daemon is socket activatable. Modern syslog systems (for example rsyslog v5) have been patched upstream to be socket-activatable. If such a init system is used configuration of the After=syslog.target dependency is redundant and implicit. However, to maintain compatibility with syslog services that have not been updated we include this dependency here.
[3] At least how it used to be defined on Fedora.
[4] Note that in systemd the graphical bootup (graphical.target, taking the role of SysV runlevel 5) is an implicit superset of the console-only bootup (multi-user.target, i.e. like runlevel 3). That means hooking a service into the latter will also hook it into the former.
[5] Actually the majority of services of the default Fedora install now take a name on the bus after startup.
posted at: 04:42 | path: /projects | permanent link to this entry | 19 comments
Posted by Anonymous at Fri Oct 1 06:58:25 2010
Ideally, couldn't you configure ABRT to only run when core files show up in a given directory, or when something requests its dbus service?
Posted by drago01 at Fri Oct 1 10:52:20 2010
CPUSchedulingPolicy=idle ... is there the same thing for IO i.e IOSchedulingPolicy=idle ?
In most cases I couldn't care less about CPU on todays multicore machines but IO is still a very limited resource (when not running an SSD).
The kernel actually allows setting IO priorities (when using the CFQ scheduler).
Posted by Lennart at Fri Oct 1 13:04:51 2010
Anonymous: While this would definitely be desirable AFAICS abrt doesn't support this scheme, since it needs to be running when the first crash dump is collected.
drag01: There's IOSchedulingClass=idle for you.
Posted by John Drinkwater at Fri Oct 1 13:34:29 2010
Restart=restart-always
Again, why have this redundancy if you are starting a design from scratch?
Restart=always|once|on-success
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
Why is one a class, and another a policy? People will mistype these.
This is not bikeshedding, this is a request to stop making everything long-winded when it does not need to be so. If systemd is to be around for the next few decades, and you have time to refine it before the next Fedora release, please do so.
Posted by Lennart at Fri Oct 1 13:55:07 2010
John, regarding Restart= you have a point. And I fixed that now.
Regarding the Class vs. Policy thing: that's how the kernel calls these things, blame the kernel folks for that. I think it would be a very bad idea to introduce deviating terminology here where the kernel fucked up.
Posted by Milan Bouchet-Valat at Fri Oct 1 15:00:38 2010
Glad to see you have an easy to parse Description field! But while you're at it, could you consider providing translated descriptions for configuration tools?
Recently, Ubuntu had a GSoC about writing a new config tool for Upstart. One of the issues was that there's no way to get a localized translation from Upstart jobs or SysV scripts, let alone an icon! It would be great if you tackled this issue in Systemd, e.g. with a standard .desktop-like file that services should ship.
The other part of the work Jacob Peddicord did in his GSoC is more remote from Systemd, but might be interesting. He has a whole project of describing configuration files associated with a service:
http://jacob.peddicord.net/gsoc2010/
http://people.ubuntu.com/~jpeddicord/SLS/0.8/sls-format-0.8.html
I guess it can be good you know it exists...
Posted by Lennart at Fri Oct 1 15:11:55 2010
Milan: the longer term plan is to support translations for the descriptions the same way as .desktop files have them. Right now we don't do this, but this is definitely the plan. I am also open to adding an Icon setting, though I am a bit concerned that if we add and Icon, then the next thing asked for is a Vendor ID and so on and so on.
Posted by j at Fri Oct 1 18:35:14 2010
verbosity is redundant (and confusing) for a unix system tool. Since Io scheduling classes are linux-specific, it can be written like that:
CPUSchedulingPolicy -> SchedLevel
IOSchedulingClass -> IOSchedLevel
BTW is systemd portable to all Unix or it needs linux kernel for some reason?
Posted by Lennart at Fri Oct 1 18:47:31 2010
j, calling the same stuff in userspace differently than in kernelspace, and calling the same stuff in the chrt tool differently than in systemd is a very bad idea.
systemd is strictly Linux specific. It is not portable to other Unixes and we do not care about portability to them. This allows us to make use of Linux features and is one of the reasons why systemd is so much more powerful than any other init system around.
Posted by Grahame at Fri Oct 1 19:03:30 2010
At the moment if I'm having a problem with a daemon failing to start I might just hack the init script, chuck strace in, and restart it. It'd be great if you could show how you might shim a failing daemon, particularly when debugging 'fails on reboot' issues (eg. starts fine later.)
Posted by Anonymous at Fri Oct 1 22:10:11 2010
I'm wondering about a services that get autostarted via D-Bus. D-Bus starts them itself, so unless I'm wrong they'll end up in the D-Bus service cgroup, not in their own cgroups. Yet I want them to be controllable as services itself. Is this possible to achieve?
Posted by Michael at Fri Oct 1 23:21:36 2010
@Anonymous:
This is one of systemd's great features:
Starting with dbus 1.4.0, dbus-daemon can hand over starting of system services to systemd, where you have all those possibilites to monitor and confine the service (in it's own cgroup)
All you need to do is to add a
SystemdService=foo.service
line to the D-Bus service file, create a foo.service file for systemd and systemd will automatically start the service defined in foo.service.
Posted by Andreas at Sat Oct 2 00:49:51 2010
I agree with those complaining about names like CPUSchedulingPolicy but as Lennart said that is hardly the fault of systemd. Not really much that can be done about it.
This is post is the part I like the most about systemd. No more boilerplate bash and no horrible XML like the launchd plists or overly verbose XML like SMF. Now there might be other good init systems but this is the first one I have seen where it is easy to just read the job configurations.
Like the use of sections too in the files so when I read them I can mostly ignore sections like [Install].
Posted by codebeard at Sat Oct 2 04:36:12 2010
@Grahame
I assume that you can do something like:
ExecStart=/usr/bin/strace -f -o /root/abrtd.strace /usr/sbin/abrtd -d -s
But perhaps Lennart has another way in mind to do this?
Posted by John Drinkwater at Sat Oct 2 14:24:51 2010
Lennart, thanks. Apologies if my comment came over a little stronger than I intended.
I notice some variables for scheduling have different ranges, is this again a kernel issue? Maybe I should go bang some heads there..
Posted by Dag Wieers at Mon Nov 22 17:58:46 2010
Lennart,
Since the moment I read your first systemd announcement I am excited about this new development. It's one of those things you wonder why that wasn't done decades ago ;-)
However, I see one thing that I liked about the sysv scripts, that is not possible. The importance of the original sysv scripts is that they are written in bash and so offers a lot of flexibility to system administrators. Flexibility comes with responsibility :-) However, where in the past sysv scripts did more than simply start/stop/restart/reload, some scripts allowed to check configuration syntax (eg. apache), initialize something (eg. sshd), etc...
There is an advantage in keeping those actions as part of the systemd tools in my opinion. Even if they are simply passing the action through to a daemon-specific configuration tool (eg. apachectl), which could become a standard. This is exactly why I liked the design of "op" so much (compared to sudo). It provided system administrators (and users) with a single interface to actions using a clean syntax.
While reading the post and the documentation I couldn't find whether "custom actions" would be retained in your design. If not, what would be the recommended alternative ?
Posted by Lennart at Mon Nov 22 19:13:05 2010
Grahame: codebears is right. You can easily prefix binary paths with strace. Just copy the service file from /lib/systemd/system to /etc/systemd/system and edit the ExecStart= line, and done.
John: yes, we mostly expose the kernel stuff 1:1.
Dag: we do not support custom actions, since their set of parameters and what they return is completely free-form it would be a bit weird to pass that through D-Bus. For example, if something is interactive, how would you pass that through D-Bus. If people want additional control interfaces for their tools, then they should create them outside of systemd, for example by creating a seperate <something>ctl tool, such as apachectl. I mean, I think it makes sense to expose new "verbs" in systemd iff these verbs make sense for everybody the same way as "start" and "stop" and similar apply for every service the same way. However, something like "apachectl graceful" is in all its meaning highly specific to Apache, and hence trying to abstract that in systemd must fail, since it's nothing that really could be abstracted nicely. SMF allows definition of additional verbs for each service, but I am not convinced this is really a good idea.
Posted by anonymous at Thu Jul 14 06:26:29 2011
bit confuse with:
To test it we copy it to /etc/systemd/system/
in my f15 installation can not find *.service file but i find in /lib/systemd/system
where .service file actually resident?
Posted by dave at Mon Feb 27 23:49:34 2012
Hi
I was having problems with my shutdown services not running as expected. I traced the issue to the use of the '--force' flag in the halt, poweroff and reboot services. Here's more about the issue and how to resolve: -
http://www.practicalclouds.com/content/blog/1/dave-mccormick/2012-02-27/why-do-my-systemd-shutdown-scripts-not-run
regards
Dave
Leave a Comment:
Your Name:
Your E-mail (optional):
Comment:
As a protection against comment spam, please type the following number into the field on the right:
Secret Number Image
Please note that this is neither a support forum nor a bug tracker! Support questions or bug reports posted here will be ignored and not responded to!
It should be obvious but in case it isn't: the opinions reflected here are my own. They are not the views of my employer, or Ronald McDonald, or anyone else.
Please note that I take the liberty to delete any comments posted here that I deem inappropriate, off-topic, or insulting. And I excercise this liberty quite agressively. So yes, if you comment here, I might censor you. If you don't want to be censored you are welcome to comment on your own blog instead.
Lennart's Blog | Lennart's Homepage | Lennart's Photos | Impressum/Imprint
Lennart Poettering <mzoybt (at) 0pointer (dot) net>
Syndicated on Planet GNOME, Planet Fedora, planet.freedesktop.org, Planet Debian Upstream. feed RSS 0.91, RSS 2.0
Archives: 2005, 2006, 2007, 2008, 2009, 2010, 2011
Valid XHTML 1.0 Strict! Valid CSS!

View File

@@ -0,0 +1,106 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-20T11:48:13+08:00
====== linux input ecosystem ======
Created Tuesday 20 November 2012
http://joeshaw.org/2010/10/01/681/
1 October 2010
Over the past couple of days, Ive been trying to figure out how input in Linux works on modern systems. There are lots of small pieces at various levels, and its hard to understand how they all interact. Things are not helped by the fact that things have changed quite a bit over the past couple of years as **HAL** — which I helped write — has been giving way to **udev**, and existing literature is largely out of date. This is my attempt at understanding how things work today, in the Ubuntu Lucid release.
===== kernel =====
In the Linux kernels **input system**, there are two pieces: __the device driver and the event driver__. The device driver talks to the hardware, obviously. Today, for most USB devices this is handled by **the usbhid driver**. The event drivers handle how to __expose the events generated by the device driver to userspace.__ Today this is primarily done through **evdev**, which creates character devices (typically named **/dev/input/eventN**) and communicates with them through **struct input_event** messages. See include/linux/input.h for its definition.
A great tool to use for getting information about evdev devices and events is **evtest**.
A somewhat outdated but still relevant description of the kernel input system can be found in the kernels Documentation/input/input.txt file.
===== udev =====
When a device is connected, the kernel creates an entry in **sysfs** for it and generates **a hotplug event**. __That hotplug event is processed by udev__, which applies some policy, attaches additional properties to the device, and ultimately creates a device node for you somewhere in /dev.
For input devices, the rules in **/lib/udev/rules.d/60-persistent-input.rules** are executed. Among the things it does is run a /**lib/udev/input_id** tool which queries the capabilities of the device from its sysfs node and sets environment variables like **ID_INPUT_KEYBOARD, ID_INPUT_TOUCHPAD, etc.** in the udev database.
For more information on input_id see the original announcement email to the hotplug list.
例如udevadm info 的输出如下
P: /devices/platform/i8042/serio4
E: DEVPATH=/devices/platform/i8042/serio4
E: DRIVER=psmouse
E: MODALIAS=serio:ty01pr00id00ex00
E: SERIO_EXTRA=00
E: SERIO_ID=00
E: SERIO_PROTO=00
E: SERIO_TYPE=01
E: SUBSYSTEM=serio
P: /devices/platform/i8042/serio4/**input/input6**
E: ABS=11000003
E: DEVPATH=/devices/platform/i8042/serio4/input/input6
--
E: NAME="SynPS/2 Synaptics TouchPad"
E: PHYS="isa0060/serio4/input0"
E: PRODUCT=11/2/7/1b1
E: PROP=1
E: __SUBSYSTEM=input__
E: TAGS=:seat:
E: USEC_INITIALIZED=13139
P: /devices/platform/i8042/serio4/input/input6/**event6 //设备路径path**
N: input/event6 **//kernel打印出的设备名称name**
__S: input/by-path/platform-i8042-serio-4-event-mouse //设备文件的符号链接symlink__
__E: DEVLINKS=/dev/input/by-path/platform-i8042-serio-4-event-mouse //udev导出的环境变量Env__
__E: DEVNAME=/dev/input/event6__
E: DEVPATH=/devices/platform/i8042/serio4/input/input6/event6
E: ID_INPUT=1
E: __ID_INPUT_TOUCHPAD=1__
E: __ID_PATH=platform-i8042-serio-4__
E: ID_PATH_TAG=platform-i8042-serio-4
E: ID_SERIAL=noserial
E: MAJOR=13
E: MINOR=70
E: SUBSYSTEM=input
E: USEC_INITIALIZED=13541
P: /devices/platform/i8042/serio4/input/input6/mouse0
N: input/mouse0
S: input/by-path/platform-i8042-serio-4-mouse
E: DEVLINKS=/dev/input/by-path/platform-i8042-serio-4-mouse
E: DEVNAME=/dev/input/mouse0
E: DEVPATH=/devices/platform/i8042/serio4/input/input6/mouse0
E: ID_INPUT=1
E: ID_INPUT_TOUCHPAD=1
E: ID_PATH=platform-i8042-serio-4
E: ID_PATH_TAG=platform-i8042-serio-4
E: ID_SERIAL=noserial
E: MAJOR=13
E: MINOR=32
E: SUBSYSTEM=input
E: USEC_INITIALIZED=13486
===== X =====
X has __a udev config backend__ which queries udev for the various input devices. It does this at startup and also watches for hotplugged devices. X looks at the different **ID_INPUT_*** properties to determine whether its a keyboard, a mouse, a touchpad, a joystick, or some other device. This information can be used in **/etc/X11/xorg.conf.d** files in the form of MatchIsPointer, MatchIsTouchpad, MatchIsJoystick, etc. in __InputClass__ sections to see whether to apply configuration to a given device.
Xorg has a handful of its own drivers to handle input devices, including **evdev, synaptics, and joystick**. And here is where things start to get confusing.
Linux has this great __generic event interface in evdev__, which means that very few drivers are needed to interact with hardware, since theyre not speaking device-specific protocols. Of the few needed on Linux nearly all of them speak evdev, including the three I listed above.
evdev即事件驱动程序为输入子系统提供了一个默认的事件处理方法。它接收来自硬件底层驱动程序的大多数事件并使用相应的逻辑对其进行处理。evdev输入事件驱动
程序从底层驱动程序接收事件信息将其反映到sysfs文件系统中用户程序通过对sysfs文件系统的操作就能够达到处理事件的目的。
The evdev driver provides basic __keyboard and mouse__ functionality, speaking — obviously — evdev through the **/dev/input/eventN** devices. It also handles things like the **lidlinux input device and power switches**. This is the basic, generic input driver for Xorg on Linux.
The synaptics driver is the most confusing of all. It also speaks evdev to the kernel. On Linux it does not talk to the hardware directly, and is __in no way Synaptics™ hardware-specific__. The synaptics driver is simply a separate driver from evdev which adds a lot of features expected of touchpad hardware, for example two-finger scrolling. It should probably be renamed the “touchpad” module, except that on non-Linux OSes it can still speak the Synaptics protocol.
The joystick driver similarly handles joysticky things, but speaks evdev to the kernel rather than some device-specific protocol.
synaptics和joystick驱动程序其实都不是直接控制硬件的驱动相反它们从硬件驱动程序接收事件然后进行处理将结果通过evdev协议发给kernel。
X only has concepts of __keyboards and pointers, the latter of which includes mice, touchpads, joysticks, wacom tablets, etc__.
X also has the concept of the __core keyboard and pointer__, which is how events are most often delivered to applications. By default all devices send core events, but certain setups might want to make devices non-core.
If you want to receive events for non-core devices, you need to use the **XInput or XInput2 extensions** for that. XInput exposes core-like events (like DeviceMotionNotify and DeviceButtonPress), so it is not a major difficulty to use, although its setup is annoyingly different than most other X extensions. I have not used XInput2.
Peter Hutterers blog is an excellent resource for all things input related in X.

View File

@@ -0,0 +1,40 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-11-30T20:20:03+08:00
====== 一些有趣的编程名言 ======
Created Friday 30 November 2012
原文http://ihower.tw/blog/archives/7046/
以下内容收集自一些优秀的技术书籍章节开头的名言佳句,非常有意思,直接或间接反映了软件开发中的一些事情。
生命太短暂不要去做一些根本__没有人想要__的东西。——Ash MauryaRunning Lean 作者
如果你交给某人一个程序你将折磨他一整天如果你教某人如何编写程序你将折磨他一辈子。——David Leinweber
软件设计有两种方式一种方式是使软件过于简单明显没有缺陷另一种方式是使软件过于复杂没有明显的缺陷。——C.A.R. Hoare
其实我尝试着使Ruby更自然而不是简单。Ruby看起来很简单但内部是非常复杂的就像我们的身体一样。——松本行弘Ruby之父
大部分情况下,**构建程序的过程本质上是对规范调试的过程**。——Fred Brooks《人月神话》作者
软件开发往往是这样最开始的90%代码占用了开始的90%的开发时间剩下10%代码同样需要90%的开发时间。——Tom Cargill
当你试图解决一个__你不理解的问题__时复杂化就产成了。——Andy Boothe
用几个小时来制定计划,可以节省几周的编程时间。—— 匿名
__控制复杂性__是计算机编程的本质。—— Brian Kernighan
计算机科学领域的所有问题都可以通过其他方式间接解决。——David Wheeler
编程是两队人马在竞争:软件工程师努力设计出最大最好的连白痴都会使用的程序;而宇宙在拼命制造最大最好的白痴。到目前为止,宇宙是胜利者。—— Rick Cook
调试一个初次见到的代码比重写代码要困难两倍。因此,按照定义,如果你写代码非常巧妙,那么没有人足够聪明来调试它。—— Brian W. Kernighan
我不是一个伟大的程序员我只是一个具有__良好习惯的优秀程序员__。― Kent Beck
你们中大多数人都熟悉程序员的美德,有三种:那就是懒惰、急躁和傲慢。– Larry WallPerl語言发明人
任何一个傻瓜都会写能够让机器理解的代码只有好的程序员才能写出人类可以理解的代码。——Martin Fowler
靠代码行数来衡量开发进度,就像是凭重量来衡量飞机制造的进度。——比尔•盖茨
这不是一个bug这只是一个未列出来的特性。——匿名
作为一个程序员,郁闷的事情是,面对一个代码块,却不敢去修改。更糟糕的是,这个代码块还是自己写的。—— Peyton Jones
它在我的机器上可以很好运行!——大部分程序员
**能说算不上什么,有本事就把你的代码给我看看。**——Linus TorvaldsLinux之父
我认为对象就像是生物学里的细胞或者网络中的一台计算机只能够通过消息来通信——Alan KaySmalltalk的发明人面向对象之父
当你选择了一种语言意味着你还选择了__一组技术、一个社区__。——Joshua Bloch
质量、速度、廉价,选择其中两个。——匿名
过早的优化是罪恶之源。——Donald Knuth
没有什么代码的执行速度比空代码更快。——Merb核心原则
如果你是房间里最聪明的人,那么你走错房间了。——匿名
如果只需更改一个单一的代码行你的部门需要花费多长时间——Mary Poppendieck
九个人不能让一个孩子在一个月内出生。——Fred Brooks《人月神话》作者
好代码本身就是最好的文档。当你需要添加一个注释时你应该考虑如何修改代码才能不需要注释。——Steve McConnellCode Complete 作者
一个人在教会电脑之前别说他真正理解这个东西了。——Donald Knuth