debug newbie question

C

Caldwell

i want to know what would be the easiest way to visualize how a MS VC++
debugger works?
i have this program which has many classes and functions, i want to see how
variables change step by step.

i tried step over, but it only shows the "step" in main()

what i would like to see is how things actally works within function.
simple instruction will be greatly appreciated.

thank you

cald
 
M

Mike Wahler

Caldwell said:
i want to know what would be the easiest way to visualize how a MS VC++
debugger works?
i have this program which has many classes and functions, i want to see how
variables change step by step.

i tried step over, but it only shows the "step" in main()

what i would like to see is how things actally works within function.
simple instruction will be greatly appreciated.

Your query is not about C++, but about how to use
a Microsoft product, so it's not topical here.

VC++ experts who will be happy to help you out hang out
at newsgroup: microsoft.public.vc.debugger

-Mike
 
J

John Harrison

Caldwell said:
i want to know what would be the easiest way to visualize how a MS VC++
debugger works?
i have this program which has many classes and functions, i want to see how
variables change step by step.

i tried step over, but it only shows the "step" in main()

what i would like to see is how things actally works within function.
simple instruction will be greatly appreciated.

thank you

cald

Perhaps you should try 'step into' instead of 'step over'.

john
 
C

Caldwell

It is not anything API related in this program. All it does is finding the
numerical results, but it had many classes which I would be interested to
look into when the program is running.

I tried step into and step over... but you are right. After I press servral
times of F10 (step into F11), I see a bunch of machine code.
that will show you the assembler code that implements your source code.

May i show you how it is like? you do not need to look what this program
does. I would like to know if VC++ debugger will allow me to see through
the program statement by statement in this program.

Thank you








#include <stdlib.h> //directives needed for this program
#include <limits.h>
#include <math.h>
#include <iostream.h>
#include <iomanip.h>
#include <assert.h>

#define DATA_UNIT 53 // data length unit
#define FRAME_LENGTH 32*24 // bytes/frame, 768 bytes
// [bitrate=2Mbps;frame period = 3msec
#define FRAME_TIME 3 // [msec]
#define OVER_HEAD 6 // mini slot size
#define NUM_OF_MINISLOT 3
#define MAX_TRANS_QUEUE 1000 //default
#define ALL_TERMINAL_QUEUE 32768L //default maximum for random



////////////////////////////////////////////////////////////////////////////
///////////////////////////


////////////////////////////////////////////////////////////
// Random Generator Class
//
// This class is for generation of random numbers
..
////////////////////////////////////////////////////////////

class CRandom {
unsigned long Seed;
public:
CRandom(unsigned long x=1L) : Seed(x) {}
unsigned long IRand(void); // long interger random
double RRand(void); // 0.0-1.0 random
double ExpRand(void); // 0.0-1.0 exponentail distribution
random
};

inline unsigned long CRandom::IRand(void) // use inline for small but
{ //frequently used function
Seed = Seed * 1566083941UL + 1;
return(Seed);
}

inline double CRandom::ExpRand(void)
{
return(-log(1.0 - RRand()));
}

inline double CRandom::RRand(void)
{
return((1.0 / (ULONG_MAX + 1.0)) * IRand());
}

////////////////////////////////////////////////////////////////////////////
/////////////////////////////


////////////////////////////////////////////////////////////
// Performance Monitor Class
//
// This class is for monitor of the number of transmitted
// packets and their delay.
////////////////////////////////////////////////////////////

class CMonitor {
double TotalPacket;
double TotalDelay;
double TotalDelaySqr;

public:
CMonitor() :
TotalPacket(0), TotalDelay(0), TotalDelaySqr(0) {} //public that can
be accessed from other functions
void Initialize(void);
void CheckPerformance(double);

double GetNumOfTotalPacket(void) const;
double GetDelay(void) const;
double GetDelayVariance(void) const;
};

inline double CMonitor::GetNumOfTotalPacket(void) const
{
return(TotalPacket);
}

