This document is the central repository for all information pertaining to debug information in LLVM. It describes the actual format that the LLVM debug information takes, which is useful for those interested in creating front-ends or dealing directly with the information. Further, this document provides specific examples of what debug information for C/C++ looks like.
The idea of the LLVM debugging information is to capture how the important pieces of the source-language's Abstract Syntax Tree map onto LLVM code. Several design aspects have shaped the solution that appears here. The important ones are:
The approach used by the LLVM implementation is to use a small set of intrinsic functions to define a mapping between LLVM program objects and the source-level objects. The description of the source-level program is maintained in LLVM metadata in an implementation-defined format (the C/C++ front-end currently uses working draft 7 of the DWARF 3 standard).
When a program is being debugged, a debugger interacts with the user and turns the stored debug information into source-language specific information. As such, a debugger must be aware of the source-language, and is thus tied to a specific language or family of languages.
The role of debug information is to provide meta information normally stripped away during the compilation process. This meta information provides an LLVM user a relationship between generated code and the original program source code.
Currently, debug information is consumed by DwarfDebug to produce dwarf information used by the gdb debugger. Other targets could use the same information to produce stabs or other debug forms.
It would also be reasonable to use debug information to feed profiling tools for analysis of generated code, or, tools for reconstructing the original source from generated code.
TODO - expound a bit more.
An extremely high priority of LLVM debugging information is to make it interact well with optimizations and analysis. In particular, the LLVM debug information provides the following guarantees:
Basically, the debug information allows you to compile a program with "-O0 -g" and get full debug information, allowing you to arbitrarily modify the program as it executes from a debugger. Compiling a program with "-O3 -g" gives you full debug information that is always available and accurate for reading (e.g., you get accurate stack traces despite tail call elimination and inlining), but you might lose the ability to modify the program and call functions where were optimized out of the program, or inlined away completely.
LLVM test suite provides a framework to test optimizer's handling of debugging information. It can be run like this:
% cd llvm/projects/test-suite/MultiSource/Benchmarks # or some other level % make TEST=dbgopt
This will test impact of debugging information on optimization passes. If debugging information influences optimization passes then it will be reported as a failure. See TestingGuide for more information on LLVM test infrastructure and how to run various tests.
LLVM debugging information has been carefully designed to make it possible for the optimizer to optimize the program and debugging information without necessarily having to know anything about debugging information. In particular, the use of metadata avoids duplicated debugging information from the beginning, and the global dead code elimination pass automatically deletes debugging information for a function if it decides to delete the function.
To do this, most of the debugging information (descriptors for types, variables, functions, source files, etc) is inserted by the language front-end in the form of LLVM metadata.
Debug information is designed to be agnostic about the target debugger and debugging information representation (e.g. DWARF/Stabs/etc). It uses a generic pass to decode the information that represents variables, types, functions, namespaces, etc: this allows for arbitrary source-language semantics and type-systems to be used, as long as there is a module written for the target debugger to interpret the information.
To provide basic functionality, the LLVM debugger does have to make some assumptions about the source-level language being debugged, though it keeps these to a minimum. The only common features that the LLVM debugger assumes exist are source files, and program objects. These abstract objects are used by a debugger to form stack traces, show information about local variables, etc.
This section of the documentation first describes the representation aspects common to any source-language. The next section describes the data layout conventions used by the C and C++ front-ends.
In consideration of the complexity and volume of debug information, LLVM provides a specification for well formed debug descriptors.
Consumers of LLVM debug information expect the descriptors for program objects to start in a canonical format, but the descriptors can include additional information appended at the end that is source-language specific. All LLVM debugging information is versioned, allowing backwards compatibility in the case that the core structures need to change in some way. Also, all debugging information objects start with a tag to indicate what type of object it is. The source-language is allowed to define its own objects, by using unreserved tag numbers. We recommend using with tags in the range 0x1000 through 0x2000 (there is a defined enum DW_TAG_user_base = 0x1000.)
The fields of debug descriptors used internally by LLVM are restricted to only the simple data types i32, i1, float, double, mdstring and mdnode.
!1 = metadata !{ i32, ;; A tag ... }
The details of the various descriptors follow.
!0 = metadata !{ i32, ;; Tag = 17 + LLVMDebugVersion ;; (DW_TAG_compile_unit) i32, ;; Unused field. i32, ;; DWARF language identifier (ex. DW_LANG_C89) metadata, ;; Source file name metadata, ;; Source file directory (includes trailing slash) metadata ;; Producer (ex. "4.0.1 LLVM (LLVM research group)") i1, ;; True if this is a main compile unit. i1, ;; True if this is optimized. metadata, ;; Flags i32 ;; Runtime version metadata ;; List of enums types metadata ;; List of retained types metadata ;; List of subprograms metadata ;; List of global variables }
These descriptors contain a source language ID for the file (we use the DWARF 3.0 ID numbers, such as DW_LANG_C89, DW_LANG_C_plus_plus, DW_LANG_Cobol74, etc), three strings describing the filename, working directory of the compiler, and an identifier string for the compiler that produced it.
Compile unit descriptors provide the root context for objects declared in a specific compilation unit. File descriptors are defined using this context. These descriptors are collected by a named metadata !llvm.dbg.cu. Compile unit descriptor keeps track of subprograms, global variables and type information.
!0 = metadata !{ i32, ;; Tag = 41 + LLVMDebugVersion ;; (DW_TAG_file_type) metadata, ;; Source file name metadata, ;; Source file directory (includes trailing slash) metadata ;; Unused }
These descriptors contain information for a file. Global variables and top level functions would be defined using this context.k File descriptors also provide context for source line correspondence.
Each input file is encoded as a separate file descriptor in LLVM debugging information output.
!1 = metadata !{ i32, ;; Tag = 52 + LLVMDebugVersion ;; (DW_TAG_variable) i32, ;; Unused field. metadata, ;; Reference to context descriptor metadata, ;; Name metadata, ;; Display name (fully qualified C++ name) metadata, ;; MIPS linkage name (for C++) metadata, ;; Reference to file where defined i32, ;; Line number where defined metadata, ;; Reference to type descriptor i1, ;; True if the global is local to compile unit (static) i1, ;; True if the global is defined in the compile unit (not extern) {}* ;; Reference to the global variable }
These descriptors provide debug information about globals variables. The provide details such as name, type and where the variable is defined. All global variables are collected inside the named metadata !llvm.dbg.cu.
!2 = metadata !{ i32, ;; Tag = 46 + LLVMDebugVersion ;; (DW_TAG_subprogram) i32, ;; Unused field. metadata, ;; Reference to context descriptor metadata, ;; Name metadata, ;; Display name (fully qualified C++ name) metadata, ;; MIPS linkage name (for C++) metadata, ;; Reference to file where defined i32, ;; Line number where defined metadata, ;; Reference to type descriptor i1, ;; True if the global is local to compile unit (static) i1, ;; True if the global is defined in the compile unit (not extern) i32, ;; Line number where the scope of the subprogram begins i32, ;; Virtuality, e.g. dwarf::DW_VIRTUALITY__virtual i32, ;; Index into a virtual function metadata, ;; indicates which base type contains the vtable pointer for the ;; derived class i32, ;; Flags - Artifical, Private, Protected, Explicit, Prototyped. i1, ;; isOptimized Function *,;; Pointer to LLVM function metadata, ;; Lists function template parameters metadata ;; Function declaration descriptor metadata ;; List of function variables }
These descriptors provide debug information about functions, methods and subprograms. They provide details such as name, return types and the source location where the subprogram is defined.
!3 = metadata !{ i32, ;; Tag = 11 + LLVMDebugVersion (DW_TAG_lexical_block) metadata,;; Reference to context descriptor i32, ;; Line number i32, ;; Column number metadata,;; Reference to source file i32 ;; Unique ID to identify blocks from a template function }
This descriptor provides debug information about nested blocks within a subprogram. The line number and column numbers are used to dinstinguish two lexical blocks at same depth.
!3 = metadata !{ i32, ;; Tag = 11 + LLVMDebugVersion (DW_TAG_lexical_block) metadata ;; Reference to the scope we're annotating with a file change metadata,;; Reference to the file the scope is enclosed in. }
This descriptor provides a wrapper around a lexical scope to handle file changes in the middle of a lexical block.
!4 = metadata !{ i32, ;; Tag = 36 + LLVMDebugVersion ;; (DW_TAG_base_type) metadata, ;; Reference to context metadata, ;; Name (may be "" for anonymous types) metadata, ;; Reference to file where defined (may be NULL) i32, ;; Line number where defined (may be 0) i64, ;; Size in bits i64, ;; Alignment in bits i64, ;; Offset in bits i32, ;; Flags i32 ;; DWARF type encoding }
These descriptors define primitive types used in the code. Example int, bool and float. The context provides the scope of the type, which is usually the top level. Since basic types are not usually user defined the context and line number can be left as NULL and 0. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a composite type (example to keep float doubles on 64 bit boundaries.) The offset is the bit offset if embedded in a composite type.
The type encoding provides the details of the type. The values are typically one of the following:
DW_ATE_address = 1 DW_ATE_boolean = 2 DW_ATE_float = 4 DW_ATE_signed = 5 DW_ATE_signed_char = 6 DW_ATE_unsigned = 7 DW_ATE_unsigned_char = 8
!5 = metadata !{ i32, ;; Tag (see below) metadata, ;; Reference to context metadata, ;; Name (may be "" for anonymous types) metadata, ;; Reference to file where defined (may be NULL) i32, ;; Line number where defined (may be 0) i64, ;; Size in bits i64, ;; Alignment in bits i64, ;; Offset in bits i32, ;; Flags to encode attributes, e.g. private metadata, ;; Reference to type derived from metadata, ;; (optional) Name of the Objective C property associated with ;; Objective-C an ivar metadata, ;; (optional) Name of the Objective C property getter selector. metadata, ;; (optional) Name of the Objective C property setter selector. i32 ;; (optional) Objective C property attributes. }
These descriptors are used to define types derived from other types. The value of the tag varies depending on the meaning. The following are possible tag values:
DW_TAG_formal_parameter = 5 DW_TAG_member = 13 DW_TAG_pointer_type = 15 DW_TAG_reference_type = 16 DW_TAG_typedef = 22 DW_TAG_const_type = 38 DW_TAG_volatile_type = 53 DW_TAG_restrict_type = 55
DW_TAG_member is used to define a member of a composite type or subprogram. The type of the member is the derived type. DW_TAG_formal_parameter is used to define a member which is a formal argument of a subprogram.
DW_TAG_typedef is used to provide a name for the derived type.
DW_TAG_pointer_type, DW_TAG_reference_type, DW_TAG_const_type, DW_TAG_volatile_type and DW_TAG_restrict_type are used to qualify the derived type.
Derived type location can be determined from the context and line number. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a composite type (example to keep float doubles on 64 bit boundaries.) The offset is the bit offset if embedded in a composite type.
Note that the void * type is expressed as a type derived from NULL.
!6 = metadata !{ i32, ;; Tag (see below) metadata, ;; Reference to context metadata, ;; Name (may be "" for anonymous types) metadata, ;; Reference to file where defined (may be NULL) i32, ;; Line number where defined (may be 0) i64, ;; Size in bits i64, ;; Alignment in bits i64, ;; Offset in bits i32, ;; Flags metadata, ;; Reference to type derived from metadata, ;; Reference to array of member descriptors i32 ;; Runtime languages }
These descriptors are used to define types that are composed of 0 or more elements. The value of the tag varies depending on the meaning. The following are possible tag values:
DW_TAG_array_type = 1 DW_TAG_enumeration_type = 4 DW_TAG_structure_type = 19 DW_TAG_union_type = 23 DW_TAG_vector_type = 259 DW_TAG_subroutine_type = 21 DW_TAG_inheritance = 28
The vector flag indicates that an array type is a native packed vector.
The members of array types (tag = DW_TAG_array_type) or vector types (tag = DW_TAG_vector_type) are subrange descriptors, each representing the range of subscripts at that level of indexing.
The members of enumeration types (tag = DW_TAG_enumeration_type) are enumerator descriptors, each representing the definition of enumeration value for the set. All enumeration type descriptors are collected inside the named metadata !llvm.dbg.cu.
The members of structure (tag = DW_TAG_structure_type) or union (tag = DW_TAG_union_type) types are any one of the basic, derived or composite type descriptors, each representing a field member of the structure or union.
For C++ classes (tag = DW_TAG_structure_type), member descriptors provide information about base classes, static members and member functions. If a member is a derived type descriptor and has a tag of DW_TAG_inheritance, then the type represents a base class. If the member of is a global variable descriptor then it represents a static member. And, if the member is a subprogram descriptor then it represents a member function. For static members and member functions, getName() returns the members link or the C++ mangled name. getDisplayName() the simplied version of the name.
The first member of subroutine (tag = DW_TAG_subroutine_type) type elements is the return type for the subroutine. The remaining elements are the formal arguments to the subroutine.
Composite type location can be determined from the context and line number. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a composite type (as an example, to keep float doubles on 64 bit boundaries.) The offset is the bit offset if embedded in a composite type.
!42 = metadata !{ i32, ;; Tag = 33 + LLVMDebugVersion (DW_TAG_subrange_type) i64, ;; Low value i64 ;; High value }
These descriptors are used to define ranges of array subscripts for an array composite type. The low value defines the lower bounds typically zero for C/C++. The high value is the upper bounds. Values are 64 bit. High - low + 1 is the size of the array. If low > high the array bounds are not included in generated debugging information.
!6 = metadata !{ i32, ;; Tag = 40 + LLVMDebugVersion ;; (DW_TAG_enumerator) metadata, ;; Name i64 ;; Value }
These descriptors are used to define members of an enumeration composite type, it associates the name to the value.
!7 = metadata !{ i32, ;; Tag (see below) metadata, ;; Context metadata, ;; Name metadata, ;; Reference to file where defined i32, ;; 24 bit - Line number where defined ;; 8 bit - Argument number. 1 indicates 1st argument. metadata, ;; Type descriptor i32, ;; flags metadata ;; (optional) Reference to inline location }
These descriptors are used to define variables local to a sub program. The value of the tag depends on the usage of the variable:
DW_TAG_auto_variable = 256 DW_TAG_arg_variable = 257 DW_TAG_return_variable = 258
An auto variable is any variable declared in the body of the function. An argument variable is any variable that appears as a formal argument to the function. A return variable is used to track the result of a function and has no source correspondent.
The context is either the subprogram or block where the variable is defined. Name the source variable name. Context and line indicate where the variable was defined. Type descriptor defines the declared type of the variable.
LLVM uses several intrinsic functions (name prefixed with "llvm.dbg") to provide debug information at various points in generated code.
void %llvm.dbg.declare(metadata, metadata)
This intrinsic provides information about a local element (e.g., variable). The first argument is metadata holding the alloca for the variable. The second argument is metadata containing a description of the variable.
void %llvm.dbg.value(metadata, i64, metadata)
This intrinsic provides information when a user source variable is set to a new value. The first argument is the new value (wrapped as metadata). The second argument is the offset in the user source variable where the new value is written. The third argument is metadata containing a description of the user source variable.
In many languages, the local variables in functions can have their lifetimes or scopes limited to a subset of a function. In the C family of languages, for example, variables are only live (readable and writable) within the source block that they are defined in. In functional languages, values are only readable after they have been defined. Though this is a very obvious concept, it is non-trivial to model in LLVM, because it has no notion of scoping in this sense, and does not want to be tied to a language's scoping rules.
In order to handle this, the LLVM debug format uses the metadata attached to llvm instructions to encode line number and scoping information. Consider the following C fragment, for example:
1. void foo() { 2. int X = 21; 3. int Y = 22; 4. { 5. int Z = 23; 6. Z = X; 7. } 8. X = Y; 9. }
Compiled to LLVM, this function would be represented like this:
define void @foo() nounwind ssp { entry: %X = alloca i32, align 4 ; <i32*> [#uses=4] %Y = alloca i32, align 4 ; <i32*> [#uses=4] %Z = alloca i32, align 4 ; <i32*> [#uses=3] %0 = bitcast i32* %X to {}* ; <{}*> [#uses=1] call void @llvm.dbg.declare(metadata !{i32 * %X}, metadata !0), !dbg !7 store i32 21, i32* %X, !dbg !8 %1 = bitcast i32* %Y to {}* ; <{}*> [#uses=1] call void @llvm.dbg.declare(metadata !{i32 * %Y}, metadata !9), !dbg !10 store i32 22, i32* %Y, !dbg !11 %2 = bitcast i32* %Z to {}* ; <{}*> [#uses=1] call void @llvm.dbg.declare(metadata !{i32 * %Z}, metadata !12), !dbg !14 store i32 23, i32* %Z, !dbg !15 %tmp = load i32* %X, !dbg !16 ; <i32> [#uses=1] %tmp1 = load i32* %Y, !dbg !16 ; <i32> [#uses=1] %add = add nsw i32 %tmp, %tmp1, !dbg !16 ; <i32> [#uses=1] store i32 %add, i32* %Z, !dbg !16 %tmp2 = load i32* %Y, !dbg !17 ; <i32> [#uses=1] store i32 %tmp2, i32* %X, !dbg !17 ret void, !dbg !18 } declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone !0 = metadata !{i32 459008, metadata !1, metadata !"X", metadata !3, i32 2, metadata !6}; [ DW_TAG_auto_variable ] !1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ] !2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"foo", metadata !"foo", metadata !"foo", metadata !3, i32 1, metadata !4, i1 false, i1 true}; [DW_TAG_subprogram ] !3 = metadata !{i32 458769, i32 0, i32 12, metadata !"foo.c", metadata !"/private/tmp", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ] !4 = metadata !{i32 458773, metadata !3, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0}; [DW_TAG_subroutine_type ] !5 = metadata !{null} !6 = metadata !{i32 458788, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ] !7 = metadata !{i32 2, i32 7, metadata !1, null} !8 = metadata !{i32 2, i32 3, metadata !1, null} !9 = metadata !{i32 459008, metadata !1, metadata !"Y", metadata !3, i32 3, metadata !6}; [ DW_TAG_auto_variable ] !10 = metadata !{i32 3, i32 7, metadata !1, null} !11 = metadata !{i32 3, i32 3, metadata !1, null} !12 = metadata !{i32 459008, metadata !13, metadata !"Z", metadata !3, i32 5, metadata !6}; [ DW_TAG_auto_variable ] !13 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ] !14 = metadata !{i32 5, i32 9, metadata !13, null} !15 = metadata !{i32 5, i32 5, metadata !13, null} !16 = metadata !{i32 6, i32 5, metadata !13, null} !17 = metadata !{i32 8, i32 3, metadata !1, null} !18 = metadata !{i32 9, i32 1, metadata !2, null}
This example illustrates a few important details about LLVM debugging information. In particular, it shows how the llvm.dbg.declare intrinsic and location information, which are attached to an instruction, are applied together to allow a debugger to analyze the relationship between statements, variable definitions, and the code used to implement the function.
call void @llvm.dbg.declare(metadata, metadata !0), !dbg !7
The first intrinsic %llvm.dbg.declare encodes debugging information for the variable X. The metadata !dbg !7 attached to the intrinsic provides scope information for the variable X.
!7 = metadata !{i32 2, i32 7, metadata !1, null} !1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ] !2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"foo", metadata !"foo", metadata !"foo", metadata !3, i32 1, metadata !4, i1 false, i1 true}; [DW_TAG_subprogram ]
Here !7 is metadata providing location information. It has four fields: line number, column number, scope, and original scope. The original scope represents inline location if this instruction is inlined inside a caller, and is null otherwise. In this example, scope is encoded by !1. !1 represents a lexical block inside the scope !2, where !2 is a subprogram descriptor. This way the location information attached to the intrinsics indicates that the variable X is declared at line number 2 at a function level scope in function foo.
Now lets take another example.
call void @llvm.dbg.declare(metadata, metadata !12), !dbg !14
The second intrinsic %llvm.dbg.declare encodes debugging information for variable Z. The metadata !dbg !14 attached to the intrinsic provides scope information for the variable Z.
!13 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ] !14 = metadata !{i32 5, i32 9, metadata !13, null}
Here !14 indicates that Z is declared at line number 5 and column number 9 inside of lexical scope !13. The lexical scope itself resides inside of lexical scope !1 described above.
The scope information attached with each instruction provides a straightforward way to find instructions covered by a scope.
The C and C++ front-ends represent information about the program in a format that is effectively identical to DWARF 3.0 in terms of information content. This allows code generators to trivially support native debuggers by generating standard dwarf information, and contains enough information for non-dwarf targets to translate it as needed.
This section describes the forms used to represent C and C++ programs. Other languages could pattern themselves after this (which itself is tuned to representing programs in the same way that DWARF 3 does), or they could choose to provide completely different forms if they don't fit into the DWARF model. As support for debugging information gets added to the various LLVM source-language front-ends, the information used should be documented here.
The following sections provide examples of various C/C++ constructs and the debug information that would best describe those constructs.
Given the source files MySource.cpp and MyHeader.h located in the directory /Users/mine/sources, the following code:
#include "MyHeader.h" int main(int argc, char *argv[]) { return 0; }
a C/C++ front-end would generate the following descriptors:
...  One can extract line number information encoded in LLVM IR using Instruction::getMetadata() and DILocation::getLineNumber().
if (MDNode *N = I->getMetadata("dbg")) { // Here I is an LLVM instruction DILocation Loc(N); // DILocation is in DebugInfo.h unsigned Line = Loc.getLineNumber(); StringRef File = Loc.getFilename(); StringRef Dir = Loc.getDirectory(); }
Given an integer global variable declared as follows:
int MyGlobal = 100;
a C/C++ front-end would generate the following descriptors:
;; ;; Define the global itself. ;; %MyGlobal = global int 100 ...  Note that the second field of the ;; anchor is 46, which is the same as the tag for subprograms ;; (46 = DW_TAG_subprogram.) ;; !6 = metadata !{ i32 524334, ;; Tag i32 0, ;; Unused metadata !1, ;; Context metadata !"main", ;; Name metadata !"main", ;; Display name metadata !"main", ;; Linkage name metadata !1, ;; File i32 1, ;; Line number metadata !4, ;; Type i1 false, ;; Is local i1 true, ;; Is definition i32 0, ;; Virtuality attribute, e.g. pure virtual function i32 0, ;; Index into virtual table for C++ methods i32 0, ;; Type that holds virtual table. i32 0, ;; Flags i1 false, ;; True if this function is optimized Function *, ;; Pointer to llvm::Function null ;; Function template parameters } ;; ;; Define the subprogram itself. ;; define i32 @main(i32 %argc, i8** %argv) { ...  The language provides features to declare a property and to let compiler synthesize accessor methods.
The debugger lets developer inspect Objective C interfaces and their instance variables and class variables. However, the debugger does not know anything about the properties defined in Objective C interfaces. The debugger consumes information generated by compiler in DWARF format. The format does not support encoding of Objective C properties. This proposal describes DWARF extensions to encode Objective C properties, which the debugger can use to let developers inspect Objective C properties.
Objective C properties exist separately from class members. A property can be defined only by "setter" and "getter" selectors, and be calculated anew on each access. Or a property can just be a direct access to some declared ivar. Finally it can have an ivar "automatically synthesized" for it by the compiler, in which case the property can be referred to in user code directly using the standard C dereference syntax as well as through the property "dot" syntax, but there is no entry in the @interface declaration corresponding to this ivar.
To facilitate debugging, these properties we will add a new DWARF TAG into the DW_TAG_structure_type definition for the class to hold the description of a given property, and a set of DWARF attributes that provide said description. The property tag will also contain the name and declared type of the property.
If there is a related ivar, there will also be a DWARF property attribute placed in the DW_TAG_member DIE for that ivar referring back to the property TAG for that property. And in the case where the compiler synthesizes the ivar directly, the compiler is expected to generate a DW_TAG_member for that ivar (with the DW_AT_artificial set to 1), whose name will be the name used to access this ivar directly in code, and with the property attribute pointing back to the property it is backing.
The following examples will serve as illustration for our discussion:
@interface I1 { int n2; } @property int p1; @property int p2; @end @implementation I1 @synthesize p1; @synthesize p2 = n2; @end
This produces the following DWARF (this is a "pseudo dwarfdump" output):
0x00000100: TAG_structure_type [7] * AT_APPLE_runtime_class( 0x10 ) AT_name( "I1" ) AT_decl_file( "Objc_Property.m" ) AT_decl_line( 3 ) 0x00000110 TAG_APPLE_property AT_name ( "p1" ) AT_type ( {0x00000150} ( int ) ) 0x00000120: TAG_APPLE_property AT_name ( "p2" ) AT_type ( {0x00000150} ( int ) ) 0x00000130: TAG_member [8] AT_name( "_p1" ) AT_APPLE_property ( {0x00000110} "p1" ) AT_type( {0x00000150} ( int ) ) AT_artificial ( 0x1 ) 0x00000140: TAG_member [8] AT_name( "n2" ) AT_APPLE_property ( {0x00000120} "p2" ) AT_type( {0x00000150} ( int ) ) 0x00000150: AT_type( ( int ) )
Note, the current convention is that the name of the ivar for an auto-synthesized property is the name of the property from which it derives with an underscore prepended, as is shown in the example. But we actually don't need to know this convention, since we are given the name of the ivar directly.
Also, it is common practice in ObjC to have different property declarations in the @interface and @implementation - e.g. to provide a read-only property in the interface,and a read-write interface in the implementation. In that case, the compiler should emit whichever property declaration will be in force in the current translation unit.
Developers can decorate a property with attributes which are encoded using DW_AT_APPLE_property_attribute.
@property (readonly, nonatomic) int pr;
Which produces a property tag:
TAG_APPLE_property [8] AT_name( "pr" ) AT_type ( {0x00000147} (int) ) AT_APPLE_property_attribute (DW_APPLE_PROPERTY_readonly, DW_APPLE_PROPERTY_nonatomic)
The setter and getter method names are attached to the property using DW_AT_APPLE_property_setter and DW_AT_APPLE_property_getter attributes.
@interface I1 @property (setter=myOwnP3Setter:) int p3; -(void)myOwnP3Setter:(int)a; @end @implementation I1 @synthesize p3; -(void)myOwnP3Setter:(int)a{ } @end
The DWARF for this would be:
0x000003bd: TAG_structure_type [7] * AT_APPLE_runtime_class( 0x10 ) AT_name( "I1" ) AT_decl_file( "Objc_Property.m" ) AT_decl_line( 3 ) 0x000003cd TAG_APPLE_property AT_name ( "p3" ) AT_APPLE_property_setter ( "myOwnP3Setter:" ) AT_type( {0x00000147} ( int ) ) 0x000003f3: TAG_member [8] AT_name( "_p3" ) AT_type ( {0x00000147} ( int ) ) AT_APPLE_property ( {0x000003cd} ) AT_artificial ( 0x1 )
| TAG | Value |
|---|---|
| DW_TAG_APPLE_property | 0x4200 |
| Attribute | Value | Classes |
|---|---|---|
| DW_AT_APPLE_property | 0x3fed | Reference |
| DW_AT_APPLE_property_getter | 0x3fe9 | String |
| DW_AT_APPLE_property_setter | 0x3fea | String |
| DW_AT_APPLE_property_attribute | 0x3feb | Constant |
| Name | Value |
|---|---|
| DW_AT_APPLE_PROPERTY_readonly | 0x1 |
| DW_AT_APPLE_PROPERTY_readwrite | 0x2 |
| DW_AT_APPLE_PROPERTY_assign | 0x4 |
| DW_AT_APPLE_PROPERTY_retain | 0x8 |
| DW_AT_APPLE_PROPERTY_copy | 0x10 |
| DW_AT_APPLE_PROPERTY_nonatomic | 0x20 |
The .debug_pubnames and .debug_pubtypes formats are not what a debugger needs. The "pub" in the section name indicates that the entries in the table are publicly visible names only. This means no static or hidden functions show up in the .debug_pubnames. No static variables or private class variables are in the .debug_pubtypes. Many compilers add different things to these tables, so we can't rely upon the contents between gcc, icc, or clang.
The typical query given by users tends not to match up with the contents of these tables. For example, the DWARF spec states that "In the case of the name of a function member or static data member of a C++ structure, class or union, the name presented in the .debug_pubnames section is not the simple name given by the DW_AT_name attribute of the referenced debugging information entry, but rather the fully qualified name of the data or function member." So the only names in these tables for complex C++ entries is a fully qualified name. Debugger users tend not to enter their search strings as "a::b::c(int,const Foo&) const", but rather as "c", "b::c" , or "a::b::c". So the name entered in the name table must be demangled in order to chop it up appropriately and additional names must be manually entered into the table to make it effective as a name lookup table for debuggers to use.
All debuggers currently ignore the .debug_pubnames table as a result of its inconsistent and useless public-only name content making it a waste of space in the object file. These tables, when they are written to disk, are not sorted in any way, leaving every debugger to do its own parsing and sorting. These tables also include an inlined copy of the string values in the table itself making the tables much larger than they need to be on disk, especially for large C++ programs.
Can't we just fix the sections by adding all of the names we need to this table? No, because that is not what the tables are defined to contain and we won't know the difference between the old bad tables and the new good tables. At best we could make our own renamed sections that contain all of the data we need.
These tables are also insufficient for what a debugger like LLDB needs. LLDB uses clang for its expression parsing where LLDB acts as a PCH. LLDB is then often asked to look for type "foo" or namespace "bar", or list items in namespace "baz". Namespaces are not included in the pubnames or pubtypes tables. Since clang asks a lot of questions when it is parsing an expression, we need to be very fast when looking up names, as it happens a lot. Having new accelerator tables that are optimized for very quick lookups will benefit this type of debugging experience greatly.
We would like to generate name lookup tables that can be mapped into memory from disk, and used as is, with little or no up-front parsing. We would also be able to control the exact content of these different tables so they contain exactly what we need. The Name Accelerator Tables were designed to fix these issues. In order to solve these issues we need to:
Table size is important and the accelerator table format should allow the reuse of strings from common string tables so the strings for the names are not duplicated. We also want to make sure the table is ready to be used as-is by simply mapping the table into memory with minimal header parsing.
The name lookups need to be fast and optimized for the kinds of lookups that debuggers tend to do. Optimally we would like to touch as few parts of the mapped table as possible when doing a name lookup and be able to quickly find the name entry we are looking for, or discover there are no matches. In the case of debuggers we optimized for lookups that fail most of the time.
Each table that is defined should have strict rules on exactly what is in the accelerator tables and documented so clients can rely on the content.
Typical hash tables have a header, buckets, and each bucket points to the bucket contents:
.------------. | HEADER | |------------| | BUCKETS | |------------| | DATA | `------------'
The BUCKETS are an array of offsets to DATA for each hash:
.------------. | 0x00001000 | BUCKETS[0] | 0x00002000 | BUCKETS[1] | 0x00002200 | BUCKETS[2] | 0x000034f0 | BUCKETS[3] | | ... | 0xXXXXXXXX | BUCKETS[n_buckets] '------------'
So for bucket[3] in the example above, we have an offset into the table 0x000034f0 which points to a chain of entries for the bucket. Each bucket must contain a next pointer, full 32 bit hash value, the string itself, and the data for the current string value.
.------------. 0x000034f0: | 0x00003500 | next pointer | 0x12345678 | 32 bit hash | "erase" | string value | data[n] | HashData for this bucket |------------| 0x00003500: | 0x00003550 | next pointer | 0x29273623 | 32 bit hash | "dump" | string value | data[n] | HashData for this bucket |------------| 0x00003550: | 0x00000000 | next pointer | 0x82638293 | 32 bit hash | "main" | string value | data[n] | HashData for this bucket `------------'
The problem with this layout for debuggers is that we need to optimize for the negative lookup case where the symbol we're searching for is not present. So if we were to lookup "printf" in the table above, we would make a 32 hash for "printf", it might match bucket[3]. We would need to go to the offset 0x000034f0 and start looking to see if our 32 bit hash matches. To do so, we need to read the next pointer, then read the hash, compare it, and skip to the next bucket. Each time we are skipping many bytes in memory and touching new cache pages just to do the compare on the full 32 bit hash. All of these accesses then tell us that we didn't have a match.
To solve the issues mentioned above we have structured the hash tables a bit differently: a header, buckets, an array of all unique 32 bit hash values, followed by an array of hash value data offsets, one for each hash value, then the data for all hash values:
.-------------. | HEADER | |-------------| | BUCKETS | |-------------| | HASHES | |-------------| | OFFSETS | |-------------| | DATA | `-------------'
The BUCKETS in the name tables are an index into the HASHES array. By making all of the full 32 bit hash values contiguous in memory, we allow ourselves to efficiently check for a match while touching as little memory as possible. Most often checking the 32 bit hash values is as far as the lookup goes. If it does match, it usually is a match with no collisions. So for a table with "n_buckets" buckets, and "n_hashes" unique 32 bit hash values, we can clarify the contents of the BUCKETS, HASHES and OFFSETS as:
.-------------------------. | HEADER.magic | uint32_t | HEADER.version | uint16_t | HEADER.hash_function | uint16_t | HEADER.bucket_count | uint32_t | HEADER.hashes_count | uint32_t | HEADER.header_data_len | uint32_t | HEADER_DATA | HeaderData |-------------------------| | BUCKETS | uint32_t[n_buckets] // 32 bit hash indexes |-------------------------| | HASHES | uint32_t[n_buckets] // 32 bit hash values |-------------------------| | OFFSETS | uint32_t[n_buckets] // 32 bit offsets to hash value data |-------------------------| | ALL HASH DATA | `-------------------------'
So taking the exact same data from the standard hash example above we end up with:
.------------. | HEADER | |------------| | 0 | BUCKETS[0] | 2 | BUCKETS[1] | 5 | BUCKETS[2] | 6 | BUCKETS[3] | | ... | ... | BUCKETS[n_buckets] |------------| | 0x........ | HASHES[0] | 0x........ | HASHES[1] | 0x........ | HASHES[2] | 0x........ | HASHES[3] | 0x........ | HASHES[4] | 0x........ | HASHES[5] | 0x12345678 | HASHES[6] hash for BUCKETS[3] | 0x29273623 | HASHES[7] hash for BUCKETS[3] | 0x82638293 | HASHES[8] hash for BUCKETS[3] | 0x........ | HASHES[9] | 0x........ | HASHES[10] | 0x........ | HASHES[11] | 0x........ | HASHES[12] | 0x........ | HASHES[13] | 0x........ | HASHES[n_hashes] |------------| | 0x........ | OFFSETS[0] | 0x........ | OFFSETS[1] | 0x........ | OFFSETS[2] | 0x........ | OFFSETS[3] | 0x........ | OFFSETS[4] | 0x........ | OFFSETS[5] | 0x000034f0 | OFFSETS[6] offset for BUCKETS[3] | 0x00003500 | OFFSETS[7] offset for BUCKETS[3] | 0x00003550 | OFFSETS[8] offset for BUCKETS[3] | 0x........ | OFFSETS[9] | 0x........ | OFFSETS[10] | 0x........ | OFFSETS[11] | 0x........ | OFFSETS[12] | 0x........ | OFFSETS[13] | 0x........ | OFFSETS[n_hashes] |------------| | | | | | | | | | | |------------| 0x000034f0: | 0x00001203 | .debug_str ("erase") | 0x00000004 | A 32 bit array count - number of HashData with name "erase" | 0x........ | HashData[0] | 0x........ | HashData[1] | 0x........ | HashData[2] | 0x........ | HashData[3] | 0x00000000 | String offset into .debug_str (terminate data for hash) |------------| 0x00003500: | 0x00001203 | String offset into .debug_str ("collision") | 0x00000002 | A 32 bit array count - number of HashData with name "collision" | 0x........ | HashData[0] | 0x........ | HashData[1] | 0x00001203 | String offset into .debug_str ("dump") | 0x00000003 | A 32 bit array count - number of HashData with name "dump" | 0x........ | HashData[0] | 0x........ | HashData[1] | 0x........ | HashData[2] | 0x00000000 | String offset into .debug_str (terminate data for hash) |------------| 0x00003550: | 0x00001203 | String offset into .debug_str ("main") | 0x00000009 | A 32 bit array count - number of HashData with name "main" | 0x........ | HashData[0] | 0x........ | HashData[1] | 0x........ | HashData[2] | 0x........ | HashData[3] | 0x........ | HashData[4] | 0x........ | HashData[5] | 0x........ | HashData[6] | 0x........ | HashData[7] | 0x........ | HashData[8] | 0x00000000 | String offset into .debug_str (terminate data for hash) `------------'
So we still have all of the same data, we just organize it more efficiently for debugger lookup. If we repeat the same "printf" lookup from above, we would hash "printf" and find it matches BUCKETS[3] by taking the 32 bit hash value and modulo it by n_buckets. BUCKETS[3] contains "6" which is the index into the HASHES table. We would then compare any consecutive 32 bit hashes values in the HASHES array as long as the hashes would be in BUCKETS[3]. We do this by verifying that each subsequent hash value modulo n_buckets is still 3. In the case of a failed lookup we would access the memory for BUCKETS[3], and then compare a few consecutive 32 bit hashes before we know that we have no match. We don't end up marching through multiple words of memory and we really keep the number of processor data cache lines being accessed as small as possible.
The string hash that is used for these lookup tables is the Daniel J. Bernstein hash which is also used in the ELF GNU_HASH sections. It is a very good hash for all kinds of names in programs with very few hash collisions.
Empty buckets are designated by using an invalid hash index of UINT32_MAX.
These name hash tables are designed to be generic where specializations of the table get to define additional data that goes into the header ("HeaderData"), how the string value is stored ("KeyType") and the content of the data for each hash value.
The header has a fixed part, and the specialized part. The exact format of the header is:
struct Header { uint32_t magic; // 'HASH' magic value to allow endian detection uint16_t version; // Version number uint16_t hash_function; // The hash function enumeration that was used uint32_t bucket_count; // The number of buckets in this hash table uint32_t hashes_count; // The total number of unique hash values and hash data offsets in this table uint32_t header_data_len; // The bytes to skip to get to the hash indexes (buckets) for correct alignment // Specifically the length of the following HeaderData field - this does not // include the size of the preceding fields HeaderData header_data; // Implementation specific header data };
The header starts with a 32 bit "magic" value which must be 'HASH' encoded as an ASCII integer. This allows the detection of the start of the hash table and also allows the table's byte order to be determined so the table can be correctly extracted. The "magic" value is followed by a 16 bit version number which allows the table to be revised and modified in the future. The current version number is 1. "hash_function" is a uint16_t enumeration that specifies which hash function was used to produce this table. The current values for the hash function enumerations include:
enum HashFunctionType { eHashFunctionDJB = 0u, // Daniel J Bernstein hash function };
"bucket_count" is a 32 bit unsigned integer that represents how many buckets are in the BUCKETS array. "hashes_count" is the number of unique 32 bit hash values that are in the HASHES array, and is the same number of offsets are contained in the OFFSETS array. "header_data_len" specifies the size in bytes of the HeaderData that is filled in by specialized versions of this table.
The header is followed by the buckets, hashes, offsets, and hash value data.
struct FixedTable { uint32_t buckets[Header.bucket_count]; // An array of hash indexes into the "hashes[]" array below uint32_t hashes [Header.hashes_count]; // Every unique 32 bit hash for the entire table is in this table uint32_t offsets[Header.hashes_count]; // An offset that corresponds to each item in the "hashes[]" array above };
"buckets" is an array of 32 bit indexes into the "hashes" array. The "hashes" array contains all of the 32 bit hash values for all names in the hash table. Each hash in the "hashes" table has an offset in the "offsets" array that points to the data for the hash value.
This table setup makes it very easy to repurpose these tables to contain different data, while keeping the lookup mechanism the same for all tables. This layout also makes it possible to save the table to disk and map it in later and do very efficient name lookups with little or no parsing.
DWARF lookup tables can be implemented in a variety of ways and can store a lot of information for each name. We want to make the DWARF tables extensible and able to store the data efficiently so we have used some of the DWARF features that enable efficient data storage to define exactly what kind of data we store for each name.
The "HeaderData" contains a definition of the contents of each HashData chunk. We might want to store an offset to all of the debug information entries (DIEs) for each name. To keep things extensible, we create a list of items, or Atoms, that are contained in the data for each name. First comes the type of the data in each atom:
enum AtomType { eAtomTypeNULL = 0u, eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2 eAtomTypeNameFlags = 4u, // Flags from enum NameFlags eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags };
The enumeration values and their meanings are:
eAtomTypeNULL - a termination atom that specifies the end of the atom list eAtomTypeDIEOffset - an offset into the .debug_info section for the DWARF DIE for this name eAtomTypeCUOffset - an offset into the .debug_info section for the CU that contains the DIE eAtomTypeDIETag - The DW_TAG_XXX enumeration value so you don't have to parse the DWARF to see what it is eAtomTypeNameFlags - Flags for functions and global variables (isFunction, isInlined, isExternal...) eAtomTypeTypeFlags - Flags for types (isCXXClass, isObjCClass, ...)
Then we allow each atom type to define the atom type and how the data for each atom type data is encoded:
struct Atom { uint16_t type; // AtomType enum value uint16_t form; // DWARF DW_FORM_XXX defines };
The "form" type above is from the DWARF specification and defines the exact encoding of the data for the Atom type. See the DWARF specification for the DW_FORM_ definitions.
struct HeaderData { uint32_t die_offset_base; uint32_t atom_count; Atoms atoms[atom_count0]; };
"HeaderData" defines the base DIE offset that should be added to any atoms that are encoded using the DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8 or DW_FORM_ref_udata. It also defines what is contained in each "HashData" object -- Atom.form tells us how large each field will be in the HashData and the Atom.type tells us how this data should be interpreted.
For the current implementations of the ".apple_names" (all functions + globals), the ".apple_types" (names of all types that are defined), and the ".apple_namespaces" (all namespaces), we currently set the Atom array to be:
HeaderData.atom_count = 1; HeaderData.atoms[0].type = eAtomTypeDIEOffset; HeaderData.atoms[0].form = DW_FORM_data4;
This defines the contents to be the DIE offset (eAtomTypeDIEOffset) that is encoded as a 32 bit value (DW_FORM_data4). This allows a single name to have multiple matching DIEs in a single file, which could come up with an inlined function for instance. Future tables could include more information about the DIE such as flags indicating if the DIE is a function, method, block, or inlined.
The KeyType for the DWARF table is a 32 bit string table offset into the ".debug_str" table. The ".debug_str" is the string table for the DWARF which may already contain copies of all of the strings. This helps make sure, with help from the compiler, that we reuse the strings between all of the DWARF sections and keeps the hash table size down. Another benefit to having the compiler generate all strings as DW_FORM_strp in the debug info, is that DWARF parsing can be made much faster.
After a lookup is made, we get an offset into the hash data. The hash data needs to be able to deal with 32 bit hash collisions, so the chunk of data at the offset in the hash data consists of a triple:
uint32_t str_offset uint32_t hash_data_count HashData[hash_data_count]
If "str_offset" is zero, then the bucket contents are done. 99.9% of the hash data chunks contain a single item (no 32 bit hash collision):
.------------. | 0x00001023 | uint32_t KeyType (.debug_str[0x0001023] => "main") | 0x00000004 | uint32_t HashData count | 0x........ | uint32_t HashData[0] DIE offset | 0x........ | uint32_t HashData[1] DIE offset | 0x........ | uint32_t HashData[2] DIE offset | 0x........ | uint32_t HashData[3] DIE offset | 0x00000000 | uint32_t KeyType (end of hash chain) `------------'
If there are collisions, you will have multiple valid string offsets:
.------------. | 0x00001023 | uint32_t KeyType (.debug_str[0x0001023] => "main") | 0x00000004 | uint32_t HashData count | 0x........ | uint32_t HashData[0] DIE offset | 0x........ | uint32_t HashData[1] DIE offset | 0x........ | uint32_t HashData[2] DIE offset | 0x........ | uint32_t HashData[3] DIE offset | 0x00002023 | uint32_t KeyType (.debug_str[0x0002023] => "print") | 0x00000002 | uint32_t HashData count | 0x........ | uint32_t HashData[0] DIE offset | 0x........ | uint32_t HashData[1] DIE offset | 0x00000000 | uint32_t KeyType (end of hash chain) `------------'
Current testing with real world C++ binaries has shown that there is around 1 32 bit hash collision per 100,000 name entries.
As we said, we want to strictly define exactly what is included in the different tables. For DWARF, we have 3 tables: ".apple_names", ".apple_types", and ".apple_namespaces".
".apple_names" sections should contain an entry for each DWARF DIE whose DW_TAG is a DW_TAG_label, DW_TAG_inlined_subroutine, or DW_TAG_subprogram that has address attributes: DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges or DW_AT_entry_pc. It also contains DW_TAG_variable DIEs that have a DW_OP_addr in the location (global and static variables). All global and static variables should be included, including those scoped withing functions and classes. For example using the following code:
static int var = 0; void f () { static int var = 0; }
Both of the static "var" variables would be included in the table. All functions should emit both their full names and their basenames. For C or C++, the full name is the mangled name (if available) which is usually in the DW_AT_MIPS_linkage_name attribute, and the DW_AT_name contains the function basename. If global or static variables have a mangled name in a DW_AT_MIPS_linkage_name attribute, this should be emitted along with the simple name found in the DW_AT_name attribute.
".apple_types" sections should contain an entry for each DWARF DIE whose tag is one of:
Only entries with a DW_AT_name attribute are included, and the entry must not be a forward declaration (DW_AT_declaration attribute with a non-zero value). For example, using the following code:
int main () { int *b = 0; return *b; }
We get a few type DIEs:
0x00000067: TAG_base_type [5] AT_encoding( DW_ATE_signed ) AT_name( "int" ) AT_byte_size( 0x04 ) 0x0000006e: TAG_pointer_type [6] AT_type( {0x00000067} ( int ) ) AT_byte_size( 0x08 )
The DW_TAG_pointer_type is not included because it does not have a DW_AT_name.
".apple_namespaces" section should contain all DW_TAG_namespace DIEs. If we run into a namespace that has no name this is an anonymous namespace, and the name should be output as "(anonymous namespace)" (without the quotes). Why? This matches the output of the abi::cxa_demangle() that is in the standard C++ library that demangles mangled names.
".apple_objc" section should contain all DW_TAG_subprogram DIEs for an Objective-C class. The name used in the hash table is the name of the Objective-C class itself. If the Objective-C class has a category, then an entry is made for both the class name without the category, and for the class name with the category. So if we have a DIE at offset 0x1234 with a name of method "-[NSString(my_additions) stringWithSpecialString:]", we would add an entry for "NSString" that points to DIE 0x1234, and an entry for "NSString(my_additions)" that points to 0x1234. This allows us to quickly track down all Objective-C methods for an Objective-C class when doing expressions. It is needed because of the dynamic nature of Objective-C where anyone can add methods to a class. The DWARF for Objective-C methods is also emitted differently from C++ classes where the methods are not usually contained in the class definition, they are scattered about across one or more compile units. Categories can also be defined in different shared libraries. So we need to be able to quickly find all of the methods and class functions given the Objective-C class name, or quickly find all methods and class functions for a class + category name. This table does not contain any selector names, it just maps Objective-C class names (or class names + category) to all of the methods and class functions. The selectors are added as function basenames in the .debug_names section.
In the ".apple_names" section for Objective-C functions, the full name is the entire function name with the brackets ("-[NSString stringWithCString:]") and the basename is the selector only ("stringWithCString:").
The sections names for the apple hash tables are for non mach-o files. For mach-o files, the sections should be contained in the "__DWARF" segment with names as follows:


What a Web Page is
A web page is a text document written in a language called HTML. Web browsers read these documents, and then interpret and display them.
How Coding Works
Coding happens when programmers write text in a language that a computer can understand. The computer can then follow the instructions the programmer wrote.
Computers are Stupid
Programmers need to write exactly the way a computer understands (also known as writing with correct "syntax").For example, if you forget to close a tag, the computer won't be able to figure out what you had intended.. This "stupidity" can be very frustrating, but it also gives programmers incredible power: if you know how to talk to a computer than you can tell it to do anything you want.
 And that's okay. If you forget how to make text italic in HTML, you can always just look it up.
Basic HTML Vocabulary
Tag: An HTML tag is always contained within angled brackets. Most tags have an opening tag and a closing tag, Some tags (called "void" tags) do not require a closing tag.em>
Element: An HTML element refers to everything within a set of opening and closing tags.
Attribute: This is a property of an HTML element.
Inline vs Block Elements
HTML elements are either inline or block. Block elements form an "invisible box" around the content inside of them.
HTML: HyperText Markup Language - the standard markup language used to create web pages.
CSS: Cascading Style Sheets - style sheet language used for describing the look and formatting of a document written in a markup language.
DOM: Document Object Model - a cross-platform and language-independent convention for representing and interacting with objects in HTML (and other markup languages). The nodes of every document are organized in a tree structure, called the DOM tree.
HTML and CSS are both "languages"
HTML controls the "structure" of a web page
CSS controls the "style" of a page (how it looks).
When programmers talk about the "DOM" (Document Object Model) they are talking about the tree-like structure of a page.
Text Editor is a program that helps you type text similar to document editors, such as Microsoft Word or Corel WordPerfect, but without all the extra formatting functions that document editors have.
Methods to include CSS Styling in a web page:
Method 1: write CSS in the "head" of your HTML - good for small projects
Method 2: Link your HTML to a separate CSS file - best for large projects
For Example: the CSS would be in a file called something like style.css that is referenced from an HTML document called something like index.html. They are separate files, which is the great thing about CSS, keeping the design away from the document.
Method 3: Write your style inline with your HTML - not recommended
Avoiding Repetitive Coding:
A programmer can avoid risk of errors by avoiding repetition. Repetition can cause problems if a programmer needs to make a change and fails to make the same change everywhere the code is written. Additionally, repetition is time consuming. One example where CSS helps avoid repetition, is by allowing the programmer to assign containers a class attribute and then specify the style in one place.
Inheritance is a key feature in CSS, it relies on the ancestor-descendant relationship to operate. Inheritance is the mechanism by which properties are applied not only to a specified element, but also to its descendants. Inheritance relies on the document tree, which is the hierarchy of (X)HTML elements in a page based on nesting. Descendant elements may inherit CSS property values from any ancestor element enclosing them. In general, descendant elements inherit text-related properties, but box-related properties are not inherited. Properties that can be inherited are color, font, letter-spacing, line-height, list-style, text-align, text-indent, text-transform, visibility, white-space and word-spacing. Properties that cannot be inherited are background, border, display, float and clear, height and width, margin, min- and max-height and -width, outline, overflow, padding, position, text-decoration, vertical-align and z-index.
Inheritance prevents certain properties from being declared over and over again in a style sheet, allowing the software developers to write less CSS. It enhances faster-loading of web pages by users and enables the clients to save money on bandwidth and development costs.
Selectors:
The biggest key to understanding CSS is understanding selectors. Selectors are what allows you to target specific HTML elements and apply style to them.
Semantic Tags:
The tag's element name determines both the semantic meaning of the content and the default style rules applied to it.
Code, Test, Refine


In a MacHg Document Window the left sidebar is always visible and contains a list of repository references. MacHg documents never contain any actual repositories. Instead MacHg is used to manage repositories which exist outside of MacHg. We sometimes refer to a repository reference as a repository when the distinction is clear.
Below is an example screenshot showing a collection of repositories. The repository 'collapseBugFix' is selected. When a repository is selected, then all repositories compatible with the selected repository have a badge beside them with the number of changes listed with respect to the selected repository. In the example here, you can see that with respect to the repository 'collapseBugFix', we could push 4 changesets to the repository 'collapseAddFeature', and we could pull 2 changesets from 'collapseAddFeature' into the selected repository, 'collapseBugFix'.
You can use standard drag and drop features to rearrange the repositories in the repository list. Through control clicking in the sidebar or through the Repository menu you can add an existing local repository, create a new local repository, add a server repository, or create a new grouping folder.
Any repository whose name in the sidebar is given in italics resides on a server and is not stored locally.


Global Digital Solution
Services
Portfolio
Blogs
About
Contact
Global Digital Solutions
Your ideas. Our Designs.


A simple Ruby project documentation website.
Motivation
I’ve used many documentation tools. Most are over-complicated and focus on what is possible rather than what is useful. Because I manage many open source projects, at a certain scale it makes sense to build something to suit your needs rather than try to adapt to existing systems. This is one such instance.
My goal is to provide task-centric documentation, and to continually improve the way it’s presented. The primary entry point for new developers are the structured usage guides, however having rich cross-referencing into the code is equally important.
With that in mind, this web application provides such a model and will evolve over time to suit my requirements and the needs of my users.
Usage
Please browse the source code index or refer to the guides below.
Getting Started
This guide explains how to use utopia-project
for your own project.
Documentation Formatting
This guide explains the conventions used by utopia-project
when
generating documentation for your project.
GitHub Pages Integration
This guide shows you how to use utopia-project
with GitHub Pages.
Contributing
We welcome contributions to this project.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
See Also
- Utopia — The website framework which powers this web application.
- Decode — The source code parser and cross-referencing library.
License
Released under the MIT license.
Copyright, 2020, by Samuel G. D. Williams.
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.
 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.


Presents:
The Back to the "Fifties" Jukebox
Now 200+ Fifties Classics in Streaming Real Audio
We think these are the Best of the best!
For Web Sites designed and maintained entirely by Seniors
Awarded February 2006.
This is the page which has been publicised in a number of Magazines and Newsletters, and is largely responsible for winning us the above awards! We think it is fairly unique.
You may spend Hours on this Page listening to some of the best Fifties Music on the Web, so bookmark it now, so you may return. If you enjoy it, please pass it along!
Notice!
I have made some major changes to all "Jukebox " pages. This is the result of a growing number of EMails saying various "Jukebox" pages not working.
Jukebox pages can accomodate only one user at a time, and users remain on the page until selections have played. The rapidly growing number of hits on jukebox pages coupled with the time factor is causing problems.
To alleviate this congestion, I have added an "Alternate" page for all jukeboxes.
If songs are not loading or playing Click the Button Below to enter an "Alternate identical page.
Also, remember the Jukebox pages do not work with the Realone Player. The solution for this problem is on the Fifties Menu page. If you are using the Realone Player please check it out also.
Cllick for Alternate page.
Play your individual selections in Streaming Real Audio!
Just like a real Jukebox. (Except it doesn't eat Quarters!)
To make Selections, press and hold down the Control Key (Ctrl). Click each selection you wish to play, or to select all, press and hold down the shift key, click the top file, scroll down, and click the bottom file. When you finish making your Selections, release the Control Key or shift key, and Click on "Play These". MAC users, try the Command (Apple) key or the Shift key! We are receiving conflicting reports on MAC!
Important!
To make multiple selections press and hold down the Control key while clicking on your selections.
, , Hits since October 21, 1998.


Remote Building and installing linux kernel
To remote build the linux kernel and install it to a separate ubuntu machine, first install dependencies.
sudo apt-get install build-essential libncurses-dev bison \
flex libssl-dev libelf-dev
Ubuntu 18 uses the linux kernel 4.15, so we’ll grab a base copy of the 4.15.0 kernel:
wget https://github.com/torvalds/linux/archive/v4.15.zip
unzip 4.15.zip
cd 4.15.zip
then copy the config file used from another operating ubuntu box:
cp /boot/config-$(uname -r) .config
then prepare the configuration file with:
make menuconfig
xconfig is also viable, but menuconfig may provide more options. In my opinion, it is also more stable. If you are trying to develop drivers for fuzzing, usb drivers can be found following
> Device Drivers > USB support
The modules by default are loaded into the linux kernel as one piece, but to make them separate modules, change the * next to the module to a M, for example:
<M> xHCI HCD (USB 3.0) support
This action doesn’t seem like much, but if you are trying to fuzz that module, it helps to have it separate for debugging purposes. For any modifications to the ethernet devices, namely e1000, changes need to be made in:
> Device Drivers > Network device support > Ethernet driver support
Now that you have a proper menuconfig built, proceed with a simple make command
make -j
Now setting the install directory to a location that we can easily copy all the modules from to the location / on the target remote ubuntu box:
make INSTALL_MOD_DIR=$(pwd)/../l15inst \
INSTALL_MOD_PATH=$(pwd)/../l15inst modules_install


| Date | Amount | Liquidation Status | Penalty Amount | Action |
| {{ p.repaymentDate | date }} | {{ p.repaymentAmount | currency: '₦' }} | {{ p.penaltyAmount | currency: '₦' }} |
Click the Apply Now button below to apply for a
Loan
It is as simple as that
Current loan balance
Are you sure you want to Pay for {{ loanDetails.repaymentAmount | currency: '₦' }}
Are you sure you want to liquidate {{ userLoanList.productName }}


• Now that you have succesfully joined Kcappia, the first thing is to share your applications or games with your friends. To do that, click on share your applications. When you click on that, you will be asked to talk about it, share an image with it, then share your application file and some extra file if it has. Then you will tell the os type so that the user can download applications of their own device, then you put your shared application name and you share it with your friends so that the world can enjoy the application or game with you. When you are done you will then be able to see your friends shared applications also by following them. You can also share screenshots of app and games moments you enjoyed, share trillers of upcoming apps or games or their new updates, and you can also talk about apps or games you just finish testing. It is that simple.
PROFILE
• Now that you can now see your friends shared application or games, images, videos, news, you need to be able to check out your own profile. You can do this by going to the profile page and there you can also see your shared stuffs and other things like your own post.
TRENDS
• On this page, you can see applications or games uploaded by users and you can also upload your own applications or games to be seen by everone not only your friends. On this page, to upload your application you just need to click on add on the trend page and fill in all the informations needed about your application and then you upload it. The rating is done by likes so you have to tell your friend about it so that they will like it and tell every other person about it. You can also see other application of all major os. Once you have added your application you will see it on top of other application and you will be able to update it. Not to forget, you can also search for applications, we create the trending page to make app installation more fun.
NOTIFICATION
• On this page you will see things that are done by your friends, and so it feeds you with updates, so that you are never left behind on what happens on your account.
DIRECT CHATING
• On the page you can do something very special, which is sharing applications and games privately with your followers. You can also chat with the follower you want to share your application with directly and you can communicate by written chat.
The sharing of applications or games feature is coming soon!
SEARCHING
• On Kcappia you can search for anything, anyone and any other thing, wonderful isn't it. Just try it out.
INSTALLS
• In the installs page you can see what you are currently installing on your device and who you have installed from, when you are done with installing, then you open it , if the application is already on your device, then you will open it, then you will install it to your device. This feature is coming soon!
SETTINGS
• On the setting page, you can logout, send us feedbacks , know about us, see private policy, get help, invite friends and see terms of use and all this can be done by just clicking on them.
Thank you for Joining Kcappia we hope you enjoyed it, please share this new social network with everyone you know and make app sharing something the world will love just like photo and video sharing services, and please in case you find any bug just give us a feedback and it will be corrected immediately.


Simple demo page to show cropping with polygonList in a OpenSeadragon viewer.
Click on Viewer to save polygon points
Reset
Load Example
Add Points as Polygon
Clear
Crop With Polygon
Clear


@lukechilds#2707 is it possible to have marketmaker launch anyway even if one of the electrum servers isnt working? Because now it just keeps loading because of the vrsc electrum. I think most people dont look at dev console, so they wont know whats causing hyperdex to load forever
@Cryptoon it should do that already, there is something like a 5s timeout. If the electrum server doesn't respond in that time marketmaker should ignore it and move on. If mm is hanging on an electrum server then it sounds like there's a bug in mm. Unfortunately we can't tell it to stop from our end, we can't communicate with it until it's finished.
If you can reproduce the issue are you able to report it to mm devs?
(edited)


Greetings,
Thank you for this opportunity to apply for the Digital Editor position at Portland Monthly. I have attached my cover letter and resume. Included in the cover letter are links to my work, however I will also include those links below for ease of reference. The cover letter and resume outlines my highlighted relevant skills and experience.
If you have any further questions, feel free to reply or call<PHONE_NUMBER>.


Due
to some error branch could not be deleted!
Branch deleted successfully!
Colleges Branches
Create and manage college branches.
| State |
City |
Branch Name |
Address |
Branch Head |
Actions |
|
{{branch.state.stateName}}
|
{{branch.city.cityName}}
|
{{branch.branchName}}
|
{{branch.address1}} {{branch.address2}}
|
{{branch.branchHead}}
|
|
| Total: {{ctrl.branches.length}} |


Ada Lovelace was a mathematician of the 19th century and is widely seen as the world’s first programmer. Through mathematics she met Charles Babbage and when he started working on the Analytical Engine in 1837 she realised to what extent it could be used. While he thought of it as a simple calculating machine, she saw what we would today call a computer. She wrote:
“The Analytical Engine has no pretensions whatever to originate anything. It can do whatever we know how to order it to perform.”
Writing her thoughts about this engine down she wrote the first computer program!
Ada Lovelace is a patriot for women in STEM and we are celebrating her day to celebrate the achievements of gender minorities in Informatics.


New Banksy artwork appears in Birmingham to highlight homelessness
by Jen MillsA new mural thought to be by Banksy has appeared in Birmingham.
The mural, which makes a park bench appear to be Santa’s sleigh being pulled along by reindeer, was painted in the Jewellery Quarter over the weekend.
It draws attention to homelessness, with anyone sitting on the bench appearing to look like Father Christmas.
A video on the artist’s Instagram page is captioned: ‘God bless Birmingham.’
It shows a homeless man called Ryan having a drink before lying down on the bench as the camera pans out.
The message continued: ‘In the 20 minutes we filmed Ryan on this bench passers-by gave him a hot drink, two chocolate bars and a lighter – without him ever asking for anything.’
Members of the public have been going to Vyse Street to pose with the artwork.
Commenting on the Instagram post, one user wrote: ‘There’s still beauty and kindness in this world. it might be difficult to find sometimes, but it’s there.’
Another said simply: ‘That’s so beautiful.’


Be Aware That Not Everybody Shares Your Enthusiasm About RESTFUL APIs
HTTP Basics
HTTP protocol
... is an application-level
protocol for distributed, collaborative, hypermedia information
systems. It is a generic, stateless, protocol which can be used for
many tasks beyond its use for hypertext, such as name servers and
distributed object management systems, through extension of its
request methods, error codes and headers ...
A feature of HTTP is the typing and negotiation of data representation, allowing systems
to be built independently of the data being transferred ...
from the abstract of HTTP/1.1
communication usually done via port 80 and TCP:
Request
from client to server ('asking')
Response
from server to client ('answering')
HTTP versions
version
content/changes
HTTP/0.9
simple protocol, easy to be implemented
just text (mainly HTML)
for each link an own TCP connection used
not standardized
HTTP/1.0
any MIME-types(e.g.: image/jpg, application/pdf, ...) can be transmitted
meta data for request and response (e.g.: Content-Type: text/html )
basics for security by access and user authentication
in order to sucessfully process request, client action is needed
4XX - client error
tough to seperate from server errors. It's likely, that the cause of error can be found on the client side
5XX - server error
tough to seperate from client errors. It's likely, that the cause of error can be found on the server side
REST Overview
Overview
architectural style based on web standards of HTTP protocol
described Roy Fielding in his dissertation in 2000
basic principles of RESTful HTTP:
resources and their unique identification
standardized methods
representation of resources
Hypermedia As The Engine Of Application State
stateless communication
Resources
The key abstraction of information in REST is a resource.
Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on.
In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource.
A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.
Fieldings definition
Entity Resource
also called Item Resource
independent, adressable information unit with its own lifecycle
http://localhost:8080/orders/1234
Collection Resource
collection of entity resources of the same kind
usually supply actions for searching, creating or adding items to the collection
http://localhost:8080/orders
Activity Resource
actions and activities can also be designed as resources, by making nouns from actions
Use Case:
As a bank, I want to transfer500€ from account A to account B.
Can you find possible resources ?
accounts
/accounts
/accounts/A
/accounts/B
And how about transfer ?
transactions
/transactions
/transactions/1
Uniform Resource Identifier (URI)
A Uniform Resource Identifier (URI) is a compact string of characters for identifying an abstract or physical resource.
IETF specification
one URI identifies exactly one resource,
one resource can be identified by multiple URIs
Uniform Resource Locator (URL)
... identify resources via a representation of their primary access
mechanism (e.g., their network "location"), rather than identifying
the resource by name or by some other attribute(s) of that resource
differences of URI, URL, URN,..
HTTP/1.1 200 OK
Content-Type: application/vnd.sandbox-v2+xml
... <?xml version="1.0" encoding="UTF-8"?>
<sb:v2 xmlns:dap="http://sandbox.bisnode.com/dap"
xmlns:sb="http://sandbox.bisnode.com">
<sb:auftrag href="http://localhost:8080/orders/1234">
<sb:name>test1</sb:name>
<sb:description>description for first test</sb:description>
</sb:auftrag> ...
</sb:v2>
Hypermedia
The next control state of an application resides in the representation of the ﬁrst requested resource, … The application state is controlled and stored by the user agent ...
... anticipate changes to that state (e.g., link maps and prefetching of representations) ...
... The model application is therefore an engine that moves from one state to the next by examining and choosing from among the alternative state transitions in the current set of representations.
Roy Fielding
HATEOAS = Hypermedia As The Engine Of Application State
Link Header
A means of indicating the relationships between resources on the Web,
as well as indicating the type of those relationships, ...
... However, links between resources need not be format specific; it can be useful to have typed links that are independent of their serialisation, especially when a resource has representations in multiple formats.
RFC 5988 - Web Linking
State transitions are modeled as links. Client does not know about state machine, available state transitions from current state of resource indicated via links in representation.
rel="east", rel="west"
... move to the left(west) OR right (east)
Stateless
... communication must be stateless in nature, ... such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server.
Roy Fielding
session state entirely on the client
visibility: monitoring system need just a single request
reliability: eases task of recovery from partial failures
scalability: free server resources (not storing state) and easily manage resource usage across requests
Richardson Maturity Model
Overview
model providing a good step by step way to understand the basic ideas behind restful thinking
Glory of REST
Level 3: Hypermedia Controls
Level 2: HTTP Verbs
Level 1: Resources
Level 0: The Swamp of POX
Level 0: The swamp of POX
... using HTTP as transport system for remote interactions, but without using any of the mechanism of the web.
Martin Fowler
One URI, one HTTP method
one resource (URI)
one method (usually POST)
multiple messages - Plain old xml (POX)
Remote Procedure Call(RPC) style
like SOAP or XML-RPC, wrapping in HTTP envelope
example (Level 0)
POST/appointmentService HTTP/1.1
[various other headers]<openSlotRequest date="2010-01-04" doctor="mjones"/>
HTTP/1.1 200 OK
[various headers]<appointmentRequestFailure>
<slot doctor="mjones" start="1400" end="1450"/>
<patient id="jsmith"/>
<reason>Slot not available</reason>
</appointmentRequestFailure>
Level 1: Resources
... introduce resources. So now rather than making all our requests to a singular service endpoint, we now start talking to individual resources.
Martin Fowler
... ugly acronym of HATEOAS (Hypertext As The Engine Of Application State)
It adresses the question of how to get from a list of open slots to knowing what to do to book an appointment.
Martin Fowler
The H Factor of a media-type is a measurement of the level of hypermedia support and sophistication of a media-type. H Factor values can be used to compare and contrast media types in order to aid in selecting the proper media-type(s) for your implementation.
Mike Amundsen


setfiles
Section: (8)Updated:<PHONE_NUMBER>
Index Return to Main Contents
NAME
setfiles - set file SELinux security contexts.SYNOPSIS
setfiles [-c policy ] [-d] [-l] [-n] [-e directory ] [-o filename ] [-q] [-s] [-v] [-vv] [-W] [-F] spec_file pathname...DESCRIPTION
This manual page describes the setfiles program. This program is primarily used to initialize the security context database (extended attributes) on one or more filesystems. This program is initially run as part of the SE Linux installation process. It can also be run at any time to correct errors, to add support for new policy, or with the -n option it can just check whether the file contexts are all as you expect. If a file object does not have a context, setfiles will write the default context to the file object's extended attributes. If a file object has a context, setfiles will only modify the type portion of the security context. The -F option will force a replacement of the entire context.OPTIONS
- -c
- check the validity of the contexts against the specified binary policy.
- -d
- show what specification matched each file.
- -l
- log changes in file labels to syslog.
- -n
- don't change any file labels.
- -p
- show progress by printing * every 1000 files.
- -q
- suppress non-error output.
- -r rootpath
- use an alternate root path
- -e directory
- directory to exclude (repeat option for more than one directory.)
- -F
- Force reset of context to match file_context for customizable files, and the default file context, changing the user, role, range portion as well as the type.
- -o filename
- save list of files with incorrect context in filename.
- -s
- take a list of files from standard input instead of using a pathname on the command line.
- -v
- show changes in file labels.
- -W
- display warnings about entries that had no matching files.
- -0
-
Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or backslashes.The GNU find -print0 option produces input suitable for this mode.
ARGUMENTS
spec_file The specification file which contains lines of the following formregexp [ -type ] ( context | <<none>> )
The regular expression is anchored at both ends. The optional type field specifies the file type as shown in the mode field by the ls(1) program, e.g. -- to match only regular files or -d to match only directories. The context can be an ordinary security context or the string <<none>> to specify that the file is not to have its context changed.
The last matching specification is used. If there are multiple hard links to a file that match different specifications and those specifications indicate different security contexts, then a warning is displayed but the file is still labeled based on the last matching specification other than <<none>>.
- pathname...
-
The pathname for the root directory of each file system to be relabeled.
Not used if the
-s
option is used.
AUTHOR
This man page was written by Russell Coker<EMAIL_ADDRESS>The program was written by Stephen Smalley<EMAIL_ADDRESS>ALSO
load_policy(8), checkpolicy(8)
Index
This document was created by man2html, using the manual pages.
Time: 05:34:30 GMT, December 24, 2015


HOOK A film review by Laurie Mann Copyright 1991 Laurie Mann
A few weeks ago, Robin Williams joked, "Hey, HOOK stars the stars of ISHTAR and POPEYE and was directed by the man who brought you 1941, so it has a history of people familiar with bombs."
HOOK isn't a complete dud, but it's disappointing given the amount of hype its gotten.
HOOK has a great premise: What if Peter Pan grew up? According to an article in PREMIERE magazine, the premise popped out of the mouth of the six-year-old son of the scriptwriter one day. IMHO, most of the problems in the film relate to the script and the direction. Most of the magic in the film is the credit of the art direction team, who created a phenomenal Never-Never Land, and the special effects team, who orchestrated some terrific flying.
There's a long opening sequence in California showing what a work-obsessed Yuppie Peter Banning (Robin Williams) is. There's a lot of unneeded setup between the time the movie opens, and the time a very elderly Wendy (a winning performance by Maggie Smith) tells Peter that "you are Peter Pan." This sequence could have been minimized because Peter's troubled relationship with his kids is done-to-death once Captain Hook spirits the kids to Never-Never Land.
Once TinkerBell drags Peter off to Never-Never Land to rescue his kids, the action picks up, but only slightly. There's some lovely business around Hook realizing what a mundane dud Peter is now, and how TinkerBell promises Hook to get Peter in to shape for a proper war.
I've already mentioned that the movie has a lot of extraneous stuff in it, but there are also a few inexplicable edits in it (okay, you can attribute these inexplicable things to "magic," but still...). One weird quick cut shows Peter being hoisted into the Lost Boys treehouse, but you never know *who* does it. There are also some "magical" costume changes.
The biggest misstep of the movie was its handling of the Lost Boys. Spielberg often does a great job directing one or two children at a time, but the writing and direction of the Lost Boys stunk. Most of the boys were updated into punky or overly cute American kids. It just felt wrong. There were too many "cute shots" of the kids, and a lot of incredibly crude language at times. Peter's acceptance by the boys was tentative at first, but once Peter started believing in himself, they started believing in him.
One writing/directing problem in this movie is the same problem that plagued 1941: You can see *everything* coming miles away. There are few surprises. Also, there are two sequence that scream "THEME PARK RIDE!" I had this same feeling from THE ADDAMS FAMILY, where some stuff felt like it was added to the movie for the sole purpose of being developed into a theme park ride.
I haven't talked about the acting of the main characters, and I guess its because I have such mixed feelings about it. IMHO, Peter Pan is a role Robin Williams was born to play, but he almost does a better job as Peter Banning, mundane, than Peter Pan, the eternal child. While Dustin Hoffman doesn't chew the scenery as Hook, he wavers wildly between being a buffoon and being quite terrifying. Charlie Korsimo is alternately affecting and obnoxious as Peter's son Jack. The girl who plays the daughter, Maggie, is cute and spirited. Julia Roberts is fine as TinkerBell, but her performance seemed strange, and it just might have been because she rarely acted *with* anyone. They aren't terrible, but they appeared to wear their characters like clothing. On the other hand, Bob Hoskins is wonderful as Smee, as is the actor who plays Toodles, another aged Lost Boy. Look for Phil Collins, David Crosby, and Glenn Close in cameos.
The essential problem with the script is it can't decide if its an overblown fairy tale, or if it's a serious movie about parents and children. There are some genuinely affecting moments in the movie, but there are other times when I felt blatantly manipulated. So I think that is where HOOK fails the most----if you can really get in to a movie, you don't feel manipulated.
In short, HOOK isn't a bomb, but it just doesn't deliver very much. If you like the trappings of a film you might like it because there's a lot to admire about the production. Unfortunate, it doesn't include the script.
<EMAIL_ADDRESS><EMAIL_ADDRESS>NeXT<EMAIL_ADDRESS>GEnie: L.MANN4
.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


We were asked to take a set of notes from another class and create "visual notes" based on their subject. At the time I was studying world art with a focus on India. I pulled the major imagery out for the basis of the poster. I created a mandala in the background using the actual words from my notes.
Ink on Paper
Fall 2014
Drawing for Communication


---
layout: archive
title: Lean Prover Zulip Chat Archive
permalink: 113488general/02039Proposalfixxforassumex.html
---
The archive URL format has changed. Please find this page at:
https://leanprover-community.github.io/archive/stream/113488-general/topic/Proposal.3A.20.60fix.20x.60.20for.20.60assume.20x.60.html


Provide a helpful hint to the learner. For example, you could show how to break the question into smaller sub-problems, show how to solve a sub-problem, or relate this question to a previous one.
The hint length is too long. Please use at most 500 characters.


My mother works as a Speech Therapist. One day, she explained to me that in France, we are sorely lacking in representatives of this profession. She then showed me her waiting list : a 15cm thick file where she preciously keep all the patients details she should contact if a place becomes available in her agenda. In order to make her life easier, I first advised her to use an excel file to compile all this information, but it wouldn’t solve the patient's problem : they would keep on calling to ask for appointments. That’s why I decided to create this platform. It allows the patient to raise requests for appointments and my mother to select, order and manage all the requests saved in the database.
I used Django to build the backend of this website. The idea was to create two main apps inside the project : one for the patient who could create their demand, and the other for the speech therapist, who could access a table of all the raised demands. It’s a basic system that uses the main functionalities of Django (Class Based views, context data, queryset…) and it was a very good exercise to put into practice what I’ve learned so far. I also learnt how to use the django-filters library to allow the Speech Therapist to sort and filter the table of data. I mainly used bulma.io as a CSS library.
I am currently thinking about implementing a tool that would automatically send an email to the user when they raised their appointment request.


Khymos is going through Srs Fd Science - today, stocks
A great series of posts from Martin “Khymos” Lersch at the moment, as he’s going through everything he learned from a recent Molecular Gastronomy seminar in Copenhagen.
Today’s one is on stocks - and the big takeaway for me was a detailed discussion of exactly how long meat stocks can be reduced for before they turn bitter.
The TLDR? 15-20 hours over a low heat.


I've never gotten into uppers that much. I've done coke once, liked it, but only done it once. I've tried adderall, a lot, and have done up to 140 mg at once (not pleasant).  This expierience made me think about my drug use.
An hour ago, I was coming down from a 1/2 oz. smoking session with my 4 dudes and I decided to mess with sum time release ritalin.  Anyways, to crush these balls I put the stuff beteen 2 spoons and grinded them together until it was powery, then I poured it onto a piece of paper and smoothed it out with a spoon until it was a fine powder, with a coke-like texture. I tasted it.. not bad, no numbing sensation tho(frown).
T+0 I crushed up 3 pills at 20 mg each between a spoon and snorted it. The taste wasn't bad like meth or other pharmasweuticals, but it wasn't as easy as adderal. It was about a 3/10 on the pain level.
T+0:15 Start to feel less like passing out, and more like talking.
T+0:20 WOW! I feel like I'm on coke, I'm not jiterry, I feel like a million dollars, and I just wanna talk to people on AIM and talk about how we should hang out more. My vision is the same as an oxycotton buzz, sharper images, everything seems a little darker and brighter at the same time. I want to express myself.
T+45:00 I'm feeling less euphoric, and a little more jittery, like the coke comedown.
T+1:00 I'm on the comedown. I'm not shaking like I do on coke, I just feel like I have extra mental energy, but I don't feel like moving. I feel a little depressed that it is over and decide to try it again, like I do on coke.
T+ 1:05 I blow 40 more mg(2 pills) in one line, nasal drip kinda sloppy, but not very painful.
T+1:15 This time it took effect very quickly, it is probably combining with my previous dose. I feel awesome. I feel like I need to get power, and I need to make friends with everyone I know.
T+ 1:25 I never want this to end, and want to drop out of school and become a cocaine dealer, and have this feeling whenever I want.
T+2:00 (right now) The second dose lasted very long. I don't feel crappy, I feel like I just popped adderall. I'm going to snort more now.
Well. Ritalin should definately be abused a lot more than it is. It feels just like coke!!! Seriously, from this expierience I've decided to spend all of my money on coke(to sell) ritalin(for me) and booze (for poon)!   It makes me feel happy and awesome and it makes life wonderful.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


{% import "macros/form.html" as form %}
You have to agree with the terms of use in order to register.


The Mezquita (Spanish for "Mosque") of Córdoba is a beautiful and fascinating building that symbolizes the many religious changes Córdoba has undergone over the centuries. Today, the Mezquita is the cathedral of Córdoba (officially the Cathedral of St. Mary of the Assumption), but the vast majority of its art and architecture is the work of Islamic architects, who built it as a mosque in the 8th century. Abd-al-Rahman who was the major person in buying and building the great mosque is supposed to be buried under it.
The Mezquita de Cordoba is most notable for its giant arches and its forest of over 856 (of an original 1,293) columns of jasper, onyx, marble, and granite.
The Mezquita also features richly gilded prayer niches. But the Mezquita's most interesting feature is certainly the Mihrab, a domed shrine of Byzantine mosaics built by Al Hakam II (961-76). Outside the Mezquita is the Courtyard of the Orange Trees (Patio de los Naranjos), which in springtime is perfumed with orange blossoms and has a beautiful fountain.
Although the CaixaForum is a contemporary building, it also exhibits retrospectives of artists from earlier time periods and has evolved into one of the most visited museums in Madrid.


UseTGAImageDecoder()
语法
UseTGAImageDecoder()概要
Enables the TGA (Targa) image support for the CatchImage(), LoadImage(), CatchSprite() and LoadSprite() functions.
参数
无.
返回值
无.
备注
The TGA format makes use of non-destructive compression (lossless) which means that the picture does not lose any information when it is compressed. The TGA image size is usually large, since the compression is very weak (Run Length Encoding - RLE). At this point, the TGA alpha channel information (if any) is ignored when using this format.
参阅
LoadImage(), CatchImage(), LoadSprite(), CatchSprite()
已支持操作系统
所有


Address: 68 Road No 15, Dhaka 1209
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 01823-039800
Address: 34, Rd No. 14A, Dhaka 1209
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-9118202
Address: 18/F, Bir Uttam Qazi Nuruzzaman Road, পান্থপথ, Dhaka 1205
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-8144466
Address: Syed Mahbub Morshed Ave, Dhaka
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-9128308
Founded: 1972
BIRDEM, the Bangladesh Institute of Research and Rehabilitation for Diabetes, Endocrine and Metabolic Disorders at Shahbag, Dhaka, Bangladesh is a 600-bed multidisciplinary hospital complex of the Diabetic Association of Bangladesh.
Address: 122 Kazi Nazrul Islam Avenue, Shahbagh, Dhaka 1000
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-9661551
Founder: Muhammad Ibrahim
Founded: 1980
Type of business: Private
Address: 89/1 Pantha Path, Dhaka 1215
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-9131901
Address: Block: E, Plot: 81, Bashundhara R/A, Dhaka 1229
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 01729-276556
Shaheed Suhrawardy Medical College is a government medical school and hospital located in Dhaka, the capital city of Bangladesh. Wikipedia
Address: Sher- E- Bangla Nagar, Dhaka 1207
Hours: Open 24 hours
Phone: 02-9130800 ext. 19
Principal: A.B.M. Maqsoodul Alam
Founded: 2006
Academic affiliation: University of Dhaka
Address: House # 2, Road No. 5 Green Rd, Dhaka 1205
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-9660015
Address: 55 Satmasjid Road, Jigatola Bustand, Dhaka 1209
Hours: Open 24 hours
Phone: 02-9672277
Address: Bir Uttam Samsul Alam Road, Dhaka 1217
Hours: Open 24 hours
Phone: 02-58310522
Address: Dhaka 1205
Hours: Open 24 hours
Phone: 02-9676356
Address: 1 Eskatan Garden Rd, Dhaka 1000
Hours: Open 24 hours
Phone: 02-8313234
Address: 78 Satmasjid Road, Dhaka 1209
Hours: Closed ⋅ Opens 8AM
Phone: 09666-787878
Address: Mirpur Rd, Dhaka 1212
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Address: Dhaka 1212
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-9852501
Address: Dhaka 1205
Hours: Open 24 hours
Laylat al-Qadr (Observed) might affect these hours
Phone: 02-9676356


{% extends 'base.html' %} {% block content %}
We are a group of graduate students at the University of Washington. Our group consists of Jack Chen, Vincent Lan, William Frame, Junhao Zhang, Samuel Perebikovsky, Anirudddha Dutta
We want to create a portfolio management tool for value investors, where we capture a variety of valuation methods on a dashboard for investors to view easily.