having problems with printing messages

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
beyondsociety

having problems with printing messages

Post by beyondsociety »

I am revamping my c code and I have noticed that when I run my code in bochs, the messages I have printed to the screen, get overwritten by other messages from functions I am calling to run.

What could be the cause of this. This is weird, because before I never had this problem. Its only when you re-write your code that you find even more problems then before. ;D

Thanks for the help.
nullify

Re:having problems with printing messages

Post by nullify »

If you've implemented task switching, there is a chance that your non-reentrant printing code is being entered multiple times, which would screw things up.

Also, pay extra attention to how you managed your cursor row/col variables. It sounds to me like at some point they might not be getting updated when they need to be.
beyondsociety

Re:having problems with printing messages

Post by beyondsociety »

If you've implemented task switching, there is a chance that your non-reentrant printing code is being entered multiple times, which would screw things up.
I have not implemented task switching as of yet.
Also, pay extra attention to how you managed your cursor row/col variables. It sounds to me like at some point they might not be getting updated when they need to be.
This is probably my problem, I will take a look at my update_cursor function and get back to you on the results. I might re-write my update_cursor function.

Update: After some testing, I figured out there is some kind of problem with my init_interrupts.c function as when it is called, it overwrites the previous messages.
beyondsociety

Re:having problems with printing messages

Post by beyondsociety »

Why would my init_pics function mess up the cursor and thus overwrite my previous messages?

I wonder if there something wrong with that function.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:having problems with printing messages

Post by Pype.Clicker »

if you messed up the 'outb' commands, it may happen ...
Also take care that an interrupt that occurs while you're printing something will not mess things.

it will depend on whether you cache the content of the position in memory or not and if you do, how you declare those cache variables to GCC (are they static ? or volatile ? or both ?)
beyondsociety

Re:having problems with printing messages

Post by beyondsociety »

if you messed up the 'outb' commands, it may happen ...
I check into this.
Also take care that an interrupt that occurs while you're printing something will not mess things.
How do I check this?
it will depend on whether you cache the content of the position in memory or not and if you do, how you declare those cache variables to GCC (are they static ? or volatile ? or both ?)
Can you give a better explanation of this.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:having problems with printing messages

Post by Pype.Clicker »

let's suppose you have something like

Code: Select all

cursor_row;
cursor_column;
char *video_current;
char *video_start;

kprint(char *message)
{
    for (;*message;message++) {
        switch(*message) {
         case '\n': cursor_row+=cursor_column/ROW_WIDTH;
              cursor_column=0;
              video_current=video_start+cursor_row*ROW_WIDTH*2;
         default:
              *video_current=*message;
              video_current[1]=attributes;
              cursor_column++;
         }
    }
    set_hw_cursor_position(cursor_row, cursor_column);
}
It is probable that the variable video_current (for instance) or cursor_row and cursor_column are not referenced everytime the code modifies them. What the compiler could do -- as there's no function call until set_hw_... -- is to decide that it will use %eax as a cache for video_current, thus the function preamble will include some code like "mov eax,[video_current]" and "mov [video_current],eax will be issued just before "call set_hw ..."

In this configuration, any interrupt that occurs while the CPU is running kprint will not find the up-to-date version of the variable.

For instance
kprint("we're in main")
will start at video_current = 10 and prints 5 characters. Then an interrupt fires and
kprint("this is the interrupt handler") will be executed, which will also find video_current=10 (rather than 15!), so it will overwrite "we're" that has already been written.
kprint("we're in main")
is resumed and it continues printing chars " in main", overwriting "is the int".

Finally, what you see on screen is
"this in main[t]errupt handler"

instead of
"we're this is the interrupt handler in main[ ]".

Hope it's clearer this way.

One way you can force GCC to access the memory location for every variable reference is by declaring "volatile char *video_current".
beyondsociety

Re:having problems with printing messages

Post by beyondsociety »

It is probable that the variable video_current (for instance) or cursor_row and cursor_column are not referenced everytime the code modifies them.
One way you can force GCC to access the memory location for every variable reference is by declaring "volatile char *video_current". Is this the way to do it?
In this configuration, any interrupt that occurs while the CPU is running kprint will not find the up-to-date version of the variable.
Why would a interrupt be triggered when my print function is called when maskable interrupts are disabled with CLI and non-maskable interrupts are disabled untill I call a interrupt?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:having problems with printing messages

Post by Pype.Clicker »

beyondsociety wrote: Why would a interrupt be triggered when my print function is called when maskable interrupts are disabled with CLI and non-maskable interrupts are disabled untill I call a interrupt?
that's something you didn't mention.
Well, one obvious cause is that the interrupt is an exception.

If this is not the case either ... well ... i dunno, except if you call printf from printf (which you of course didn't, did you ?)
beyondsociety

Re:having problems with printing messages

Post by beyondsociety »

Well, one obvious cause is that the interrupt is an exception.
How can I check this?
If this is not the case either ... well ... i dunno, except if you call printf from printf (which you of course didn't, did you ?)
I dont think this is my problem. Do you mean calling a printf function inside of the printf function? If this is the case, then no Im not that stupid.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:having problems with printing messages

Post by Pype.Clicker »

well, maybe the best way for you to solve this out will be to have bochs running step by step from the start of the 'print' command until it ends. I know this is boring as hell, but at least it will show you what's going on.
Another possible way to solve this is to ask Bochs to enable the call trace (see bochs first aid kit in .:QuickLinkz:. for more info), so that you'll know what function/interrupt/exception calls are made.

At this level, it seems to me that just trying to guess what's going wrong do no longer suffice and that you need extra info to debug.
BI lazy

Re:having problems with printing messages

Post by BI lazy »

Hi, gosh!

You ask how to check what kind of Interrupt (exception/irq line): This is straight forward.

Take your usual isr stub and have it push a number on the stack *before* calling the c-isr. Afterwards you have to remove this value to some clobber register - say eax. it doesn't matter for the following popping will restore the former register values - maybe of another task.

Here is an example - in nasm and c.

Code: Select all

in nasm define a macro like this one for your isr stubs.

%macro ISR 1  ;macro with one parameter
  ISR_PROLOGUE ;macro for saving registers, pushing error codes etc.
  push %1 ;put the parameter on the stack
  call interrupt_handler ;to be defined as EXTERN!!!
  pop eax ;remove the parameter from stack
  ISR_EPILOGUE ;macro for restoring registers, removing error codes, etc
%endmacro

later in your code, where you place the isr and exception stubs in the code section (this is *the lowest level of kernel*!!)

you just say: ISR 1 ... ISR 31 -> for exceptions
                     ISR 31 ... ISR n -> for interrupt handlers.

for interrupt handlers, you can have different offsets in the IDT. Take care of that this is only an example.

In your C code for Interrupt handling, define the interrupt handlers like this:

void interrupt_handler(int irq);

And see, the parameter irq is pushed on the stack by the stub. Just pick it and check the number. Exceptions are only from 1 - 31 if i remember correctly.

I hope this helps to solve some problems.

stay safe
beyondsociety

Re:having problems with printing messages

Post by beyondsociety »

Another possible way to solve this is to ask Bochs to enable the call trace (see bochs first aid kit in .:QuickLinkz:. for more info), so that you'll know what function/interrupt/exception calls are made.
When I enable the trace-on command, then set the virtual breakpoint to the loacation and then continue execution, it does an infinite loop. On the bochs manual it says once trace-on is entered, it will print every extruction on the cpu. How do I get it to just print the contents of a certain range of addresses?
Post Reply