inline double CMonitor::GetDelay(void) const
{
return (TotalPacket > 0) ? TotalDelay/TotalPacket : 0;
}

inline double CMonitor::GetDelayVariance(void) const
{
return (TotalPacket > 0) ?
sqrt(TotalDelaySqr/TotalPacket -
TotalDelay*TotalDelay/TotalPacket/TotalPacket) : 0;
}

void CMonitor::Initialize(void) //recursion call #1
{
TotalPacket = 0;
TotalDelaySqr = 0;
TotalDelay = 0;
}

void CMonitor::CheckPerformance(double Delay) //call #2
{
TotalPacket += 1;
Delay += DATA_UNIT; // Add Transmission Delay
TotalDelay += Delay;
TotalDelaySqr += Delay * Delay;
}


////////////////////////////////////////////////////////////
// Packet Structure Definition, reference from p.347 of
// h.m. deitel/p.j deitel "How to program in C++"
//
struct CPacket {
int Size; //member types
double Time;
CPacket() : Size(0), Time(0) {}
};

////////////////////////////////////////////////////////////////////////////
/////////////

////////////////////////////////////////////////////////////
// Terminal Class
//
// This class discribes the behavior of each terminal,
// such as queuing and transmission of packets.
//
////////////////////////////////////////////////////////////////////////////
/////////////

class CTerminal {
int QueueSize;
CPacket* Queue;
int wp; //dummy variable wp, rp
int rp;
int NumOfPacket;
int NumOfReserved;
public:
CTerminal():
Queue(NULL), QueueSize(0), wp(0), rp(0),
NumOfPacket(0), NumOfReserved(0) {}
~CTerminal() {delete [] Queue;}
void Initialize(int queue_size);
int CheckBuffer(void) const;
int PacketArrival(const CPacket&);
void ChannelReserve(void);
void ChannelAllocate(double Time, CMonitor* Monitor=NULL);
private:
CTerminal(const CTerminal&);
CTerminal& operator = (const CTerminal&);
};

inline int CTerminal::CheckBuffer(void) const
{
return (NumOfPacket > NumOfReserved) ?
(NumOfPacket - NumOfReserved) : 0; //checking the buffer
size, if needed
}

inline void CTerminal::ChannelReserve(void)
{
NumOfReserved++;
}

void CTerminal::Initialize(int queue_size)
{
assert(queue_size > 0);

QueueSize = queue_size;
wp = 0;
rp = 0;
NumOfPacket = 0;
NumOfReserved = 0;

delete [] Queue;
if (NULL == (Queue = new CPacket[QueueSize])) {
cerr << "Memory Allocation Error in CTerminal" << endl;
exit(-1);
}
}


int CTerminal::packetArrival(const CPacket& Packet) //this describes the
packet arriving
{ //to one terminal and check for overflow
if (Packet.Size > 0) {
if ((rp - wp - 1 + QueueSize) % QueueSize != 0) {
Queue[wp] = Packet;
NumOfPacket += Queue[wp].Size;
wp = (wp + 1) % QueueSize;
return(1); //hang the program
} else {
cerr << "Packet User Queue Over Flow!!!" << endl;
}
}
return(0);
}

void CTerminal::ChannelAllocate(double Time, CMonitor* Monitor)
{
if (--NumOfReserved < 0) {
cerr << "reservation error in Terminal" << endl;
exit(-1);
}

if (rp != wp) {
const double Delay = Time - Queue[rp].Time;
Queue[rp].Size -= 1;
NumOfPacket -= 1;
if (Monitor) {
Monitor->CheckPerformance(Delay);
}
if (Queue[rp].Size == 0) {
rp = (rp + 1) % QueueSize;
}
}
}

////////////////////////////////////////////////////////////////////////////
/////////////////

////////////////////////////////////////////////////////////
// Traffic Source Class
//
// This class discribes the behavior of traffic source.
// Call GenerateTraffic function to generate packets
// and set them to each terminal.
/////////////////////////////////////////////////////////////


