Announcement

Collapse
No announcement yet.

****ing Fortran

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    /me compiles those with gfortran -S -fverbose-asm

    Well, I can't tell *why* it happens, but I can tell what happens here: The segfaulting version initialises a .long 7 (labeled .LC0) in rodata, then tries to write to it right before calling ircon_. Since it's read-only, well, writing to it segfaults.

    Code:
    $ cat works.s 
    	.file	"foo.f"
    # GNU F95 version 4.1.1 (Gentoo 4.1.1-r1) (i686-pc-linux-gnu)
    #	compiled by GNU C version 4.1.1 (Gentoo 4.1.1-r1).
    
    	.text
    .globl MAIN__
    	.type	MAIN__, @function
    MAIN__:
    	pushl	%ebp	#
    	movl	%esp, %ebp	#,
    	subl	$40, %esp	#,
    	movl	$0, 8(%esp)	#,
    	movl	$127, 4(%esp)	#,
    	movl	$70, (%esp)	#,
    	call	_gfortran_set_std	#
    	movl	$7, -8(%ebp)	#, istart
    	leal	-8(%ebp), %eax	#, tmp59
    	movl	%eax, (%esp)	# tmp59,
    	call	ircon_	#
    	movl	%eax, -4(%ebp)	# D.593, i
    	leave
    	ret
    	.size	MAIN__, .-MAIN__
    .globl ircon_
    	.type	ircon_, @function
    ircon_:
    	pushl	%ebp	#
    	movl	%esp, %ebp	#,
    	movl	8(%ebp), %eax	# istart, istart
    	movl	$5, (%eax)	#, (* istart)
    	popl	%ebp	#
    	ret
    	.size	ircon_, .-ircon_
    	.ident	"GCC: (GNU) 4.1.1 (Gentoo 4.1.1-r1)"
    	.section	.note.GNU-stack,"",@progbits
    Code:
    $ cat segfaults.s 
    	.file	"foo.f"
    # GNU F95 version 4.1.1 (Gentoo 4.1.1-r1) (i686-pc-linux-gnu)
    #	compiled by GNU C version 4.1.1 (Gentoo 4.1.1-r1).
    
    	.section	.rodata
    	.align 4
    .LC0:
    	.long	7
    	.text
    .globl MAIN__
    	.type	MAIN__, @function
    MAIN__:
    	pushl	%ebp	#
    	movl	%esp, %ebp	#,
    	subl	$40, %esp	#,
    	movl	$0, 8(%esp)	#,
    	movl	$127, 4(%esp)	#,
    	movl	$70, (%esp)	#,
    	call	_gfortran_set_std	#
    	movl	$.LC0, (%esp)	#,
    	call	ircon_	#
    	movl	%eax, -4(%ebp)	# D.593, i
    	leave
    	ret
    	.size	MAIN__, .-MAIN__
    .globl ircon_
    	.type	ircon_, @function
    ircon_:
    	pushl	%ebp	#
    	movl	%esp, %ebp	#,
    	movl	8(%ebp), %eax	# istart, istart
    	movl	$5, (%eax)	#, (* istart)
    	popl	%ebp	#
    	ret
    	.size	ircon_, .-ircon_
    	.ident	"GCC: (GNU) 4.1.1 (Gentoo 4.1.1-r1)"
    	.section	.note.GNU-stack,"",@progbits
    Code:
    $ diff works.s segfaults.s 
    4a5,8
    > 	.section	.rodata
    > 	.align 4
    > .LC0:
    > 	.long	7
    16,18c20
    < 	movl	$7, -8(%ebp)	#, istart
    < 	leal	-8(%ebp), %eax	#, tmp59
    < 	movl	%eax, (%esp)	# tmp59,
    ---
    > 	movl	$.LC0, (%esp)	#,
    This is Shireroth, and Giant Squid will brutally murder me if I ever remove this link from my signature | In the end it won't be love that saves us, it will be mathematics | So many people have this concept of God the Avenger. I see God as the ultimate sense of humor -- SlowwHand

    Comment


    • #17
      Seriously. This is weird.
      12-17-10 Mohamed Bouazizi NEVER FORGET
      Stadtluft Macht Frei
      Killing it is the new killing it
      Ultima Ratio Regum

      Comment


      • #18
        I've seen way weirder. I wouldn't rule out the possibility of this being a compiler bug of some sort.

        And in g77/gcc, good luck getting it fixed within 5 years.

        I spent days right before Christmas 2 years ago tracking down a data corruption bug. Turns out when two obscure optimization flags were used together, register 31 would get trashed with a data store. Problem is, on AIX register 31 is an OS stack pointer. KA-RAHSHSHSHS of the whole system each time.

        Even better of course was this was with optimized binaries only. Have you ever analyzed the assembly output of an -O5 binary before? It was the most painful week of my life.

        Sybase was going to release it for the new year, so they were doing the UAT with the retail build (with full optimizations) when they noticed it crashed all the time.
        "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
        Ben Kenobi: "That means I'm doing something right. "

        Comment


        • #19
          If this is really a compiler bug then it's my first.

          YAYYYYYYYYY
          12-17-10 Mohamed Bouazizi NEVER FORGET
          Stadtluft Macht Frei
          Killing it is the new killing it
          Ultima Ratio Regum

          Comment


          • #20
            ...just got an out of office reply from my old IBM friend. He's gone til the 2nd.
            "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
            Ben Kenobi: "That means I'm doing something right. "

            Comment


            • #21
              Oh well. It only took 3 hours to chase this down.

              Maybe I should learn not to code for 12 hours straight without a single compile/test run...
              12-17-10 Mohamed Bouazizi NEVER FORGET
              Stadtluft Macht Frei
              Killing it is the new killing it
              Ultima Ratio Regum

              Comment


              • #22
                Try comp.lang.fortran:

                "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                Ben Kenobi: "That means I'm doing something right. "

                Comment


                • #23
                  I pinged another IBMer I knew. Turns out this program runs fine in IBM's compiler on AIX and Linux. Looks like a compiler bug in g77.

                  As for your issue, I can't recreate it with our compilers. I got another IBMer buddy of mine to look into it and he also couldn't see any problems. It seems the only difference is that IRCON receives integer literal in the second case. Sorry I couldn't be of more help here.
                  "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                  Ben Kenobi: "That means I'm doing something right. "

                  Comment


                  • #24
                    Thanks, Asher.

                    Is this the sort of problem you compsci geeks get off on?

                    12-17-10 Mohamed Bouazizi NEVER FORGET
                    Stadtluft Macht Frei
                    Killing it is the new killing it
                    Ultima Ratio Regum

                    Comment


                    • #25
                      Originally posted by KrazyHorse
                      Thanks, Asher.

                      Is this the sort of problem you compsci geeks get off on?

                      We prefer the performance type problems. If we can improve performance by 1%, look out...
                      "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                      Ben Kenobi: "That means I'm doing something right. "

                      Comment


                      • #26
                        Right.. the heads used to call it bumming code..

                        But one thing is for sure, .. wait, can't remember.. think of something witty and to the point here.
                        In da butt.
                        "Do not worry if others do not understand you. Instead worry if you do not understand others." - Confucius
                        THE UNDEFEATED SUPERCITIZEN w:4 t:2 l:1 (DON'T ASK!)
                        "God is dead" - Nietzsche. "Nietzsche is dead" - God.

                        Comment


                        • #27
                          Ari pretty much gave you the answer. Just read his assembly output.

                          Let's look at what happens in the function that works:

                          1: movl $7, -8(%ebp) #, istart
                          2: leal -8(%ebp), %eax #, tmp59
                          3: movl %eax, (%esp) # tmp59,
                          4: call ircon_ #

                          In the first line, a local variable is created, the address of which is the content of the register EBP (extended base pointer) minus 8.
                          In the second line, the address of this temporary variable is moved into the register EAX.
                          In the third, this address is moved to the place, where the stack pointer ESP points. This is obviously the way how that FORTRAN compiler passes function parameters. The result is usually passed back in the accumulator register (EAX)
                          In the fourth line, the function code is called.

                          Now let's look, what the called function does

                          1: movl %esp, %ebp #,
                          2: movl 8(%ebp), %eax # istart, istart
                          3: movl $5, (%eax) #, (* istart)

                          In the first line, the current value of the stack pointer ESP is moved to the base pointer EBP. Note that this is not the same value as in MAIN anymore, as the function call put parameter and return address on the stack.
                          In the second line, the content of EBP+8 is put in the accumulator. This is the address you passed as parameter, i.e. the address of ISTART in MAIN.
                          In the third line, the constant of 5 is loaded into this address. The function returns now.

                          The next line in MAIN is also noteworthy:

                          movl %eax, -4(%ebp) # D.593, i

                          Here, the content of the accumulator is put into the local variable I (residing at EBP-4). The strange thing is, the accumulator does not content a return value. It still contains the address of ISTART. This address is now written into I, and not the 5 as you might expect.

                          You forgot to assign the return value of the function. You should have added the line

                          IRCON = ISTART

                          or simply, and omitting the parameter

                          IRCON = 5

                          Let's now have a look at the segfaulting function:

                          .section .rodata
                          .align 4
                          .LC0:
                          .long 7

                          This creates a data segment. It name implies, that it is read only. The segment contains only one variable, a long (32 bit) constant 7. The label .LC0 points at it.

                          Let's now look at the same snippet of the MAIN program:

                          movl $.LC0, (%esp) #,
                          call ircon_ #

                          In the first line, the address of the constant 7 (.LC0) is moved on the stack.
                          In the second line, the function is called.

                          The function itself behaves identical. It puts a 5 on the address it received on the stack. But other than in the first example, this address now does not point on a local r/w variable, but contains an address in a segment marked read only. This writing operation results in a segmentation fault.

                          The quintessence is, you just don't do stuff like this. You don't pass a constant (like 7 in the second example) to a function and then try to write another value over it. A constant is just that, constant, and if you try to change it by force, strange things may happen in any language and with any compiler.

                          Comment


                          • #28
                            ****ing frog tranny
                            hm...
                            "I realise I hold the key to freedom,
                            I cannot let my life be ruled by threads" The Web Frogs
                            Middle East!

                            Comment


                            • #29
                              You forgot to assign the return value of the function. You should have added the line


                              Doesn't make a difference
                              12-17-10 Mohamed Bouazizi NEVER FORGET
                              Stadtluft Macht Frei
                              Killing it is the new killing it
                              Ultima Ratio Regum

                              Comment


                              • #30
                                According to the Fortran language spec, that should be permissable.

                                It's just a bit obscure, which means it doesn't surprise me that g77, being a hulking piece of ****, can't handle it.
                                "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                                Ben Kenobi: "That means I'm doing something right. "

                                Comment

                                Working...
                                X