Friday, September 7, 2007

Debugging

Debugging is a major part of any coding project, large or small. Many a student has stayed up until the wee hours of the morning trying to figure out why their program churns out the wrong output. It can be a long, frustrating ordeal during the process but after the insight dawns or the bug reveals its source, it's like winning the lottery. Our backend code base is primarily in C and C++ and since we're a Linux shop, we do most of our debugging using a tool called gdb ("The GNU Debugger"). We employ a number of techniques to help us track down bugs and I thought I'd share a few with you.

Corefiles are very important. A core file (or core dump) is basically a nice snapshot of the state of the program after it's crashed. When you compile your program into its executable state, you can also add in debugging symbols, which gives the developer function names and variable names to work with when poring through the core file. We keep track of when core files are produced and how often, so we can track down the most common bugs. To use gdb to see the contents of the core file, you'll have to pass in the original binary and the corefile, e.g. gdb path/to/binary corefile and then you can go about tracing through the snapshot.

Sometimes you may want to debug a program as its running, and not after it has crashed. In that case you can employ different techniques.

To get a deeper look at the program's execution, you can also use gdb to "attach" to the running program. Attaching to a running process allows you to set breakpoints, look at backtraces, and do all the normal things you would do if you started the program using the debugger. Be careful though because gdb will stop the program when you attach, you'll have to use "continue" or detach (by exiting) to continue execution. To do this, you can use gdb path/to/binary 1234 (if 1234 is the process ID -- you can find this out by using the ps command). This technique is really only useful if you have debugging information compiled into your program (otherwise you'll see a lot of ???? where you'd expect to see function names =p), so just keep that in mind.

Another tool you can use is called strace. strace allows you to see the system calls (requests made to the operating system) your program is making. This is useful when perhaps your program seems to be taking up too much CPU or memory, and strace can attach to the running program without slowing it down too much. And, it works even if you don't have debugging symbols. The one downside is that you don't get to see any of your own calls.