class CSource {
int NumOfTerminal;
CTerminal* Terminal;
double NextEventTime;
double AveArrivalTime;
double AveServiceTime;
CRandom NodeRand;
CRandom ArrivalRand;
CRandom ServiceRand;
public:
CSource():
NumOfTerminal(0), Terminal(NULL),
NextEventTime(0), AveArrivalTime(0), AveServiceTime(0),
NodeRand(rand()), ArrivalRand(rand()), ServiceRand(rand()) {}
void Association(int, CTerminal[]);
void SetParameter(double, double);
int GenerateTraffic(double);
};

void CSource::Association(int n, CTerminal terminal[])
{
assert(n > 0);

NumOfTerminal = n;
Terminal = terminal;
}

void CSource::SetParameter(double arrival, double service)
{
assert(arrival > 0 && service > 0);

AveArrivalTime = arrival;
AveServiceTime = service;
NextEventTime += AveArrivalTime * ArrivalRand.ExpRand(); //packet
arrival
}

int CSource::GenerateTraffic(double Time)
{
int n=0;

while (NextEventTime < Time) {
CPacket Packet;
Packet.Size = ceil(AveServiceTime * ServiceRand.ExpRand());
Packet.Time = NextEventTime;
NextEventTime += AveArrivalTime * ArrivalRand.ExpRand();
int No = NodeRand.IRand() % NumOfTerminal;
if (No < 0) {
No = 0;
} else if (No >= NumOfTerminal) {
No = NumOfTerminal - 1;
}
Terminal[No].PacketArrival(Packet);
n++;
}
return(n);
}

////////////////////////////////////////////////////////////////////////
// Reservation Queue Class
//
// This class discribes the behavior of Reservation Queue.
// Call SetLeaf and MakeTree functions to make up a contention tree.
// Then, call Pop function to get a contention result of each mini slot.
//
// Reference class with some modifications
// Still need time to modify this class, Collision at a junction point?
//
////////////////////////////////////////////////////////////////////////

class CReservationQueue {
enum {IDLE=0, BUSY=1, COLLISION=2};
typedef unsigned char NodeData;
struct Position {int x, y;};
private:
int Height;
NodeData** Node;
int Depth;
int Ptr;
Position* Stack;
public:
CReservationQueue():
Height(0), Node(NULL), Depth(0), Ptr(0), Stack(NULL) {}
~CReservationQueue();
void Initialize(int);
void SetLeaf(int i, int n);
void MakeTree(void);
int Pop(int&);
protected:
int PushBranch(int, int);
int PopBranch(int&, int&);
private:
CReservationQueue(const CReservationQueue&);
CReservationQueue& operator = (const CReservationQueue&);
};

inline void CReservationQueue::SetLeaf(int i, int n)
{
Node[Height] = (n > 0) ? BUSY : IDLE;
}

CReservationQueue::~CReservationQueue()
{
if (Node) {
for (int i=0;i<=Height;i++) {
delete [] Node;
}
}
delete [] Node;
delete [] Stack;
}

void CReservationQueue::Initialize(int n)
{
assert(n > 0);

if (Node) {
for (int i=0;i<=Height;i++) {
delete [] Node;
}
}
delete [] Node;
delete [] Stack;

Height = n;
Depth = n + 1;
Ptr = 0;

if (NULL == (Stack = new Position[Depth]) || NULL == (Node = new
NodeData*[Height+1])) {
cerr << "Memory Allocation Error in CReservationQueue" << endl;
exit(-1);
}

int NumOfNode = 1;
for (int i=0;i<=Height;i++) {
if (NULL == (Node = new NodeData[NumOfNode])) {
cerr << "Memory Allocation Error in CReservationQueue" << endl;
exit(-1);
}
for (int j=0;j<NumOfNode;j++) Node[j] = IDLE;
NumOfNode *= 2;
}
}

