OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 12:10 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Kernel Crashes due to compiler optimization
PostPosted: Thu Jun 08, 2017 10:41 pm 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
Hello,

i686-elf-gcc -c print.c -o print.o -std=gnu99 -ffreestanding -Os -Wall -Wextra

By using the above -OS or -O2 or any flag optimisation, the following causing the crash


Puts(){

Putc ();
Here the compiler compiling Putc as Jmp Putc instead of Call Putc

}


So i removed optimization flag and complied , then everything went well but the code size of Kernel changed massively.

Any Suggestions on this optimizing and achieving call instruction instead Jmp @ Putc


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Thu Jun 08, 2017 11:17 pm 
Offline
Member
Member

Joined: Sat Nov 21, 2009 5:11 pm
Posts: 852
I suspect that the crash, in this case, is caused not by a GCC bug, but by PEBKAC.


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Thu Jun 08, 2017 11:25 pm 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
yerri07 wrote:
By using the above -OS or -O2 or any flag optimisation, the following causing the crash


Puts(){

Putc ();
Here the compiler compiling Putc as Jmp Putc instead of Call Putc

}


So i removed optimization flag and complied , then everything went well but the code size of Kernel changed massively.

Any Suggestions on this optimizing and achieving call instruction instead Jmp @ Putc


And why jumping to Putc() should be bad? Did you write some crappy inline assembly code in Putc()?


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 12:53 am 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
No inline assembly , here comes another one , Watch @c00013e4, this occurred even without O flag. Declaring the function prototypes with cdecl and any , would solve the issue?

c00013a9 <GotoXY>:
c00013a9: 80 3d 22 26 00 c0 50 cmpb $0x50,0xc0002622
c00013b0: 55 push %ebp
c00013b1: 89 e5 mov %esp,%ebp
c00013b3: 8b 55 08 mov 0x8(%ebp),%edx
c00013b6: 8b 45 0c mov 0xc(%ebp),%eax
c00013b9: 77 06 ja c00013c1 <DebugGotoXY+0x18>
c00013bb: 88 15 22 26 00 c0 mov %dl,0xc0002622
c00013c1: 80 3d 21 26 00 c0 19 cmpb $0x19,0xc0002621
c00013c8: 77 05 ja c00013cf <DebugGotoXY+0x26>
c00013ca: a2 21 26 00 c0 mov %al,0xc0002621
c00013cf: 0f b6 05 21 26 00 c0 movzbl 0xc0002621,%eax
c00013d6: 89 45 0c mov %eax,0xc(%ebp)
c00013d9: 0f b6 05 22 26 00 c0 movzbl 0xc0002622,%eax
c00013e0: 89 45 08 mov %eax,0x8(%ebp)
c00013e3: 5d pop %ebp
c00013e4: e9 75 fd ff ff jmp c000115e <UpdateCur>


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 4:39 am 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Your kernel is not crashing due to compiler optimization.

