Reputation: 836
On my school project (a multi-threaded shell) I am trying to add some debug statements in the code. I ran into an interesting situation and would like to know why it is happening.
int signals(void)
{
if (tcb[curTask].signal)
{
int beforeSignal = tcb[curTask].signal;
if (tcb[curTask].signal & mySIGINT)
{
tcb[curTask].signal &= ~mySIGINT; // clears the mySIGINT from the signals
(*tcb[curTask].sigIntHandler)();
}
if (tcb[curTask].signal & mySIGCONT)
{
tcb[curTask].signal &= ~mySIGCONT; // clears the mySIGCONT from the signals
(*tcb[curTask].sigContHandler)();
}
if (tcb[curTask].signal & mySIGTERM)
{
tcb[curTask].signal &= ~mySIGTERM; // clears the mySIGTERM from the signals
(*tcb[curTask].sigTermHandler)();
}
if (tcb[curTask].signal & mySIGTSTP)
{
tcb[curTask].signal &= ~mySIGTSTP; // clears the mySIGTSTP from the signals
(*tcb[curTask].sigTstpHandler)();
}
if (DEBUG) {
printf("\nSignals:\n\tBefore: %s\n\tAfter: %s",byte_to_binary(beforeSignal), byte_to_binary(tcb[curTask].signal));
}
}
return 0;
}
TCB is a struct:
typedef struct // task control block
{
char* name; // task name
int (*task)(int,char**); // task address
int state; // task state
int priority; // task priority (project 2)
int argc; // task argument count (project 1)
char** argv; // task argument pointers (project 1)
int signal; // task signals (project 1)
void (*sigContHandler)(void); // task mySIGCONT handler
void (*sigIntHandler)(void); // task mySIGINT handler
void (*sigKillHandler)(void); // task mySIGKILL handler
void (*sigTermHandler)(void); // task mySIGTERM handler
void (*sigTstpHandler)(void); // task mySIGTSTP handler
TID parent; // task parent
int RPT; // task root page table (project 5)
int cdir; // task directory (project 6)
Semaphore *event; // blocked task semaphore
void* stack; // task stack
jmp_buf context; // task context pointer
} TCB;
and byte_to_binary converts the int to a binary string.
const char *byte_to_binary(int x)
{
static char b[9];
b[0] = '\0';
int z;
for (z = 128; z > 0; z >>= 1)
{
strcat(b, ((x & z) == z) ? "1" : "0");
}
return b;
}
When the debug statement prints it looks like this:
Signals:
Before: 000000000
After: 000000000
Printing the signal where the beforeSignal int is assigned and after the conditial/masking blocks results in:
Signals:
Before: 00001000
After: 00000000
So it appears that the beforeSignal is being updated by the masking operations in the conditionals. I thought that integers were always passed by value so I don't get why the int is being changed from its initial value. I am sure there is a simple method to get a "copy" of the int that won't mirror the original value and I would appreciate knowing it.
Upvotes: 0
Views: 73
Reputation: 340198
The problem is that you place the result of the byte_to_binary()
function in a static
buffer. The statement where printf()
is called actually makes both calls to byte_to_binary()
before transferring control to printf()
. So printf()
just displays the same buffer twice.
You'll need to do something like have byte_to_binary()
return a string that's allocated dynamically then free it later (in which case you can't easily use it in a call to printf()
without a memory leak), or you'll need to change the interface so that the output buffer is passed into byte_to_binary()
. Just have byte_to_binary()
return the pointer that is passed in and you can call it from printf()
like you're doing now.
Upvotes: 3