void CReservationQueue::MakeTree(void)
{
static const NodeData TABLE[3][3] // status of the three minislot
= { {IDLE, BUSY, COLLISION},
{BUSY, COLLISION, COLLISION},
{COLLISION, COLLISION, COLLISION} };

int NumOfNode = 1;
for (int i=0;i<Height-1;i++) NumOfNode *= 2;

for (i=Height-1;i>=0;i--) {
for (int j=0;j<NumOfNode;j++) { //with help of a freind
NodeData Left = Node[i+1][j*2];
NodeData Right = Node[i+1][j*2+1];
Node[j] = TABLE
;
}
NumOfNode /= 2;
}

Ptr = 0;
if (Node[0][0] != IDLE) {
PushBranch(0, 0);
}
}

int CReservationQueue::pushBranch(int x, int y)
{
if (Ptr < Depth) {
Stack[Ptr].x = x;
Stack[Ptr].y = y;
Ptr++;
return(1);
} else {
cerr << "Reservation Queue Over Flow!!!" << endl;
return(0);
}
}

int CReservationQueue::popBranch(int& x, int& y)
{
if (Ptr > 0) {
Ptr--;
x = Stack[Ptr].x;
y = Stack[Ptr].y;
return(1);
} else {
return(0);
}
}

int CReservationQueue::pop(int& adr)
{
int x, y;

if (PopBranch(x, y)) {
if (Node[x][y] == COLLISION) {
PushBranch(x+1, 2*y+1);
PushBranch(x+1, 2*y);
adr = -1;
} else if (Node[x][y] == BUSY) {
while (x < Height) {
x++;
y*=2;
if (Node[x][y] == IDLE) y++;
}
if (Node[x][y] != BUSY) {
cerr << "Reservation Queue Pop Error!!!" << endl;
}
adr = y;
} else {
adr = -2;
}
} else {
adr = -3;
}

return (Ptr > 0);
}

////////////////////////////////////////////////////////////////////////////
///////////////////////

///////////////////////////////////////////////////////////////
// Transmission Queue Class
//
// This class discribes the behavior of Transmission Queue.
// This is a simple FIFO queue.
// Call Push function to push a node number which succeeds in
// mini slot access.
// Call Pop function to get a node number which can send data
// in each data slot.
//
////////////////////////////////////////////////////////////////

class CTransmissionQueue {
int* Queue;
int MaxQueue;
int wp, rp;
public:
CTransmissionQueue():Queue(NULL), MaxQueue(0), wp(0), rp(0) {}
~CTransmissionQueue() {delete [] Queue;}
void Initialize(int);
int IsFull(void) const;
int Push(int);
int Pop(int&);
private:
CTransmissionQueue(const CTransmissionQueue&);
CTransmissionQueue& operator = (const CTransmissionQueue&);
};

inline int CTransmissionQueue::IsFull(void) const //Call IsFull function to
check whether queue
{
return ((rp-wp-1+MaxQueue) % MaxQueue == 0); //is full or not.
}

void CTransmissionQueue::Initialize(int n)
{
assert(n > 0);

MaxQueue = n;
wp = rp = 0;

delete [] Queue;
if (NULL == (Queue = new int[MaxQueue])) {
cerr << "Memory Allocation Error in CTransmissionQueue" << endl;
exit(-1);
}
}

int CTransmissionQueue::push(int n)
{
if ((rp - wp - 1 + MaxQueue) % MaxQueue != 0) {
Queue[wp] = n;
wp = (wp + 1) % MaxQueue;
return(1);
} else {
cerr << "Transmission Queue Over Flow!!!" << endl;
return(0);
}
}

int CTransmissionQueue::pop(int& n)
{
if (wp != rp) {
n = Queue[rp];
rp = (rp + 1) % MaxQueue;
return(1);
} else {
return(0);
}
}

////////////////////////////////////////////////////////////
// Controller Class
//
// This class discribes the behavior of controller.
// Call Schedule function for each slot access.
//
/////////////////////////////////////////////////////////////