Most likely, you have written bad code without realizing it. Show us the code that's crashing and we can try to figure out what's wrong.


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 5:02 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
If anything, the optimizing code paths of a compiler are even more well-tested than the non-optimizing ones. I second Octocontrabass here -- most likely enabling optimization unveiled a problem with your code, but the problem is still with your code, not the compiler. (That's just hugely unlikely.)

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 7:54 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

yerri07 wrote:
Here the compiler compiling Putc as Jmp Putc instead of Call Putc


That's probably a perfectly valid tail call optimisation.

Solar wrote:
If anything, the optimizing code paths of a compiler are even more well-tested than the non-optimizing ones. I second Octocontrabass here -- most likely enabling optimization unveiled a problem with your code, but the problem is still with your code, not the compiler. (That's just hugely unlikely.)


The problem/s are likely to be caused by undefined behaviour and/or other forms of "programmer error"; but what caused "programmer error"?

There's a chance that language design and/or compiler design are partially responsible for "programmer error not detected at compile time". For a simple example; maybe various warnings (that perhaps should've been enabled by default but aren't) haven't been explicitly enabled.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 9:24 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
A topical StackOverflow answer regarding the use of compiler warnings...

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 10:36 am 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
Solar wrote:
A topical StackOverflow answer regarding the use of compiler warnings...



Thank you for the link , but i haven't recieved any warnings compile and linking process went good


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 11:11 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

Maybe it would help if I "de-optimised" the compiler's code:

The original disassembly, just with some tidying up (whitespace, etc):
Code:
c00013a9 <GotoXY>:
     cmpb $0x50,0xc0002622
     push %ebp
     mov %esp,%ebp
     mov 0x8(%ebp),%edx
     mov 0xc(%ebp),%eax
     ja .L1
     mov %dl,0xc0002622
.L1:
     cmpb $0x19,0xc0002621
     ja .L2
     mov %al,0xc0002621
.L2:
     movzbl 0xc0002621,%eax
     mov %eax,0xc(%ebp)
     movzbl 0xc0002622,%eax
     mov %eax,0x8(%ebp)

     pop %ebp
     jmp c000115e <UpdateCur>


Without the tail call optimisation:
Code:
c00013a9 <GotoXY>:
     cmpb $0x50,0xc0002622
     push %ebp
     mov %esp,%ebp
     mov 0x8(%ebp),%edx
     mov 0xc(%ebp),%eax
     ja .L1
     mov %dl,0xc0002622
.L1:
     cmpb $0x19,0xc0002621
     ja .L2
     mov %al,0xc0002621
.L2:
     movzbl 0xc0002621,%eax
     mov %eax,0xc(%ebp)
     movzbl 0xc0002622,%eax
     mov %eax,0x8(%ebp)

     call c000115e <UpdateCur>
     pop %ebp
     ret


Without instruction re-ordering:

Code:
c00013a9 <GotoXY>:
     push %ebp
     mov %esp,%ebp
     mov 0x8(%ebp),%edx
     mov 0xc(%ebp),%eax

     cmpb $0x50,0xc0002622
     ja .L1
     mov %dl,0xc0002622
.L1:
     cmpb $0x19,0xc0002621
     ja .L2
     mov %al,0xc0002621
.L2:
     movzbl 0xc0002621,%eax
     mov %eax,0xc(%ebp)

     movzbl 0xc0002622,%eax
     mov %eax,0x8(%ebp)

     call c000115e <UpdateCur>

     pop %ebp
     ret


A guess at the original C:

Code:
int currentX;
int currentY;

void GotoXY(int x, int y) {
    if(currentX <= 80) {
        currentX = x;
    }
    if(currentY <= 25) {
        currentY = y;
    }
    UpdateCur(currentX, currentY);
}


That looks buggy to me, so here's a guess at what the original code should have been:

Code:
int currentX;
int currentY;

void GotoXY(int x, int y) {
    if(x < 80) {
        currentX = x;
    }
    if(y < 25) {
        currentY = y;
    }
    UpdateCur(currentX, currentY);
}


Of course we have no idea how many bugs are in your original C source code, because you haven't provided any.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 11:17 am 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
Here is the file, pls find the attactchment


Attachments:
print.h [2.4 KiB]
Downloaded 19 times
print.c [7.46 KiB]
Downloaded 38 times
Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 12:33 pm 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
I suspect the BrokenThorn tutorial code is crashing because you've made a mistake somewhere when you tried to translate it from MSVC to GCC.

You might have better luck with a tutorial specifically written to use GCC, or taking a break to improve your background knowledge before you try to tackle something as ambitious as developing an operating system.


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 9:22 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 18, 2009 5:47 pm
Posts: 208
Location: Alexandria, Egypt | Ottawa, Canada
Hi,

Thank you for posting the code. According to what I see now, the code makes a lot of checks to make sure that null pointer exceptions and out-of-range references do not occur. That's really nice. However, there is one line of code that really stopped me.

This line of code is strange. I don't know how your i686-gcc compiler doesn't report a warning at this line. This line should cause a warning even without -Wall and -Wextra!

This line of code,.... Well I don't really know how to express my feelings towards it... but it is really strange

It is like seeing an atom of Lithium (Li, with only 3 electrons) in a world full of Uranium

Despite all of these awkward feelings towards this strange line, it really touched me. The line, if you look at it very closely, is like a small child in a green garden. It is really cute and I have seen all my beautiful childhood when I looked at the line. But wait! my childhood wasn't beautiful. I still can't forget that creepy, awful day when... Sorry did you check stdarg.h before you use it in your operating system? Is it written by your or someone else? Are you sure about its behaviour? Is it deterministic?

TFM wrote:
If there is no next argument, or if type is not compatible with the
type of the actual next argument (as promoted according to the default
argument promotions), random errors will occur.


Now let's see what type is passed to the innocent va_arg:

Code:
               /*** address of ***/
               case 's': {
                  int c = (int) va_arg (args, char);
                  char str[64];
                  strcpy (str,(const char*)c);
                  DebugPuts (str);
                  i++;      // go to next character
                  break;
               }


First of all, without even looking at the context of va_arg here, your explicit cast from (char) to (int) with va_arg() is very dangerous. The manual itself says it very clearly: random errors will occur if promotions are not compatible with the passed type. The word "promotions" here refer to the promotions that are done by gcc-compiled code when a function is called. Types that are passed to that function are promoted. For example, on my machine, (char) parameters are promoted to (int) before the function is called (simply by movsbl instruction). For that reason, gcc should throw a warning at this point, because your assumption about argument-passing promotions as done by gcc is wrong.

Furthermore, it throws the same warning at places with the same risky use of va_arg(). For example, at line 261, the passed type is (char) so you simply used va_arg() with (char)... However, the compiler should tell you the whole point:

gcc wrote:
<your file>: In function <your function>:
<your file>:<the line>:<unsurprisingly, the column>:

warning: ‘char’ is promoted to ‘int’ when passed through ‘...’
char c = (char) va_arg(args, char);
^
note: (so you should pass ‘int’ not ‘char’ to ‘va_arg’)
note: if this code is reached, the program will abort



Can you see it? The compiler tells us the truth. It doesn't lie like us (not because it is honest, but because it is dumb (or dump?)). A passed character will always be promoted to an integer, so you should use va_arg() with 'int', not 'char', according to the first note.

OK. I will pass 'char'... and I will ignore this silly warning... What on earth will happen? we always happily cast a (char) to (int) even when it is the Christmas day! Recent research on the origins of Java programmers suggests that their ancestors heavily used such awkward constructs and their programs worked well (to them). So what about gcc? Here comes the second note...

gcc wrote:
<your file>: In function <your function>:
<your file>:<the line>:<unsurprisingly, the column>:

warning: ‘char’ is promoted to ‘int’ when passed through ‘...’
char c = (char) va_arg(args, char);
^
note: (so you should pass ‘int’ not ‘char’ to ‘va_arg’)
note: if this code is reached, the program will abort



How innocent! Did you like it? I will make your program abort if this code is reached! You know what, If I compile and execute va_arg(args, char) on my x86_64 machine (using gcc), the program gives illegal instruction exception!

OK iocoder, that's easy... my compiler doesn't give me the same warning that appears to you, so it might be handling va_arg() differently, in a way that doesn't abort the program.

Me: OK dude, even if we assume that this random behavior is deterministic (how can this be?), I am sure the tape on Turing machine will get damaged if we run this program on it (and you can't replace the tape because it doesn't have boundaries).

Why? Let's look at the code again:

Code:
                  int c = (int) va_arg (args, char);
                  ....
                  strcpy (str,(const char*)c);


You assume that the passed type is char. In this case, you will ignore whatever that argument holds except the lowest significant byte. So, if for example, I pass this:

Code:
    printf("%s", 0x12345678);


The va_arg (args, char) thing will evaluate to 0x78 with (char) type. You then convert this to integer, hoping that gods will return back the missed 0x123456 when the character is converted to an integer. You then convert the integer to char pointer and use it to retrieve the passed string!

I am not saying that this bug (I am not even sure if it is the actual bug that crashes your OS, because the behavior of va_arg is random in this case, so it might even be working correctly. But it is still a bug, because it will behave differently (in an unwanted manner) if I compile your OS with my gcc) is why your OS crashes, but my argument here is that such holes in a program are why it crashes. The compiler is an innocent child that is not intelligent enough to understand the reality of our awkward world.

My suggestion is to try to debug your code a component by component. We don't know exactly in which component the bug is hiding. The compiler itself might be buggy. However, the compiler is well tested. Is your program well tested?

You could also post the code of the other parts of your kernel that you suspect they have the bug. I love it when someone gives me code to fix and it is challenging to me. But, you must learn how to find the bug by yourself. Our answers here are just guidelines that help you understand what is going on.

Best of luck!


Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 10:25 pm 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
I tried above code cause another strange execution happened when i have a code to print functions in assembly and called the function from the c file(linked both files) , the first two instructions are not executed and but when i place a call to print the message with in the assembly file it executes correctly . So i gave a try compiling the above tutorial code.

see the disassembly of the code (push edi) in the image, the stack doesn't changed after the execution.

I will provide you the image that caused the strange execution.

1. After stepping the instruction
2.Before steeping the instruction


Attachments:
Screenshot at 2017-06-08 23-51-15.png
Screenshot at 2017-06-08 23-51-15.png [ 93.82 KiB | Viewed 4460 times ]
Screenshot at 2017-06-08 23-48-27.png
Screenshot at 2017-06-08 23-48-27.png [ 93.36 KiB | Viewed 4460 times ]
Top
 Profile  
 
 Post subject: Re: Kernel Crashes due to compiler optimization
PostPosted: Fri Jun 09, 2017 10:41 pm 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
Octocontrabass wrote:
I suspect the BrokenThorn tutorial code is crashing because you've made a mistake somewhere when you tried to translate it from MSVC to GCC.

You might have better luck with a tutorial specifically written to use GCC, or taking a break to improve your background knowledge before you try to tackle something as ambitious as developing an operating system.



Thank you for the reply. Yes i believe i wiil be improved when i ran into these situations , and i learnt a lot while implementing , because of the wonderful support of the Series Editor Brokenthorn. And now i am feeling the support of Osdev forum too.

I learnt a lot while implementing rather studying.

Thank you all for the suggestions


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], Octocontrabass and 103 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group