Wednesday, October 24, 2012
Tuesday, October 23, 2012
Tips for using gdb
1. Stack trace
(gdb) backtrace-bt
2. Print value of variable:
- (gdb) p variable
- Print one array:
(gdb) print a[0]@5 --> print 5 element of array
(gdb) display a[0]@5
3. List a snippet of code
(gdb) list
4. Auto execute debug command when reach to break point
(gdb) commands (breaking point number)
Type commands for when breaking point 1 is hit, one per line
End with a line saying just "end"
>cont
>end
5. Display information of break points
(gdb) info
6. Delete breaking point
(gdb) delete break 1
(gdb) backtrace-bt
2. Print value of variable:
- (gdb) p variable
- Print one array:
(gdb) print a[0]@5 --> print 5 element of array
(gdb) display a[0]@5
3. List a snippet of code
(gdb) list
4. Auto execute debug command when reach to break point
(gdb) commands (breaking point number)
Type commands for when breaking point 1 is hit, one per line
End with a line saying just "end"
>cont
>end
5. Display information of break points
(gdb) info
6. Delete breaking point
(gdb) delete break 1
Debug by some analysis statical tools
-lclint or splint: analyze coding without compile or running to find logic coding.
-ctag: list all function that we used in program
-cflow: list all called hierarchy of function
-ctag: list all function that we used in program
-cflow: list all called hierarchy of function
Wednesday, September 26, 2012
C++ DEBUG Rule : use assertions
When you are developping, use the assert macro to detect errors as soon
as they occur. This macro is defined in the include file
<assert.h>, and is used that way :
assert (expression) ;
If expression is false, program will stop indicating which assertion failed.
What is really nice with this macro, is that you can easily get rid of it for the production version of your code, by declaring #define NDEBUG.
This is because the assert macro is defined as :
assert (expression) ;
If expression is false, program will stop indicating which assertion failed.
What is really nice with this macro, is that you can easily get rid of it for the production version of your code, by declaring #define NDEBUG.
This is because the assert macro is defined as :
#ifndef NDEBUG #define assert(THETEST) ... #else #define assert(THETEST) ((void)0) #endif
C++ INCLUDE Rule : Use forward declaration when possible
Suppose you want to define a new class B that uses objects of class A.
- B only uses references or pointers to A. Use forward declaration
then : you don't need to include <A.h>. This
will in turn speed a little bit the compilation.
class A ; class B { private: A* fPtrA ; public: void mymethod(const& A) const ; } ; - B derives from A or B explicitely (or implicitely) uses objects of class A.
You then need to include <A.h>
#include <A.h> class B : public A { } ; class C { private: A fA ; public: void mymethod(A par) ; }
Friday, August 31, 2012
7 nguyên tắc sống của người giàu
1. Rõ ràng. Biết mình muốn gì? Mục tiêu trong từng giai đoạn là gì?
2. Tập trung: Khi đã có mục tiêu phải toàn tâm toàn ý. Khi tập trung cao độ sẽ lóe lên những ý tưởng táo bạo.
2. Tập trung: Khi đã có mục tiêu phải toàn tâm toàn ý. Khi tập trung cao độ sẽ lóe lên những ý tưởng táo bạo.
3. Ra quyết định: không phải mọi quyết định đều đúng nhưng thời gian sẽ chứng minh cho bạn thấy đa số quyết định là đúng.
4. Làm việc chuyên nghiệp: Việc ra một đồng, cũng phải làm chuyên nghiệp.
4. Làm việc chuyên nghiệp: Việc ra một đồng, cũng phải làm chuyên nghiệp.
5. Lời nói đi đôi với việc làm: Nói những điều mình làm và làm những gì mình nói.
6. Tập-Tập-Tập
Trước khi bắt tay vào
làm bất cứ việc gì, đặc biệt là kinh doanh, các bạn đều phải tập. Sau
lần tập thứ nhất, bạn sẽ mắc lỗi. Sau lần tập thứ 2 mắc lỗi ít hơn. Sau
lần tập thứ 3, bạn mới có thể thành công. Kinh doanh ảo về bất động sản
theo quy tắc 100-10-3-1 là minh chứng hùng hồn nhất cho điều này. Thành
công là sự nở hoa trong nhọc nhằn.
7. Khi thất bại, hãy tự an ủi mình bằng cách đưa ra 4 điều tự vấn:
+ Mình đã học được điều gì tuyệt vời từ sự việc này?
+ Số tiền mình mất là một phần hay là tất cả tài sản của mình?
+ Mình chỉ mất tiền chứ không mất sinh mạng
+ Kẻ lấy trộm là nó chứ không phải là mình
7. Khi thất bại, hãy tự an ủi mình bằng cách đưa ra 4 điều tự vấn:
+ Mình đã học được điều gì tuyệt vời từ sự việc này?
+ Số tiền mình mất là một phần hay là tất cả tài sản của mình?
+ Mình chỉ mất tiền chứ không mất sinh mạng
+ Kẻ lấy trộm là nó chứ không phải là mình
Thursday, August 30, 2012
Some suggestions when u make friend wt foreigner
Trong
giao tiếp tiếng Anh chắc hẳn các bạn rất muốn nói chuyện với người nước
ngoài nhưng lại ngại vì thấy thiếu tự tin và không biết bắt đầu từ đâu?
Sau đây là một số lời khuyên cho chúng ta khi muốn bắt chuyện với người
nước ngoài.
Bạn nên chủ động đến những nơi có nhiều người nước ngoài hay sinh sống hoặc đi du lịch và làm quen với họ. Sau khi đã tiếp cận và có cơ hội nói chuyện bạn hãy thoải mái và mỉm cười. Đừng cố phải nói những gì quá khó và đừng quá lo nghĩ xem mình phải nói gì tiếp theo. Trước tiên, hãy cứ lắng nghe thấu đáo.
Cố gắng ghi nhớ tên của người nước ngoài và hỏi họ xem mình phát âm tên của họ đã chuẩn chưa. Hãy cố gắng tìm cách ghi nhớ ví dụ: bạn liên tưởng tên người ấy với một người nổi tiếng nào đó hoặc đồng nhất tên người ấy với các từ quen thuộc như (Jen với jewellery hoặc Ben với beard). Thậm chí cả việc bạn đề nghị họ đánh vần tên họ để nhớ. Và rồi khi câu chuyện kết thúc bạn có thể chào họ bằng các câu như: Thanks for chatting, Jen." hoặc "It was great to meet you Ben."
Ta nên hỏi người bản xứ về một tuần hay một ngày của họ trôi qua thế nào? Bạn có thể đặt các câu hỏi như:
"Did anything exciting happen today/this week?"
"How was your weekend?"
Then, describe something memorable or funny about your day or week.
"You'll never guess what happened to me..."
Bàn luận các tin tức quốc tế. Bạn có thể mở đầu các câu chuyện theo các cách sau:
Ví dụ:
"Did you know..."
"Did you hear..."
"I just heard..."
"I just read..."
"Is it true...?"
"Did you hear about the bus strike?"
"I just read that the recession is officially over."
"Is it true that gas prices are going up again?"
Hay bàn luận những thứ xung quanh bạn, những điều bạn thấy trước mắt như các bức tranh vẽ nguệch ngoạc trên đường phố, về lũ trẻ đang chơi đùa ở gần đó, hoặc các chủ đề mang tính tích cực.
Ví dụ
"The garden is so nice, isn't it? I wonder who takes care of it."
"I can't believe how many buses stop here. Is it always like this?"
"I can't believe how many students live around here."
"There sure are a lot of dogs here. Do you have a pet?"
Hay nói về vấn đề du lich : Bạn hãy nói bạn đến từ đâu và hỏi xem họ đã từng đến đấy chưa?
Ví dụ:
"Where have you travelled?"
"Where would you like to travel?"
"Have you ever been to...?"
"You should go to ..."
"Have you lived here all your life?"
Đề nghị họ cho vài lời khuyên :
Ví dụ:
"What is there to do around here?"
"Where is a good place to eat/have a coffee?"
"Is there anywhere to go swimming in this town?"
"I like to watch English movies. Can you recommend a good one?"
Hỏi về sở thích của họ và đồng thời chia sẻ với họ vài sở thích của mình. Nếu có thể bạn hãy cố gắng tìm được điểm chung giữa hai người ví dụ như các bộ phim, các chương trình truyền hình hay thể thao.
Ví dụ:
"What do you get up to in your spare time?"
"Don't laugh but...I'm into reality TV shows these days."
"Do you play any sports?"
Hỏi về việc học tiếng Anh
Ví dụ:
"Can I ask you a question about English? I often hear people at the coffee shop say 'double double'. What does that mean?"
"You said you were 'crazy busy' this week. What exactly does that mean?"
Hy vọng những lời khuyên trên sẽ giúp cho các bạn tự tin hơn trong việc giao tiếp với người nước ngoài.
Bạn nên chủ động đến những nơi có nhiều người nước ngoài hay sinh sống hoặc đi du lịch và làm quen với họ. Sau khi đã tiếp cận và có cơ hội nói chuyện bạn hãy thoải mái và mỉm cười. Đừng cố phải nói những gì quá khó và đừng quá lo nghĩ xem mình phải nói gì tiếp theo. Trước tiên, hãy cứ lắng nghe thấu đáo.
Cố gắng ghi nhớ tên của người nước ngoài và hỏi họ xem mình phát âm tên của họ đã chuẩn chưa. Hãy cố gắng tìm cách ghi nhớ ví dụ: bạn liên tưởng tên người ấy với một người nổi tiếng nào đó hoặc đồng nhất tên người ấy với các từ quen thuộc như (Jen với jewellery hoặc Ben với beard). Thậm chí cả việc bạn đề nghị họ đánh vần tên họ để nhớ. Và rồi khi câu chuyện kết thúc bạn có thể chào họ bằng các câu như: Thanks for chatting, Jen." hoặc "It was great to meet you Ben."
Ta nên hỏi người bản xứ về một tuần hay một ngày của họ trôi qua thế nào? Bạn có thể đặt các câu hỏi như:
"Did anything exciting happen today/this week?"
"How was your weekend?"
Then, describe something memorable or funny about your day or week.
"You'll never guess what happened to me..."
Bàn luận các tin tức quốc tế. Bạn có thể mở đầu các câu chuyện theo các cách sau:
Ví dụ:
"Did you know..."
"Did you hear..."
"I just heard..."
"I just read..."
"Is it true...?"
"Did you hear about the bus strike?"
"I just read that the recession is officially over."
"Is it true that gas prices are going up again?"
Hay bàn luận những thứ xung quanh bạn, những điều bạn thấy trước mắt như các bức tranh vẽ nguệch ngoạc trên đường phố, về lũ trẻ đang chơi đùa ở gần đó, hoặc các chủ đề mang tính tích cực.
Ví dụ
"The garden is so nice, isn't it? I wonder who takes care of it."
"I can't believe how many buses stop here. Is it always like this?"
"I can't believe how many students live around here."
"There sure are a lot of dogs here. Do you have a pet?"
Hay nói về vấn đề du lich : Bạn hãy nói bạn đến từ đâu và hỏi xem họ đã từng đến đấy chưa?
Ví dụ:
"Where have you travelled?"
"Where would you like to travel?"
"Have you ever been to...?"
"You should go to ..."
"Have you lived here all your life?"
Đề nghị họ cho vài lời khuyên :
Ví dụ:
"What is there to do around here?"
"Where is a good place to eat/have a coffee?"
"Is there anywhere to go swimming in this town?"
"I like to watch English movies. Can you recommend a good one?"
Hỏi về sở thích của họ và đồng thời chia sẻ với họ vài sở thích của mình. Nếu có thể bạn hãy cố gắng tìm được điểm chung giữa hai người ví dụ như các bộ phim, các chương trình truyền hình hay thể thao.
Ví dụ:
"What do you get up to in your spare time?"
"Don't laugh but...I'm into reality TV shows these days."
"Do you play any sports?"
Hỏi về việc học tiếng Anh
Ví dụ:
"Can I ask you a question about English? I often hear people at the coffee shop say 'double double'. What does that mean?"
"You said you were 'crazy busy' this week. What exactly does that mean?"
Hy vọng những lời khuyên trên sẽ giúp cho các bạn tự tin hơn trong việc giao tiếp với người nước ngoài.
Wednesday, August 22, 2012
String contants special characters
Ex:
s = "abc??(x)";
Compile error by '-trigraphs' option of compiler,
??=、??(、??/、??)、??'、??<、??!、??>、??- is each #、[、¥、]、^、{、|、}、̃
"abc??(x)" is "abc[x)".
Fix:
s = "abc\?\?(x)";
s = "abc??(x)";
Compile error by '-trigraphs' option of compiler,
??=、??(、??/、??)、??'、??<、??!、??>、??- is each #、[、¥、]、^、{、|、}、̃
"abc??(x)" is "abc[x)".
Fix:
s = "abc\?\?(x)";
Some special marco define
1. Double quotes around a parameter string of x, producing a string literal.
#defined Identifier( x ) #x
2. The formal arguments x and y concatenates the one formal argument axis.
#defined Identifier( x, y ) x ## y
3. NOTE: # operator and # # operator must not be mixed, it should not be used more than once.
#define XXX(a, b, c) a#b##c is not correct
Please change to:
#define AAA(a, b) a#b
#define BBB(x, y) x##y
#defined Identifier( x ) #x
2. The formal arguments x and y concatenates the one formal argument axis.
#defined Identifier( x, y ) x ## y
3. NOTE: # operator and # # operator must not be mixed, it should not be used more than once.
#define XXX(a, b, c) a#b##c is not correct
Please change to:
#define AAA(a, b) a#b
#define BBB(x, y) x##y
Difference between 'new', 'new operator' and 'operator new' in C++
A question asked in a forum said:
Why
does void* p = new (1024); gives me a compilation error while void* p =
operator new (1024); works. What is the difference between new and
"operator new"?
Lets go back to the
beginning. Once upon a time there was this C language that used 'malloc'
to allocate memory. Then when C++ came, a new way was defined of
allocating memory by the use of 'new'. Its supposed to be much safter
and better way but some software gurus may differ. Memory for 'new' is
allocated from 'Free Store' and memory by 'malloc' is generated from
'heap'. The 'heap' and 'Free Store' may be the same area and is a
compiler implementation detail.
The syntax for 'operator new' is:
void* new (std::size_t size);
All it does is allocate a memory of size specified
On the other hand, 'new' does 2 things:
1. It calls 'operator new'
2. It calls constructor for the type of object
In the above case since 1024 is not a type, it will fail in calling its constructor.
'new' is also referred to as 'keyword new' or 'new operator' to cause more confusion :)
Here
is a small example to play with 'operator new' after the example you
will realise that regardless of what is passed, it always allocates a 4
byte memory.
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy#include<iostream> using namespace std; int main() { //void* p = new (1024); void* p = operator new (1024); //Lets test if we can do anything with the memory cout<<"p = "<<p<<endl; cout<<"sizeof(p) = "<<sizeof(p)<<endl; int *x = static_cast<int *>(p); cout<<"*x before = "<<*x<<endl; *x = 23456; cout<<"*x after = "<<*x<<endl; void* q = operator new (0); cout<<"\nq = "<<q<<endl; cout<<"sizeof(q) = "<<sizeof(q)<<endl; x = static_cast<int *>(q); cout<<"*x before = "<<*x<<endl; *x = 65432; cout<<"*x after = "<<*x<<endl; void* z = operator new ('a'); cout<<"\nz = "<<z<<endl; cout<<"sizeof(z) = "<<sizeof(z)<<endl; x = static_cast<int *>(z); cout<<"*x before = "<<*x<<endl; *x = 11111; cout<<"*x after = "<<*x<<endl; return 0; }
The output is as follows:
An example of dynamic_cast
Lets look at an example of dynamic_cast where you can cast a pointer
from Derived class to Base class. The example should be self
explanatory:
The output is as follows:
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy //A very simple program to explain dynamic cast #include <iostream> using namespace std; //Base classclass A { public: int a; int b; private: int c; }; //Derived classclass B :public A { private: int d; }; //function that prints a and bvoid function(A a) { cout<<"\n a = "<<a.a<<" b = "<<a.b<<endl; } int main() { A *a; B *b=new(B); b->a = 20, b->b = 40; a = dynamic_cast<A*>(b); //Dynamic cast from Dervied to Base function(*a); return 0; }
The output is as follows:
Tuesday, August 21, 2012
virtual destructor of base class
You may often find that the destructor of your class is virtual. The
main reason for having virtual destructor stems from the fact that some
other class may derive from your class. If the derived object is
referenced as base object and destroyed then the derived class objects
wont be deleted. To overcome this problem we define the destructor
virtual . Lets look at an example:
The output is as follows:

Now lets modify the base destructor to make it virtual.
The modified output is as follows:

There is one more point to be noted regarding virtual destructor. We can't declare pure virtual destructor. Even if a virtual destructor is declared as pure, it will have to implement an empty body (at least) for the destructor.
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy //Example showing the need for Virtual Destructor#include <iostream> using namespace std; class Base { public: Base() { cout<<"Base Constructor Called"<<endl; } ~Base() { cout<<"Base Destructor Called"<<endl; } }; class Derived : public Base { public: Derived() { cout<<"Derived Constructor Called"<<endl; } ~Derived() { cout<<"Derived Destructor Called"<<endl; } }; int main() { cout<<"\nTESTING NON-VIRTUAL BASE DESTRUCTOR\n"; Base *b = new (Derived); delete(b); return 0; }
The output is as follows:

Now lets modify the base destructor to make it virtual.
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy //Example showing the need for Virtual Destructor#include <iostream> using namespace std; class Base { public: Base() { cout<<"Base Constructor Called"<<endl; } virtual ~Base() { cout<<"Base Destructor Called"<<endl; } }; class Derived : public Base { public: Derived() { cout<<"Derived Constructor Called"<<endl; } ~Derived() { cout<<"Derived Destructor Called"<<endl; } }; int main() { cout<<"\nTESTING VIRTUAL BASE DESTRUCTOR\n"; Base *b = new (Derived); delete(b); return 0; }
The modified output is as follows:

There is one more point to be noted regarding virtual destructor. We can't declare pure virtual destructor. Even if a virtual destructor is declared as pure, it will have to implement an empty body (at least) for the destructor.
You can read more about this at C++ FAQ.
Monday, August 20, 2012
Initialize for struct members in C++
How to initialize for struct member as bellow
struct ExSt{
std:string str;
int a;
int b;
} ss_;
Normally, to initialize for ss_ we may use memset (&ss_, 0, sizeof (struct ExSt)). But in this case, it cause hang, because of 'str' is a class.
A solution to initialize for ss_ is:
Define constructor for struct ExSt, in constructor, we initialize for its members.
struct ExSt{
int a;
int b;
} ss_;
struct ExSt{
std:string str;
int a;
int b;
} ss_;
Normally, to initialize for ss_ we may use memset (&ss_, 0, sizeof (struct ExSt)). But in this case, it cause hang, because of 'str' is a class.
A solution to initialize for ss_ is:
Define constructor for struct ExSt, in constructor, we initialize for its members.
struct ExSt{
ExSt():a(0), b(0)
{};
std:string str;int a;
int b;
} ss_;
Inside the Linux boot process
This note is referred from IBM
http://www.ibm.com/developerworks/linux/library/l-linuxboot/
In the early days, bootstrapping a computer meant feeding a paper tape containing a boot program or manually loading a boot program using the front panel address/data/control switches. Today's computers are equipped with facilities to simplify the boot process, but that doesn't necessarily make it simple.
Let's start with a high-level view of Linux boot so you can see the entire landscape. Then we'll review what's going on at each of the individual steps. Source references along the way will help you navigate the kernel tree and dig in further.
Overview
Figure 1 gives you the 20,000-foot view.
Figure 1. The 20,000-foot view of the Linux boot process
When a system is first booted, or is reset, the processor executes code at a well-known location. In a personal computer (PC), this location is in the basic input/output system (BIOS), which is stored in flash memory on the motherboard. The central processing unit (CPU) in an embedded system invokes the reset vector to start a program at a known address in flash/ROM. In either case, the result is the same. Because PCs offer so much flexibility, the BIOS must determine which devices are candidates for boot. We'll look at this in more detail later.
When a boot device is found, the first-stage boot loader is loaded into RAM and executed. This boot loader is less than 512 bytes in length (a single sector), and its job is to load the second-stage boot loader.
When the second-stage boot loader is in RAM and executing, a splash screen is commonly displayed, and Linux and an optional initial RAM disk (temporary root file system) are loaded into memory. When the images are loaded, the second-stage boot loader passes control to the kernel image and the kernel is decompressed and initialized. At this stage, the second-stage boot loader checks the system hardware, enumerates the attached hardware devices, mounts the root device, and then loads the necessary kernel modules. When complete, the first user-space program (
That's Linux boot in a nutshell. Now let's dig in a little further and explore some of the details of the Linux boot process.
System startup
The system startup stage depends on the hardware that Linux is being booted on. On an embedded platform, a bootstrap environment is used when the system is powered on, or reset. Examples include U-Boot, RedBoot, and MicroMonitor from Lucent. Embedded platforms are commonly shipped with a boot monitor. These programs reside in special region of flash memory on the target hardware and provide the means to download a Linux kernel image into flash memory and subsequently execute it. In addition to having the ability to store and boot a Linux image, these boot monitors perform some level of system test and hardware initialization. In an embedded target, these boot monitors commonly cover both the first- and second-stage boot loaders.
In a PC, booting Linux begins in the BIOS at address 0xFFFF0. The first
step of the BIOS is the power-on self test (POST). The job of the POST is
to perform a check of the hardware. The second step of the BIOS is local device
enumeration and initialization.
Given the different uses of BIOS functions, the BIOS is made up of two parts: the POST code and runtime services. After the POST is complete, it is flushed from memory, but the BIOS runtime services remain and are available to the target operating system.
To boot an operating system, the BIOS runtime searches for devices that are both active and bootable in the order of preference defined by the complementary metal oxide semiconductor (CMOS) settings. A boot device can be a floppy disk, a CD-ROM, a partition on a hard disk, a device on the network, or even a USB flash memory stick.
Commonly, Linux is booted from a hard disk, where the Master Boot Record (MBR) contains the primary boot loader. The MBR is a 512-byte sector, located in the first sector on the disk (sector 1 of cylinder 0, head 0). After the MBR is loaded into RAM, the BIOS yields control to it.
Stage 1 boot loader
The primary boot loader that resides in the MBR is a 512-byte image containing both program code and a small partition table (see Figure 2). The first 446 bytes are the primary boot loader, which contains both executable code and error message text. The next sixty-four bytes are the partition table, which contains a record for each of four partitions (sixteen bytes each). The MBR ends with two bytes that are defined as the magic number (0xAA55). The magic number serves as a validation check of the MBR.
Figure 2. Anatomy of the MBR
The job of the primary boot loader is to find and load the secondary boot loader (stage 2). It does this by looking through the partition table for an active partition. When it finds an active partition, it scans the remaining partitions in the table to ensure that they're all inactive. When this is verified, the active partition's boot record is read from the device into RAM and executed.
Stage 2 boot loader
The secondary, or second-stage, boot loader could be more aptly called the kernel loader. The task at this stage is to load the Linux kernel and optional initial RAM disk.
The first- and second-stage boot loaders combined are
called Linux Loader (LILO) or GRand Unified Bootloader (GRUB) in the x86
PC environment. Because LILO has some disadvantages that were corrected
in GRUB, let's look into GRUB. (See many additional resources on GRUB,
LILO, and related topics in the Resources section later in this article.)
The great thing about GRUB is that it includes knowledge of Linux file systems. Instead of using raw sectors on the disk, as LILO does, GRUB can load a Linux kernel from an ext2 or ext3 file system. It does this by making the two-stage boot loader into a three-stage boot loader. Stage 1 (MBR) boots a stage 1.5 boot loader that understands the particular file system containing the Linux kernel image. Examples include
With stage 2 loaded, GRUB can, upon request, display a list of available kernels (defined in
With the second-stage boot loader in memory, the file system is consulted, and the default kernel image and
Kernel
With the kernel image in memory and control given from the stage 2
boot loader, the kernel stage begins. The kernel image isn't so much an
executable kernel, but a compressed kernel image. Typically this is a zImage
(compressed image, less than 512KB) or a bzImage (big compressed image, greater
than 512KB), that has been previously compressed with zlib. At the head of
this kernel image is a routine that does some minimal amount of hardware setup
and then decompresses the kernel contained within the kernel image and places
it into high memory. If an initial RAM disk image is present, this routine moves
it into memory and notes it for later use. The routine then calls the kernel and the kernel boot
begins.
When the bzImage (for an i386 image) is invoked, you begin at
In the new
Figure 3. Major functions flow for the Linux kernel i386 boot
With the call to
During the boot of the kernel, the initial-RAM disk (
The
Init
After the kernel is booted and initialized, the kernel starts the first user-space application. This is the first program invoked that is compiled with the standard C library. Prior to this point in the process, no standard C applications have been executed.
In a desktop Linux system, the first application started is commonly
Summary
Much like Linux itself, the Linux boot process is highly flexible, supporting a huge number of processors and hardware platforms. In the beginning, the loadlin boot loader provided a simple way to boot Linux without any frills. The LILO boot loader expanded the boot capabilities, but lacked any file system awareness. The latest generation of boot loaders, such as GRUB, permits Linux to boot from a range of file systems (from Minix to Reiser).
http://www.ibm.com/developerworks/linux/library/l-linuxboot/
In the early days, bootstrapping a computer meant feeding a paper tape containing a boot program or manually loading a boot program using the front panel address/data/control switches. Today's computers are equipped with facilities to simplify the boot process, but that doesn't necessarily make it simple.
Let's start with a high-level view of Linux boot so you can see the entire landscape. Then we'll review what's going on at each of the individual steps. Source references along the way will help you navigate the kernel tree and dig in further.
Overview
Figure 1 gives you the 20,000-foot view.
Figure 1. The 20,000-foot view of the Linux boot process
When a system is first booted, or is reset, the processor executes code at a well-known location. In a personal computer (PC), this location is in the basic input/output system (BIOS), which is stored in flash memory on the motherboard. The central processing unit (CPU) in an embedded system invokes the reset vector to start a program at a known address in flash/ROM. In either case, the result is the same. Because PCs offer so much flexibility, the BIOS must determine which devices are candidates for boot. We'll look at this in more detail later.
When a boot device is found, the first-stage boot loader is loaded into RAM and executed. This boot loader is less than 512 bytes in length (a single sector), and its job is to load the second-stage boot loader.
When the second-stage boot loader is in RAM and executing, a splash screen is commonly displayed, and Linux and an optional initial RAM disk (temporary root file system) are loaded into memory. When the images are loaded, the second-stage boot loader passes control to the kernel image and the kernel is decompressed and initialized. At this stage, the second-stage boot loader checks the system hardware, enumerates the attached hardware devices, mounts the root device, and then loads the necessary kernel modules. When complete, the first user-space program (
init) starts, and high-level system initialization is performed.That's Linux boot in a nutshell. Now let's dig in a little further and explore some of the details of the Linux boot process.
System startup
The system startup stage depends on the hardware that Linux is being booted on. On an embedded platform, a bootstrap environment is used when the system is powered on, or reset. Examples include U-Boot, RedBoot, and MicroMonitor from Lucent. Embedded platforms are commonly shipped with a boot monitor. These programs reside in special region of flash memory on the target hardware and provide the means to download a Linux kernel image into flash memory and subsequently execute it. In addition to having the ability to store and boot a Linux image, these boot monitors perform some level of system test and hardware initialization. In an embedded target, these boot monitors commonly cover both the first- and second-stage boot loaders.
Extracting the MBR
To see the contents of your MBR, use this command:
# dd if=/dev/hda of=mbr.bin bs=512 count=1
# od -xa mbr.bin
The dd command, which needs to be run from
root, reads the first 512 bytes from /dev/hda (the first Integrated Drive Electronics,
or IDE drive) and writes them to the mbr.bin
file. The od command prints
the binary file in hex and ASCII formats.Given the different uses of BIOS functions, the BIOS is made up of two parts: the POST code and runtime services. After the POST is complete, it is flushed from memory, but the BIOS runtime services remain and are available to the target operating system.
To boot an operating system, the BIOS runtime searches for devices that are both active and bootable in the order of preference defined by the complementary metal oxide semiconductor (CMOS) settings. A boot device can be a floppy disk, a CD-ROM, a partition on a hard disk, a device on the network, or even a USB flash memory stick.
Commonly, Linux is booted from a hard disk, where the Master Boot Record (MBR) contains the primary boot loader. The MBR is a 512-byte sector, located in the first sector on the disk (sector 1 of cylinder 0, head 0). After the MBR is loaded into RAM, the BIOS yields control to it.
Stage 1 boot loader
The primary boot loader that resides in the MBR is a 512-byte image containing both program code and a small partition table (see Figure 2). The first 446 bytes are the primary boot loader, which contains both executable code and error message text. The next sixty-four bytes are the partition table, which contains a record for each of four partitions (sixteen bytes each). The MBR ends with two bytes that are defined as the magic number (0xAA55). The magic number serves as a validation check of the MBR.
Figure 2. Anatomy of the MBR
The job of the primary boot loader is to find and load the secondary boot loader (stage 2). It does this by looking through the partition table for an active partition. When it finds an active partition, it scans the remaining partitions in the table to ensure that they're all inactive. When this is verified, the active partition's boot record is read from the device into RAM and executed.
Stage 2 boot loader
The secondary, or second-stage, boot loader could be more aptly called the kernel loader. The task at this stage is to load the Linux kernel and optional initial RAM disk.
GRUB stage boot loaders
The
/boot/grub directory contains the
stage1, stage1.5,
and stage2 boot loaders, as well as a number of
alternate loaders (for example, CR-ROMs use the iso9660_stage_1_5).The great thing about GRUB is that it includes knowledge of Linux file systems. Instead of using raw sectors on the disk, as LILO does, GRUB can load a Linux kernel from an ext2 or ext3 file system. It does this by making the two-stage boot loader into a three-stage boot loader. Stage 1 (MBR) boots a stage 1.5 boot loader that understands the particular file system containing the Linux kernel image. Examples include
reiserfs_stage1_5
(to load from a Reiser journaling file system) or
e2fs_stage1_5 (to load from an ext2 or ext3
file system). When the stage 1.5 boot loader is loaded and running, the stage
2 boot loader can be loaded.With stage 2 loaded, GRUB can, upon request, display a list of available kernels (defined in
/etc/grub.conf, with soft links
from /etc/grub/menu.lst and
/etc/grub.conf). You can select a kernel and even
amend it with additional kernel parameters. Optionally, you can use a command-line
shell for greater manual control over the boot process.
With the second-stage boot loader in memory, the file system is consulted, and the default kernel image and
initrd image are loaded into memory. With the
images ready, the stage 2 boot loader invokes the kernel image.Kernel
Manual boot in GRUB
From the GRUB command-line, you can boot a specific kernel with a
named
initrd image as follows:
grub> kernel /bzImage-2.6.14.2
[Linux-bzImage, setup=0x1400, size=0x29672e]
grub> initrd /initrd-2.6.14.2.img
[Linux-initrd @ 0x5f13000, 0xcc199 bytes]
grub> boot
Uncompressing Linux... Ok, booting the kernel.
If you don't know the name of the kernel to boot, just type a forward slash (/)
and press the Tab key. GRUB will display the list of kernels and initrd
images.When the bzImage (for an i386 image) is invoked, you begin at
./arch/i386/boot/head.S in the
start assembly routine (see Figure 3 for the major
flow). This routine does some basic hardware setup and invokes the
startup_32 routine in
./arch/i386/boot/compressed/head.S. This routine
sets up a basic environment (stack, etc.) and clears the Block Started by Symbol (BSS). The kernel is
then decompressed through a call to a C function called
decompress_kernel (located in
./arch/i386/boot/compressed/misc.c). When the
kernel is decompressed into memory, it is called. This is yet
another startup_32 function, but this function is
in ./arch/i386/kernel/head.S.
In the new
startup_32 function (also called the swapper or process 0), the page
tables are initialized and memory paging is enabled. The type of CPU is
detected along with any optional floating-point unit (FPU) and stored away for later use. The
start_kernel function is then invoked
(init/main.c), which takes you to the non-architecture
specific Linux kernel. This is, in essence, the main
function for the Linux kernel.Figure 3. Major functions flow for the Linux kernel i386 boot
With the call to
start_kernel, a long list of
initialization functions are called to set up interrupts, perform further
memory configuration, and load the initial RAM disk. In the end, a call is made
to kernel_thread (in
arch/i386/kernel/process.c) to start the
init function, which is the first user-space
process. Finally, the idle task is started and the scheduler can now take
control (after the call to cpu_idle). With interrupts enabled, the
pre-emptive scheduler periodically takes control to provide multitasking.During the boot of the kernel, the initial-RAM disk (
initrd) that was loaded
into memory by the stage 2 boot loader is copied into RAM and mounted. This
initrd serves as a temporary root file system in
RAM and allows the kernel to fully boot without having to mount any physical
disks. Since the necessary modules needed to interface with peripherals can be
part of the initrd, the kernel can be very small,
but still support a large number of possible hardware configurations. After
the kernel is booted, the root file system is pivoted (via
pivot_root) where the
initrd root file system is unmounted and the real
root file system is mounted.decompress_kernel output
The
decompress_kernel function is where you see the usual
decompression messages emitted to the display:
Uncompressing Linux... Ok, booting the kernel.
initrd function allows you to create a small Linux
kernel with drivers compiled as loadable modules. These loadable modules give
the kernel the means to access disks and the file systems on those disks, as
well as drivers for other hardware assets. Because the root file system is a file system on a disk, the initrd function provides a means
of bootstrapping to gain access to the disk and mount the real root file system.
In an embedded target without a hard disk, the initrd
can be the final root file system, or the final root file system can be mounted
via the Network File System (NFS).Init
After the kernel is booted and initialized, the kernel starts the first user-space application. This is the first program invoked that is compiled with the standard C library. Prior to this point in the process, no standard C applications have been executed.
In a desktop Linux system, the first application started is commonly
/sbin/init. But it need not be. Rarely do
embedded systems require the extensive initialization provided by
init (as configured through
/etc/inittab). In many cases, you can invoke a
simple shell script that starts the necessary embedded applications.
Summary
Much like Linux itself, the Linux boot process is highly flexible, supporting a huge number of processors and hardware platforms. In the beginning, the loadlin boot loader provided a simple way to boot Linux without any frills. The LILO boot loader expanded the boot capabilities, but lacked any file system awareness. The latest generation of boot loaders, such as GRUB, permits Linux to boot from a range of file systems (from Minix to Reiser).
Shared Libraries
This note is referred from http://rute.2038bug.com/node26.html.gz
:
The -shared option to gcc builds our shared library. The -W options are linker options that set the version number of the library that linking programs will load at runtime. The -fPIC -DPIC means to generate position-independent code, that is, code suitable for dynamic linking.
After running make we have
DLLs have a problem. Consider a DLL that is outdated or buggy: simply overwriting the DLL file with an updated file will affect all the applications that use it. If these applications rely on certain behavior of the DLL code, then they will probably crash with the fresh DLL. UNIX has elegantly solved this problem by allowing multiple versions of DLLs to be present simultaneously. The programs themselves have their required version number built into them. Try
which will show the DLL files that
mytest is scheduled to link
with:
At the moment, we are interested in
libsimple_math.so.1.0.
Note how it matches the
SOVERSION variable in the
Makefile. Note also how we have chosen our symlinks.
We are effectively allowing
mytest to link with any future
libsimple_math.so.1.0.? (were our
simple_math library
to be upgraded to a new version) purely because of the way we have chosen
our symlinks. However, it will not link with any
library
libsimple_math.so.1.1.?, for example. As developers of
libsimple_math, we are deciding that libraries of a different
minor [For this example we are considering libraries to be
named
libname
.so.major
.minor
.patch]version number will be incompatible, whereas libraries of a different
patch level will not be incompatible.
We could also change SOVERSION to libsimple_math.so.1. This would effectively be saying that future libraries of different minor version numbers are compatible; only a change in the major version number would dictate incompatibility.
Then, edit the
/etc/ld.so.conf file and add a line
Then, reconfigure your libraries with
Finally, run your program with
ldconfig configures all libraries on the system. It recreates appropriate symlinks (as we did) and rebuilds a lookup cache. The library directories it considers are /lib, /usr/lib, and those listed in /etc/ld.so.config. The ldconfig command should be run automatically when the system boots and manually whenever libraries are installed or upgraded.
The LD_LIBRARY_PATH environment variable is relevant to every executable on the system and similar to the PATH environment variable. LD_LIBRARY_PATH dictates what directories should be searched for library files. Here, we appended /usr/local/lib to the search path in case it was missing. Note that even with LD_LIBRARY_PATH unset, /lib and /usr/lib will always be searched.
1 Creating DLL .so Files
Creating a DLL requires several changes to the Makefile on page
5 10 15 20 |
OBJS = simple_math_sqrt.o simple_math_pow.oLIBNAME = simple_mathSONAME = libsimple_math.so.1.0.0SOVERSION = libsimple_math.so.1.0CFLAGS = -Wall all: lib$(LIBNAME).so mytest mytest: lib$(LIBNAME).so mytest.o gcc $(CFLAGS) -o $@ mytest.o -L. -l${LIBNAME} lib$(LIBNAME).so: $(OBJS) gcc -shared $(CFLAGS) $(OBJS) -lc -Wl,-soname -Wl,$(SOVERSION) \ -o $(SONAME) && \ ln -sf $(SONAME) $(SOVERSION) && \ ln -sf $(SONAME) lib$(LIBNAME).so .c.o: gcc -fPIC -DPIC $(CFLAGS) -c -o $*.o $< clean: rm -f *.o *.a *.so mytest |
The -shared option to gcc builds our shared library. The -W options are linker options that set the version number of the library that linking programs will load at runtime. The -fPIC -DPIC means to generate position-independent code, that is, code suitable for dynamic linking.
After running make we have
|
lrwxrwxrwx 1 root root 23 Sep 17 22:02 libsimple_math.so -> libsimple_math.so.1.0.0lrwxrwxrwx 1 root root 23 Sep 17 22:02 libsimple_math.so.1.0 -> libsimple_math.so.1.0.0-rwxr-xr-x 1 root root 6046 Sep 17 22:02 libsimple_math.so.1.0.0-rwxr-xr-x 1 root root 13677 Sep 17 22:02 mytest |
2 DLL Versioning
You may observe that our three .so files are similar to the many files in /lib/ and /usr/lib/. This complicated system of linking and symlinking is part of the process of library versioning. Although generating a DLL is out of the scope of most system admin tasks, library versioning is important to understand.DLLs have a problem. Consider a DLL that is outdated or buggy: simply overwriting the DLL file with an updated file will affect all the applications that use it. If these applications rely on certain behavior of the DLL code, then they will probably crash with the fresh DLL. UNIX has elegantly solved this problem by allowing multiple versions of DLLs to be present simultaneously. The programs themselves have their required version number built into them. Try
|
ldd mytest |
|
libsimple_math.so.1.0 => ./libsimple_math.so.1.0 (0x40018000)libc.so.6 => /lib/libc.so.6 (0x40022000)/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) |
We could also change SOVERSION to libsimple_math.so.1. This would effectively be saying that future libraries of different minor version numbers are compatible; only a change in the major version number would dictate incompatibility.
3 Installing DLL .so Files
If you run ./mytest, you will be greeted with an error while loading shared libraries message. The reason is that the dynamic linker does not search the current directory for .so files. To run your program, you will have to install your library:
|
mkdir -p /usr/local/libinstall -m 0755 libsimple_math.so libsimple_math.so.1.0 \ libsimple_math.so.1.0.0 /usr/local/lib |
|
/usr/local/lib |
|
ldconfig |
|
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"./mytest |
ldconfig configures all libraries on the system. It recreates appropriate symlinks (as we did) and rebuilds a lookup cache. The library directories it considers are /lib, /usr/lib, and those listed in /etc/ld.so.config. The ldconfig command should be run automatically when the system boots and manually whenever libraries are installed or upgraded.
The LD_LIBRARY_PATH environment variable is relevant to every executable on the system and similar to the PATH environment variable. LD_LIBRARY_PATH dictates what directories should be searched for library files. Here, we appended /usr/local/lib to the search path in case it was missing. Note that even with LD_LIBRARY_PATH unset, /lib and /usr/lib will always be searched.
Bash Shell Scripting - 10 Seconds Guide
This note is referred by http://www.aboutlinux.info/2005/10/10-seconds-guide-to-bash-shell.html
This Bash shell scripting guide is not a detailed study but a quick reference to the BASH syntax. So lets begin...
... and press enter.
For example, if I do the following:
... I get the value (My login name) which is stored in the environment variable
syntax:
'if' condition also permits multi-way branching. That is you can evaluate more conditions if the previous condition fails.
Example :
Relational Operators
File related tests
String tests
A few Example snippets of using test
... which means, if the value in the variable d is equal to 25, print the value. Otherwise don't print anything.
In the above example, I have used square brackets instead of the keyword test - which is another way of doing the same thing.
... above, I have checked if both strings are not null then execute the echo command.
Things to remember while using test
Syntax:
The keywords here are in, case and esac. The ';;' is used as option terminators. The construct also uses ')' to delimit the pattern from the action.
Example:
Here is another example:
Case can also match more than one pattern with each option.You can also use shell wild-cards for matching patterns.
In the above case, if you enter YeS, YES,yEs and any of its combinations, it will be matched.
This brings us to the end of conditional statements.
Example:
The above code implements a infinite loop. You could also write 'while true' instead of 'while :' .
Here I would like to introduce two keywords with respect to looping conditionals. They are break and continue.
Syntax:
Example:
The above code is executed repeatedly until the file myfile can be read.
Example:
Here the list contains 5 numbers 1 to 5. Here is another example:
Suppose you have a directory full of java files and you want to compile those. You can write a script like this:
The above symbols are known as positional parameters. Let me explain the positional parameters with the aid of an example.
Suppose I have a shell script called my_script.sh . Now I execute this script in the command line as follows :
... as you can see above, I have passed 5 parameters to the script. In this scenario, the values of the positional parameters are as follows:
For example, try this:
Example :
To see the process Id of the current shell, try this:
Validate that it is the same value by executing the following command:
Make your shell script interactive.
An example -
Every command returns a value after execution. This value is called the exit status or return value of the command. A command is said to be
Linux Shell Scripting Tutorial @ Cyberciti.biz
Introduction to BASH Programming @ Tldp.org
BASH FAQ @ Greg's Wiki
BASH Pitfalls @ Greg's Wiki
Unix shell scripting resource @ Shelldorado
I hope you enjoyed reading this Bash shell scripting 10 seconds guide.
This Bash shell scripting guide is not a detailed study but a quick reference to the BASH syntax. So lets begin...
If you like this 10 seconds guide, don't forget to read -
Common environment variables
PATH - Sets the search path for any executable command. Similar to the PATH variable in MSDOS.HOME - Home directory of the user.MAIL - Contains the path to the location where mail addressed to the user is stored. IFS - Contains a string of characters which are used as
word seperators in the command line. The string normally consists of the
space, tab and the newline characters. To see them you will have to do
an octal dump as follows:$ echo $IFS | od -bc
PS1 and PS2 - Primary and secondary prompts in bash. PS1 is set to $ by default and PS2 is set to > . To see the secondary prompt, just run the command :$ ls |
... and press enter.
USER - User login name.TERM - indicates the terminal type being used. This should be set correctly for editors like Vim to work correctly.SHELL - Determines the type of shell that the user sees on logging in.
To see what are the values held by the above environment variables, just do an
echo of the name of the variable preceded with a $.For example, if I do the following:
$ echo $USER ravi
... I get the value (My login name) which is stored in the environment variable
USER.Some bash shell scripting rules
- The first line in your script must be
#!/bin/bash
... that is a#(Hash) followed by a!(bang) followed by the path of the shell. This line lets the environment know the file is a shell script and the location of the shell. - Before executing your script, you should make the script executable. You do it by using the following command:
$ chmod ugo+x your_shell_script.sh
- The name of your shell script must end with a
.sh. This lets the user know that the file is a shell script. This is not compulsary but is the norm.
Conditional statements
'if' Statement
The 'if' statement evaluates a condition which accompanies its command line.syntax:
if condition_is_true then //execute commands else //execute commands fi
'if' condition also permits multi-way branching. That is you can evaluate more conditions if the previous condition fails.
if condition_is_true then //execute commands elif another_condition_is_true then //execute commands else //execute commands fi
Example :
if grep "aboutlinux" thisfile.html then echo "Found the word in the file" else echo "Sorry no luck!" fi
if's companion - test
test is an internal feature of the shell. 'test' evaluates
the condition placed on its right, and returns either a true or false
exit status. For this purpose, 'test' uses certain operators to evaluate
the condition. They are as follows:Relational Operators
-eq- Equal to-lt- Less than-gt- Greater than-ge- Greater than or Equal to-le- Less than or Equal to
File related tests
-f file- True if file exists and is a regular file.-r file- True if file exists and is readable.-w file- True if file exists and is writable.-x file- True if file exists and is executable.-d file- True if file exists and is a directory.-s file- True if file exists and has a size greater than zero.
String tests
-n str- True if string str is not a null string.-z str- True if string str is a null string.str1 == str2- True if both strings are equal.str- True if string str is assigned a value and is not null.str1 != str2- True if both strings are unequal.-s file- True if file exists and has a size greater than zero.
-a- Performs the AND function-o- Performs the OR function
A few Example snippets of using test
test $d -eq 25 && echo $d
... which means, if the value in the variable d is equal to 25, print the value. Otherwise don't print anything.
test $s -lt 50 && do_something
if [ $d -eq 25 ] then echo $d fi
In the above example, I have used square brackets instead of the keyword test - which is another way of doing the same thing.
if [ $str1 == $str2 ]
then
//do something
fi
if [ -n "$str1" -a -n "$str2" ]
then
echo 'Both $str1 and $str2 are not null'
fi
... above, I have checked if both strings are not null then execute the echo command.
Things to remember while using test
- If you are using square brackets
[ ]instead oftest, then care should be taken to insert a space after the[and before the]. testis confined to integer values only. Decimal values are simply truncated.- Do not use wildcards for testing string equality - they are expanded by the shell to match the files in your directory rather than the string.
Case statement
Case statement is the second conditional offered by the shell.Syntax:
case expression in pattern1) //execute commands ;; pattern2) //execute commands ;; ... esac
The keywords here are in, case and esac. The ';;' is used as option terminators. The construct also uses ')' to delimit the pattern from the action.
Example:
... echo "Enter your option : " read i; case $i in 1) ls -l ;; 2) ps -aux ;; 3) date ;; 4) who ;; 5) exit esac
The last
case option need not have ;; but you can provide them if you want.Here is another example:
case `date |cut -d" " -f1` in Mon) commands ;; Tue) commands ;; Wed) commands ;; ... esac
Case can also match more than one pattern with each option.You can also use shell wild-cards for matching patterns.
... echo "Do you wish to continue? (y/n)" read ans case $ans in Y|y) ;; [Yy][Ee][Ss]) ;; N|n) exit ;; [Nn][Oo]) exit ;; *) echo "Invalid command" esac
In the above case, if you enter YeS, YES,yEs and any of its combinations, it will be matched.
This brings us to the end of conditional statements.
Looping Statements
while loop
while loop syntax -while condition_is_true do //execute commands done
Example:
while [ $num -gt 100 ] do sleep 5 done
while : do //execute some commands done
The above code implements a infinite loop. You could also write 'while true' instead of 'while :' .
Here I would like to introduce two keywords with respect to looping conditionals. They are break and continue.
break - This keyword causes control to break out of the loop.continue - This keyword will suspend the execution of all
statements following it and switches control to the top of the loop for
the next iteration.until loop
until complements while construct in the sense that the loop body here is executed repeatedly as long as the condition remains false.Syntax:
until false do //execute commands done
Example:
... until [ -r myfile ] do sleep 5 done
The above code is executed repeatedly until the file myfile can be read.
for loop
for loop syntax :for variable in list do //execute commands done
Example:
... for x in 1 2 3 4 5 do echo "The value of x is $x"; done
Here the list contains 5 numbers 1 to 5. Here is another example:
for var in $PATH $MAIL $HOME do echo $var done
Suppose you have a directory full of java files and you want to compile those. You can write a script like this:
... for file in *.java do javac $file done
Special symbols used in BASH scripting
$*- This denotes all the parameters passed to the script at the time of its execution. Which includes$1,$2and so on.$0- Name of the shell script being executed.$#- Number of arguments specified in the command line.$?- Exit status of the last command.
The above symbols are known as positional parameters. Let me explain the positional parameters with the aid of an example.
Suppose I have a shell script called my_script.sh . Now I execute this script in the command line as follows :
$ ./my_script.sh linux is a robust OS
... as you can see above, I have passed 5 parameters to the script. In this scenario, the values of the positional parameters are as follows:
$*- will contain the values 'linux','is','a','robust','OS'.$0- will contain the valuemy_script.sh- the name of the script being executed.$#- contains the value 5 - the total number of parameters.$$- contains the process ID of the current shell. You can use this parameter while giving unique names to any temporary files that you create at the time of execution of the shell.$1- contains the value 'linux'$2- contains the value 'is'
The set and shift statements
set - Lets you associate values with these positional parameters .For example, try this:
$ set `date` $ echo $1 $ echo $* $ echo $# $ echo $2
shift - transfers the contents of a positional parameter to
its immediate lower numbered one. This goes on as many times it is
called.Example :
$ set `date` $ echo $1 $2 $3 $ shift $ echo $1 $2 $3 $ shift $ echo $1 $2 $3
To see the process Id of the current shell, try this:
$ echo $$ 2667
Validate that it is the same value by executing the following command:
$ ps -f |grep bash
Make your BASH shell script interactive
read statement
Make your shell script interactive.
read will let the user
enter values while the script is being executed. When a program
encounters the read statement, the program pauses at that point. Input
entered through the keyboard id read into the variables following read,
and the program execution continues.An example -
#!/bin/sh echo "Enter your name : " read name echo "Hello $name , Have a nice day."
Exit status of the last command
Every command returns a value after execution. This value is called the exit status or return value of the command. A command is said to be
true if it executes successfully, and false if it fails. This can be checked in the script using the $? positional parameter.Resources for more detailed study of the BASH command
Linux Shell Scripting Tutorial @ Cyberciti.biz
Introduction to BASH Programming @ Tldp.org
BASH FAQ @ Greg's Wiki
BASH Pitfalls @ Greg's Wiki
Unix shell scripting resource @ Shelldorado
I hope you enjoyed reading this Bash shell scripting 10 seconds guide.
A look at Smart Pointers
There is lot of confucion, misconceptions and misunderstanding
regarding smart pointers. After looking at various books and tutorials, i
got quite confused till I managed to figure out what they exactly are:
Smart pointers are objects that look and feel like pointers, but are smarter.
To look and feel like pointers, smart pointers need to have the same interface that pointers do: they need to support pointer operations like dereferencing (operator *) and indirection (operator ->). An object that looks and feels like something else is called a proxy object, or just proxy.
To be smarter than regular pointers, smart pointers need to do things that regular pointers don't. What could these things be? Probably the most common bugs in C++ (and C) are related to pointers and memory management: dangling pointers, memory leaks, allocation failures and other joys. Having a smart pointer take care of these things.
The simplest example of a smart pointer is auto_ptr, which is included in the standard C++ library. You can find it in the header , or take a look at Scott Meyers' auto_ptr implementation. Here is part of auto_ptr's implementation, to illustrate what it does:
Smart pointers are objects that look and feel like pointers, but are smarter.
To look and feel like pointers, smart pointers need to have the same interface that pointers do: they need to support pointer operations like dereferencing (operator *) and indirection (operator ->). An object that looks and feels like something else is called a proxy object, or just proxy.
To be smarter than regular pointers, smart pointers need to do things that regular pointers don't. What could these things be? Probably the most common bugs in C++ (and C) are related to pointers and memory management: dangling pointers, memory leaks, allocation failures and other joys. Having a smart pointer take care of these things.
The simplest example of a smart pointer is auto_ptr, which is included in the standard C++ library. You can find it in the header , or take a look at Scott Meyers' auto_ptr implementation. Here is part of auto_ptr's implementation, to illustrate what it does:
template <class T> class auto_ptr { T* ptr; public: explicit auto_ptr(T* p = 0) : ptr(p) {} ~auto_ptr() {delete ptr;} T& operator*() {return *ptr;} T* operator->() {return ptr;} // ...};
As you can see, auto_ptr is a simple wrapper around a regular pointer. It forwards all meaningful operations to this pointer (dereferencing and indirection). Its smartness in the destructor: the destructor takes care of deleting the pointer.
Lets look at a proper example:
#include<iostream> #include<memory> using namespace std; class A { public: int *data; string name; A(string n): name(n) { cout<<"Constructor of A = "<<name.c_str()<<" called "<<endl; data = new(int); }; A(string n, int x): name(n) { cout<<"Overloaded Constructor of A = "<<name.c_str()<<" called "<<endl; data = new(int); *data = x; }; ~A() { cout<<"Destructor of A = "<<name.c_str()<<" called "<<endl; delete(data); data = this->data; data = NULL; } A* operator ->() { return this;}; }; void someFunc() { auto_ptr<A> a1(new A("a1")); cout<<"Enter a number and press enter: "; cin >> (*a1->data); cout << "a1->data = "<<*a1->data<<endl; A a2("a2",25); A *a3 = new A("a3"); } int main() { cout<<"Before SomeFunc()"<<endl; someFunc(); cout<<"After SomeFunc()"<<endl; return 0; }
The output is as follows:

As you have probably noticed, the instance a3 is never deleted and will cause memory leaks. Using smart pointer would automatically delete the instance a3 and the memory associated with it.
You can read Smart Pointers in much more detail at the References below.
References:
http://ootips.org/yonat/4dev/smart-pointers.html
http://www.geekpedia.com/tutorial47_Smart-Pointers---Part-1.html
http://www.geekpedia.com/tutorial59_Smart-Pointers---Part-II.html
Special macros in Makefile
Now all those $@ thingees that appear in the example above
and elsewhere in the makefile are clearly not plain old macros, since
they're never defined and yet this makefile works quite well, I
promise. The reason is that there are a number of special macros with
one character names that are only useable as part of a dependency
rule:
- $@
- The file name of the target.
- $<
- The name of the first dependency.
- $*
- The part of a filename which matched a suffix rule.
- $?
- The names of all the dependencies newer than the target separated by spaces.
- $^
- The names of all the dependencies separated by spaces, but with duplicate names removed.
- $+
- The names of all the dependencies separated by spaces with duplicate names included and in the same order as in the rule.
Subscribe to:
Comments (Atom)