class CController {
CSource* Source;
int NumOfTerminal;
CTerminal* Terminal;
int MiniSlot;
CReservationQueue RsrvQueue;
CTransmissionQueue TrnsQueue;
public:
CController(int mini_slot):
Source(NULL), NumOfTerminal(0), Terminal(NULL), MiniSlot(mini_slot)
{}
~CController() {}
void Association(CSource&, int, CTerminal[]);
int Schedule(double Time, CMonitor* Monitor=NULL);
private:
CController(const CController&);
CController& operator = (const CController&);
};

void CController::Association(CSource& source, int n, CTerminal terminal[])
{
assert(n > 0 && n < 15);

Source = &source;

NumOfTerminal = 1;
for (int i=0;i<n;i++) NumOfTerminal *= 2;
Terminal = terminal;

RsrvQueue.Initialize(n);
TrnsQueue.Initialize(MAX_TRANS_QUEUE);
}

int CController::Schedule(double Time, CMonitor* Monitor) //modified by
KinHo Wong
{
static int IsNextPacket=1;
int No;

if (TrnsQueue.Pop(No)) {
Terminal[No].ChannelAllocate(Time, Monitor);
}
for (int i=0;i<MiniSlot;i++) {
if (!TrnsQueue.IsFull()) {
int next = RsrvQueue.Pop(No);
if (No >= 0) {
Terminal[No].ChannelReserve();
TrnsQueue.Push(No);
}
if (next == 0)

{
int IsNewPacket =
Source->GenerateTraffic(Time+DATA_UNIT+i*OVER_HEAD);
if (IsNextPacket || IsNewPacket) {
IsNextPacket = 0;
for (int j=0;j<NumOfTerminal;j++) {
int k = Terminal[j].CheckBuffer();
RsrvQueue.SetLeaf(j, k);
if (!IsNextPacket && k > 1) IsNextPacket = 1;
}
RsrvQueue.MakeTree();
}
}
}
}
return (MiniSlot * OVER_HEAD + DATA_UNIT);
}

////////////////////////////////////////////////////////////////////////////
//////////////////////////////

////////////////////////////////////////////////////////////////////////
// CSimulation Class
//
// This class discriber the behavior of all simulation.
// CSource, CTerminal, and CController class are associated
// and Simulation is executed.(Still working on this as on 5/8/2003
****************************
//
////////////////////////////////////////////////////////////////////////

class CSimulation {
long FrameLength;
CSource Source;
int NumOfTerminal;
CTerminal* Terminal;
CController Controller;
CMonitor Monitor;
public:
CSimulation() :
FrameLength(0), NumOfTerminal(0), Terminal(NULL),
Controller(NUM_OF_MINISLOT) {}
~CSimulation() {delete [] Terminal;}
void Initialize(int, long);
void Run(long, int, double, double);
private:
CSimulation(const CSimulation&);
CSimulation& operator = (const CSimulation&);
};

void CSimulation::Initialize(int n, long frame_length)
{
assert(n > 0 && n < 15);

FrameLength = frame_length;

NumOfTerminal = 1;
for (int i=0;i<n;i++) NumOfTerminal *= 2;

delete [] Terminal;
if (NULL == (Terminal = new CTerminal[NumOfTerminal])) {
cerr << "Memory Allocation Error in CSimulation" << endl;
exit(-1);
}

int QueueSize = ALL_TERMINAL_QUEUE / NumOfTerminal;
for (i=0;i<NumOfTerminal;i++) {
Terminal.Initialize(QueueSize);
}

Source.Association(NumOfTerminal, Terminal);
Controller.Association(Source, n, Terminal);
}

