Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Feb 2013 15:04:02 +0100
From:      <natris@centrum.cz>
To:        =?utf-8?q?Konstantin_Belousov?= <kostikbel@gmail.com>
Cc:        =?utf-8?q?freebsd=2Dhackers=40freebsd=2Eorg?= <freebsd-hackers@freebsd.org>, =?utf-8?q?Ryan_Stone?= <rysto32@gmail.com>
Subject:   =?utf-8?q?Re=3A_SIGSEGV=2FSIGBUS_when_accessing_after_end_of_mmapped_file=3B_why_it_differs_with_GCC=3F?=
Message-ID:  <20130214150402.49631109@centrum.cz>
In-Reply-To: <20130213191208.GR2522@kib.kiev.ua>
References:  <20130213171825.76D3A9DC@centrum.cz>, <CAFMmRNxkYKy_-GVSGAwM7Zjikwtezj1cR3mmzDjC1sqkv2Btog@mail.gmail.com> <20130213191208.GR2522@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
 
 
Od: "Konstantin Belousov" <kostikbel@gmail.com>
> On Wed, Feb 13, 2013 at 12:13:58PM -0500, Ryan Stone wrote:
>> On Wed, Feb 13, 2013 at 11:18 AM, <natris@centrum.cz> wrote:
>>
>> > Hello,
>> > I am porting an application which maps files into the memory and works
>> > directly with the memory. When doing this, it can happen that when
>> > someone
>> > resizes the file so that part of the previously mapped region is no
>> > longer
>> > backed by the file, synchronous signal is sent to the process which
>> > needs
>> > to be handled.
>> >
>> > On all other platforms than FreeBSD I have tested (Solaris, Linux,
>> > Darwin,
>> > HP-UX) the signal in question is SIGBUS. However on FreeBSD, depending
>> > on
>> > the >>compiler<< used, it is either SIGBUS or SIGSEGV. When I compile
>> > the
>> > binary with "gcc version 4.2.1 20070831 patched [FreeBSD], amd64", the
>> > signal is SIGBUS, when i use "gcc version 4.7.3 20121103 (prerelease)
>> > (FreeBSD Ports Collection)", the signal is SIGSEGV. Please note that one
>> > of
>> > the versions of gcc between 4.2 and 4.7 also caused SIGSEFV to be sent
>> > but
>> > this did not matter for me as I did not need to use that version; I
>> > however
>> > need gcc 4.7 to work because of c++11 stuff that my project has recently
>> > started to use.
>> >
>> > Unfortunately registering signal handler on SIGSEGV is very inconvenient
>> > for me; I would prefer to somehow switch the behavior to be sane.
>> >
>> > Please anyone has an idea whether or how this could be achieved? I have
>> > tried to find out why, on single machine, just because of different gcc
>> > version, kernel sends different signal but I have never worked with fbsd
>> > kernel before and so my search did not succeed so far.
>> >
>> > Machine in question runs amd64 FreeBSD 9.1-RC2, but this has also
>> > happened
>> > to me with older version of FreeBSD.
>> >
>> >
>> > gcc 4.2 (same happens also with libstdc++ and co. from gcc 4.2):
>> > Program received signal SIGBUS, Bus error.
>> > (gdb) i shared
>> > From                To                  Syms Read   Shared Object
>> > Library
>> > 0x0000000800f2ef70  0x0000000800f3ee68  Yes (*)     /libexec/ld-elf.so.1
>> > 0x000000080114d710  0x0000000801159748  Yes (*)     /lib/libthr.so.3
>> > 0x00000008013c2d30  0x000000080142c656  Yes
>> > /usr/local/lib/gcc47/libstdc++.so.6
>> > 0x00000008016737c0  0x00000008016891b8  Yes (*)     /lib/libm.so.5
>> > 0x0000000801893930  0x00000008018a3088  Yes
>> > /usr/local/lib/gcc47/libgcc_s.so.1
>> > 0x0000000801ad71d0  0x0000000801ba9358  Yes (*)     /lib/libc.so.7
>> >
>> > gcc 4.7:
>> > Program received signal SIGSEGV, Segmentation fault.
>> > (gdb) i shared
>> > From                To                  Syms Read   Shared Object
>> > Library
>> > 0x0000000800f5ef70  0x0000000800f6ee68  Yes (*)     /libexec/ld-elf.so.1
>> > 0x000000080117d710  0x0000000801189748  Yes (*)     /lib/libthr.so.3
>> > 0x00000008013f2d30  0x000000080145c656  Yes
>> > /usr/local/lib/gcc47/libstdc++.so.6
>> > 0x00000008016a37c0  0x00000008016b91b8  Yes (*)     /lib/libm.so.5
>> > 0x00000008018c3930  0x00000008018d3088  Yes
>> > /usr/local/lib/gcc47/libgcc_s.so.1
>> > 0x0000000801b071d0  0x0000000801bd9358  Yes (*)     /lib/libc.so.7
>> >
>> >
>> > I would be glad for any hint or information.
>> > Kind Regards,
>> > Ondrej Kolacek
>> > _______________________________________________
>> > freebsd-hackers@freebsd.org mailing list
>> > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> > To unsubscribe, send any mail to
>> > "freebsd-hackers-unsubscribe@freebsd.org"
>>
>>
>>
>> I think that setting sysctl machdep.prot_fault_translation=1 would do what
>> you want.
>
> This might be an indication of the issue with the toolchains you use,
> in particular, with the linker or csu.  The default selection for the signal
> is based on the note osver, linked into the binary from crt1.o. Either
> linker omits the note, or wrong crt1 is used.
>
> You did not specified anything about version of the FreeBSD used, nor
> the exact compiler invocations. Using the crystal ball, I see the
> r244600 for HEAD and r244904 for stable/9, if you use --gc-sections
> flags. This is more or less consistent with what you reported, since
> gcc from ports uses binutils from ports, which have newer ld with
> bugfix already applied.

Thanks a lot for the pointers. So, to sum it up for potential others who could stumble into this problem:
In FBSD6 and older, there was a POSIX nonconformity in FreeBSD when in some cases SIGBUS was raisedinstead of SIGSEGV. Within FBSD7, change of behavior was implemented in kernel - in case of page fault, SIGSEGV is raised instead of SIGBUS. However it was quickly determined that this was breaking stuff, as the old binaries expected SIGBUS instead. Also it was determined that this change is not really POSIX conformant either as some page faults are supposed to signal SIGBUS (like the mmap issue I was asking about). Because of this, within PR 118304, hack has been made to the kernel. Based on ELF OSABI note within the executable (eg. note (.note.ABI-tag): FreeBSD 901000), for ELF files with OS version older than 700004 or for those who do not contain such a note, SIGBUS is used, for those who contain newer flag SIGSEGV is used. There is also an option to tune the translation globally for all processes on the given machine via sysctl machdep.prot_fault_translation.
 
In my case it is indeed so that while the gcc42 generated binary does not contain the note, gcc47 binary does contain it. I am indeed using --gc-sections linker option, however whether this, potentially with some bug in linker, caused the note to be missing, I am not sure, as I did not investigate into this. The solution of the original problem is thus to ensure that the note presence is consistent and that the correct signal is handled.
 
Thanks again for the assistance
Ondrej Kolacek



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130214150402.49631109>