One last tip is that sometimes you may not want to compile debugging information into your binary. In that case there is a way to have your cake and eat it too. Using strip (or eu-strip if your version of strip hasn't been updated) you can have your symbols in a different file than the normal binary. gdb will automatically load the symbols from the other file as long as it's in the right place. If you've moved it, you can pass --symbols=SYMFILE to let gdb know where to find it.

Hope that helps!

--
Warm regards
Saurabh Tiwari

Thursday, August 23, 2007

BUBBLE SORT

`/*

* Written By: Saurabh Tiwari

* Date: 11th May 2006

*
* Sorts a binary file using a Random Access External Sort. Uses the

* BUBBLE SORT algorithm (a simplified version of the SHELL SORT algorithm)

* to swap records in the file

*

*/



#include // includes



class person_rec

{

friend class

donor_class;

private:

int id;

char name[20];

float fund;

};



class donor_class

{

private:

long num_of_rec;



public:

donor_class();

void bubble_sort();

void display();

};



//-----------------------------------------------------------------------



void main (void)

{

donor_class donor;

cout << "This is the file before sorting...\n\n";

donor.display();

donor.bubble_sort();

cout << "\nThis is the file after sorting...\n\n";

donor.display();

} // main



//-----------------------------------------------------------------------



donor_class::donor_class ()

{

person_rec rec;

fstream bifile ("a:\\a57h3g4.dat", ios::in | ios::binary);

bifile.seekg (0L, ios::end);

num_of_rec = bifile.tellg()/sizeof (rec);

cout << num_of_rec;

bifile.close();

} // constructor



//-----------------------------------------------------------------------



void donor_class::bubble_sort()

// swaps records into increasing order in a binary file

{

int i, not_sorted;

person_rec person1, person2, rec;

fstream bifile ("a:\\a57h3g4.dat", ios::in | ios::out | ios::binary);



do

{

not_sorted = 0;

for (i = 0; i < num_of_rec - 1; i = i + 1)

{

bifile.seekg ((i*sizeof(rec)), ios::beg);

bifile.read ((char *) &person1, sizeof (rec));

bifile.seekg (((i+1)*sizeof(rec)), ios::beg);

bifile.read ((char *) &person2, sizeof (rec));

if (person1.id > person2.id)

{

bifile.seekp ((i*sizeof(rec)), ios::beg);

bifile.write ((char *) &person2, sizeof (rec));

bifile.seekp (((i+1)*sizeof(rec)), ios::beg);

bifile.write ((char *) &person1, sizeof (rec));

not_sorted = 1;

} // if

} // for

}

while (not_sorted);



bifile.close();

} // bubble_sort



//-----------------------------------------------------------------------



void donor_class::display ()

// displays the file to the screen

{

person_rec person;



fstream infile ("a:\\a57h3g4.dat", ios::in | ios::binary);



while (infile.read((char *) &person, sizeof(person)))

{

cout << "ID: " << person.id << " Name: " << person.name;

cout << " Amount: $" << person.fund << endl;

} // while



infile.close();

} // display

Insertion Sort

/* Question 2 Insertion Sort Algorithm

Description: Sorts ten names and coressponding telephone numbers

using a database to add names to the list, in decending order.

Files:

ASCII File = amx.dat found on a:\\ drive

CPP File = a57q1.cpp

Date: 17/9/2001 (Final Revision) */



#include // automacically includes

#include // for scrcmp function



int size; // size of the list



class List_class // class named List_class

{

private:

char name[30][10],phone[30][10]; //private data mebers for name and telephone numbers

public:

List_class(); //methods

void to_screen(int &pinhead);

void insertion_sort(char newname[],char newnumber[]);

};



//------------------------------------------------------------------



void main (void)

{

List_class name_list; // declaration of List_class object name_list

char newname[30],newnumber[10];

cout << "This is the list: \n"<
name_list.to_screen(size); // display to screen



cout << "Enter a new name to add to the list or -1 to exit:"; // prompt for new name

cin >> newname; // get the info

cout << "Enter a corresponding phonenumber to add to the list: "; //prompt for new telephone number

cin >> newnumber; //get the info



while(strcmp(newname,"-1")!=0) // while statement breaks on -1

{

name_list.insertion_sort(newname,newnumber) ; // insert new name correctly ordered

name_list.to_screen(size); // displays list to screen

cout << endl; // them's the breaks kid!

cout << "Enter a new name to add to the list or -1 to exit: ";

cin >> newname;

if (strcmp(newname,"-1")!=0)

{

cout << "Enter a coressponding phonenumber to add to the list: ";

cin >> newnumber;

} // end if

} // end while

}// end main



//---------------------------------------------------------



List_class::List_class() //reads the list in from a file

{

int a ; // tags the postition in the for loop

size = 0; //preliminary inialization

fstream infile ("a:/qu2/a57q2a.dat",ios::in); // call the data file named infile



for(a = 0;a < 10;a = a + 1) // for loop

{

infile >> name[a] >> phone[a]; // read the list

size++; //increment size

}// end for

infile.close(); // close the file

}// end constructor



//----------------------------------------------------------------



void List_class::to_screen(int &pinhead) //displays the list to the screen

{

int a, array; // tag the elements

array = pinhead; // inialization of array to max



fstream outfile("a:/qu2/a57q2b.dat",ios::out); // record new values

for(a = 0; a < array; a = a + 1) // for loop

{

cout<< name[a] << " "<< phone[a] << endl; // display name and telephone number to screen

outfile << name[a] << " " << phone[a] << endl; //write to file new.dat

}// end for

outfile.close(); // close the file

}// end to_screen



//---------------------------------------------------------------



void List_class::insertion_sort(char newname[],char newnumber[]) //sorts a new name into the sorted list

{

int old,spot = 0,spotfound = 0; // insertion sort mehtod variables





while (!spotfound && spot < size) // while loop while breaks if spot is not found and spot is less than size

{

if (strcmp(newname, name[spot])>0) // tests name position spot with newname

{

spotfound = 1; // true

}

else

{

spot = spot + 1; // move on

}// end if

}// end while

for (old = size; old > spot; old = old -1) //for loop

{

strcpy(name[old], name[old-1]); // copy name from old-1 into old variable

strcpy(phone[old], phone[old-1]); //coressponding telephone numbers

}// end for

size = size +1; //increment size



strcpy(name[spot], newname); // copies newname into name

strcpy(phone[spot], newnumber); //coressponding telephone numbers



}// end insertion_sort

Selection Sort

/* Question 1 Selection Sort Algorithm

Subject: Algorithms and Data Structures - Sorting and searching

Description: Sorts ten names and coressponding telephone numbers

Files:

ASCII File = a57q1.dat found on a:\\ drive

CPP File = a57q1.cpp

Date: 17/9/2001 (Final Revision) */



#include // automacically includes

#include // for strcmp function

#define size 10 // defines the maximum amount of numbers possible



class List_class // class called List_class

{

private:

long num[size]; // private data member for the telephone numbers

char words[size][30]; // private data member for the names

public:

List_class(); // public code members

void to_screen(); // code member for displaying list to screen

void num_selection_sort(); // code member for the sorting of telephone numbers

void word_selection_sort(); // code member sorting the names with coressponding telephone numbers



};



//-------------------------------------------------------



void main(void) // main program builder

{

List_class words_list; // declaration of List_class object words_list



cout << "This is the list: " << endl << endl; // descriptive heading



words_list.to_screen(); //print the unsoted list to screen



cout << "\n\nThis is the sorted list: " << endl << endl; // descriptive heading



words_list.word_selection_sort(); // sort the list

words_list.to_screen(); // print the sorted list to screen

} // end main



//-------------------------------------------------------



List_class::List_class() //read the list in from a file

{

int a; // integer for for loop that tags the array locations



fstream infile("a:\\a57q1.dat",ios::in); // file to be used in A drive named infile for a57q1.dat



for(a=0;a
{

infile >> words[a] >> num[a]; // reads the list from a file words[position] number[position]

}// end for

infile.close(); //close the file

} //constructor



//-------------------------------------------------------



void List_class::to_screen() //displays the list to the screen

{

int a; // // integer for for loop that tags the array locations

for(a=0;a
{

cout << words[a] << " " << num[a] << " "; // display the words and numbers

}// end for

}// end to screen



//----------------------------------------------------------------------------------------



void List_class::word_selection_sort() //sorts the array into increasing order

{

int i, j, loc_of_min; // three integers here track the word locations

long tphone, minp; // longs for coressponding telephone numbers

char min[30], temp[30],name[30]; // chars for name sorting

for(i=0;i
{

strcpy(min,words[i]); // copy min to words position i

minp = num[i]; // telphone numners minp is equal to num position i

loc_of_min = i; // the location of min equal i

for(j=i+1;j
{

if(strcmp(words[j],min)>0) // test words[j] with min to see if it is less than

{ // if true

strcpy(min,words[j]); //copy min value to words[j]

minp = num[j]; // coressponding telephone numnbers

loc_of_min=j; // location of min equals j

} // end if

}// end for

if(strcmp(min,words[i])>0) // if statement comparing min to see if it is less than words position i

{ // if true

strcpy(temp,words[i]); //copy temp to words position i

tphone = num[i]; // coressponding telephone numbers

strcpy(words[i],min); // copy words position i to min

num[i]= minp; // coressponding telephone numbers

strcpy(words[loc_of_min],temp); // copy words position location of min to temp

num[loc_of_min] = tphone; // coressponding telephone numbers

}// end if

}// end for

}// end selection sort

Coordinate system display. and other Calculations on it

#include
#include
using namespace std;
class point
{
protected:
float x,y;

public:
void setpoint(float x1,float y1)
{
x=x1;
y=y1;
}
void showpoint()
{
cout<<"x coodinate="< }
point getpoint()
{
point t;
t.x=x;
t.y=y;

return t;
}
float getx()
{
return x;
}
float gety()
{
return y;
}
};
#include
using namespace std;
class expoint:public point
{
private:
float x,y;
expoint()
{
x=getx();
y=gety();
}

float distance(expoint p1)
{
float d;
d=sqrt(pow(((x)-(p1.x)),2)+pow(((y)-(p1.y)),2));
return d;
}
point section(expoint p1,int n,int d)
{
point m;
m.x=(n*p1.x+d*x)/(n+d);
m.y=(n*p1.y+d*y)/(n+d);
return m;
}






};
int main()
{
point a,b,c;
a.setpoint(4,4);
a.showpoint();
expoint a1(a);
float l;
b.setpoint(4,4);
b.showpoint();
l=a1.distance(b);
cout< c=a1.section(b,1,1);
c.showpoint();
return 0;
}

Friday, July 20, 2007

Programming

Program to write and edit details of student into a file.



#include
#include
using namespace std;
struct student
{
char name[20];
int roll;
char phone[15];
};
int main()
{
student a;
ofstream f1("student.bin",ios::out|ios::binary);
for(int i=1;i<=3;i++)
{
cout<<"enter name,roll,phone number\n";
cin.getline(a.name,20);
cin>>a.roll;
cin.get();
cin.getline(a.phone,15);
f1.write((char*)&a,sizeof(a));

}
f1.close();
ifstream f("student.bin",ios::in|ios::binary);
f.seekg(0);

for(int i=1;i<=3;i++)
{
f.read((char*)&a,sizeof(a));
cout< cout< cout<
}
f.close();
}