void CSimulation::Run(long MaxFrame, int Interval,
double PacketAveArvlTime, double PacketAveSize)
{
double Time;
long Frame;
long UsedBandWidth;
long n;

Source.SetParameter(PacketAveArvlTime, PacketAveSize);

cout << "F\tS\tD1\tD2\tDV1\tDV2\n";

Time = 0;
n = 0L;
for (Frame=0L;Frame<MaxFrame;Frame++) {
n += FrameLength;
while (n > 0) {
UsedBandWidth = Controller.Schedule(Time, &Monitor);
Time += UsedBandWidth;
n -= UsedBandWidth;
}

if (Frame % Interval == 0)

{

cout << Frame;
cout << "\t" << (Monitor.GetNumOfTotalPacket()*DATA_UNIT/Time);
cout << "\t" << Monitor.GetDelay()/DATA_UNIT;
cout << "\t" << Monitor.GetDelay()/FrameLength*FRAME_TIME;
cout << "\t" << Monitor.GetDelayVariance()/DATA_UNIT;
cout << "\t" <<
Monitor.GetDelayVariance()/FrameLength*FRAME_TIME;
cout << endl;
}
}

cout << setiosflags(ios::fixed) << setprecision(3);
cout << Frame;
cout << "\t" << (Monitor.GetNumOfTotalPacket()*DATA_UNIT/Time);
cout << "\t" << Monitor.GetDelay()/DATA_UNIT;
cout << "\t" << Monitor.GetDelay()/FrameLength*FRAME_TIME;
cout << "\t" << Monitor.GetDelayVariance()/DATA_UNIT;
cout << "\t" << Monitor.GetDelayVariance()/FrameLength*FRAME_TIME;
cout << endl;

cout << "%\tF=Frame\n";
cout << "%\tS=Throughput\n";
cout << "%\tD1=Delay[cells] D2=Delay[ms]\n";
cout << "%\tDV1=Delay Variance[cells] DV2=Delay Variance[ms]\n";
cout << flush;
}

////////////////////////////////////////////////////////////////////////////
////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////
//
// main(void)
//
//
////////////////////////////////////////////////////////////////////////////
////////////////////


int main(void)
{
int n;
double MaxFrame;
double PacketAveSize;
double TrafficLoad;
int Interval;


MaxFrame = 10;
n = 4;
PacketAveSize = 3;
TrafficLoad = 0.6;
Interval = 2;


if (MaxFrame <= 0 || n <= 0 || n >= 15 || PacketAveSize <= 0 ||
TrafficLoad <= 0 || TrafficLoad >= 1) {
cerr << "Parameter Error" << endl;
return(-1);
}

int NumOfTerminal = 1;
for (int i=0;i<n;i++) NumOfTerminal*=2;
double PacketAveArvlTime = PacketAveSize * DATA_UNIT / TrafficLoad;

cout << "% DQRAP Simulation\n";
cout << setiosflags(ios::fixed) << setprecision(4);
cout << "% Num.of.Terminals:" << setw(20);
cout << NumOfTerminal << endl;
cout << "% Max.Sim.Frames: " << setw(20);
cout << MaxFrame << endl;
cout << "% Num.of.Ave.Cells:" << setw(20);
cout << PacketAveSize << endl;
cout << "% Data.Arrvl.Intvl:" << setw(20);
cout << (PacketAveArvlTime/DATA_UNIT) <<endl;

CSimulation Sim;
Sim.Initialize(n, FRAME_LENGTH);
Sim.Run(MaxFrame, Interval, PacketAveArvlTime, PacketAveSize);

return(0);
}
 
H

Howard

Caldwell said:
It is not anything API related in this program. All it does is finding the
numerical results, but it had many classes which I would be interested to
look into when the program is running.

I tried step into and step over... but you are right. After I press servral
times of F10 (step into F11), I see a bunch of machine code.


May i show you how it is like? you do not need to look what this program
does. I would like to know if VC++ debugger will allow me to see through
the program statement by statement in this program.

Thank you

I'm not sure what exactly you are having a problem with. Did you make a
debug build? (See your VC++ documentation on how to do that and what
settings are important.) Try setting a breakpoint in the code you want to
stop and examine, then run the application, and once it stops at your
breakpoint use Step Into or Step Over to step into functions or to execute
individual lines of code one at a time.

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top