[Bug libstdc++/86189] New: not equal allocators not behaving as expected

2018-06-17 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86189

Bug ID: 86189
   Summary: not equal allocators not behaving as expected
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rianquinn at gmail dot com
  Target Milestone: ---

I think this is a bug, but I am dealing with allocators so I am not 100% sure
here. I have created a really simple allocator for testing. The allocators are
NOT equal, and I have instructed the containers to propagate the allocator
using the propagate_on_container_copy_assignment alias set to true. Propagation
occurs, but during the destruction of the containers, the old allocator is
somehow being used. Whats worse is the newly allocated memory that was created
using one allocator, is deallocated using another, even though they are not
equal. Seems like a bug. 

Here is the allocator I have created:
template
class myallocator4
{
public:

using value_type = T;
using pointer = T *;
using size_type = std::size_t;
using propagate_on_container_copy_assignment = std::true_type;
using is_always_equal = std::false_type;

public:

myallocator4() = default;

template 
myallocator4(const myallocator4 &other) noexcept
{ (void) other; }

pointer allocate(size_type n)
{
if (auto ptr = static_cast(malloc(sizeof(T) * n))) {
std::cout << "A: " << this << " ptr: " << ptr << '\n';
return ptr;
}

throw std::bad_alloc();
}

void deallocate(pointer p, size_type n)
{
(void) n;

std::cout << "D: " << this << " ptr: " << p << '\n';
free(p);
}
};

template 
bool operator==(const myallocator4 &, const myallocator4 &)
{ return false; }

template 
bool operator!=(const myallocator4 &, const myallocator4 &)
{ return true; }

Here is the test case:
TEST_CASE("copy container, propogate")
{
std::cout << "copy container, propogate\n";

std::list> mylist1;
std::list> mylist2;

mylist1.push_back(1);
mylist1.push_back(2);
mylist1.push_back(3);
mylist2.push_back(4);
mylist2.push_back(5);
mylist2.push_back(6);

std::cout << "--" << '\n';
mylist2 = mylist1;
std::cout << "--" << '\n';
}

And here is the result:
copy container, propogate
A: 0x7ffce414af40 ptr: 0x562e4822ca30
A: 0x7ffce414af40 ptr: 0x562e4822cbf0
A: 0x7ffce414af40 ptr: 0x562e4822cc40
A: 0x7ffce414af60 ptr: 0x562e48237880
A: 0x7ffce414af60 ptr: 0x562e48233fe0
A: 0x7ffce414af60 ptr: 0x562e4822cc60
--
D: 0x7ffce414af60 ptr: 0x562e48237880
D: 0x7ffce414af60 ptr: 0x562e48233fe0
D: 0x7ffce414af60 ptr: 0x562e4822cc60
A: 0x7ffce414ae40 ptr: 0x562e4822cc60
A: 0x7ffce414ae40 ptr: 0x562e48233fe0
A: 0x7ffce414ae40 ptr: 0x562e48237880
--
D: 0x7ffce414af60 ptr: 0x562e4822cc60
D: 0x7ffce414af60 ptr: 0x562e48233fe0
D: 0x7ffce414af60 ptr: 0x562e48237880
D: 0x7ffce414af40 ptr: 0x562e4822ca30
D: 0x7ffce414af40 ptr: 0x562e4822cbf0
D: 0x7ffce414af40 ptr: 0x562e4822cc40

As can be seen, the allocator at 0x7ffce414af60 (which is the original
allocator for the second list) is used to deallocate memory from
0x7ffce414ae40, even though the allocators are not equal.

[Bug libstdc++/86189] not equal allocators not behaving as expected

2018-06-18 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86189

--- Comment #4 from Rian Quinn  ---
Nope, I think that is the root of the issue. Where exactly does the spec
state that as this is the first I have heard of this.

Thanks a ton,
- Rian

On Mon, Jun 18, 2018 at 6:31 AM, redi at gcc dot gnu.org <
gcc-bugzi...@gcc.gnu.org> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86189
>
> Jonathan Wakely  changed:
>
>What|Removed |Added
> 
> 
>  Status|UNCONFIRMED |WAITING
>Last reconfirmed||2018-06-18
>  Ever confirmed|0   |1
>
> --- Comment #1 from Jonathan Wakely  ---
> (In reply to Rian Quinn from comment #0)
> > template 
> > bool operator==(const myallocator4 &, const myallocator4 &)
> > { return false; }
> >
> > template 
> > bool operator!=(const myallocator4 &, const myallocator4 &)
> > { return true; }
>
> Your allocators *always* compare unequal to all other instances of the same
> allocator. This is invalid, a copy-constructed allocator must compare
> equal to
> the original, and be able to deallocate its memory.
>
> I haven't analysed any further, but I assume that the containers are using
> a
> copy to deallocate, which is perfectly fine. If you think the problem lies
> elsewhere please reopen this.
>
> --
> You are receiving this mail because:
> You reported the bug.

[Bug c++/78130] New: Strict overflow warning appears to be invalid

2016-10-27 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78130

Bug ID: 78130
   Summary: Strict overflow warning appears to be invalid
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rianquinn at gmail dot com
  Target Milestone: ---

Currently bounds checks inside Microsoft's GSL are causing a strict overflow
warning to trigger that appears to be invalid (i.e. the bounds checks should be
fine). The issue has been documented here:
https://github.com/Microsoft/GSL/pull/405

The bounds check looks like this (both count and size() are std::ptrdiff_t):
Expects(count >= 0 && count <= size());

The code can be seen here:
https://github.com/Microsoft/GSL/blob/master/gsl/span#L475

The warning is the following:
warning: assuming signed overflow does not occur when assuming
that (X - c) > X is always false [-Wstrict-overflow]

And the warning occurs on both GCC 5 and 6. Simplifying the code still
generates the warning:
Expects(count >= 0); // fine
Expects(count <= size()); // Generates warning

Doing the following fixes the issue, but is obviously less than ideal:
Expects(count >= 0 && (count < size() || count == size()));

[Bug c++/78130] Strict overflow warning appears to be invalid

2016-10-27 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78130

--- Comment #2 from Rian Quinn  ---
The output:

Using built-in specs.
COLLECT_GCC=/usr/bin/c++
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
5.4.0-6ubuntu1~16.04.2' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-5 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2)
COLLECT_GCC_OPTIONS='-D' 'GSL_THROW_ON_CONTRACT_VIOLATION' '-I'
'/home/user/gsl/build' '-I' '/home/user/gsl/tests/..' '-I'
'/home/user/gsl/tests/./unittest-cpp' '-v' '-save-temps' '-fno-strict-aliasing'
'-std=c++14' '-O3' '-Wall' '-Wno-missing-braces' '-o'
'CMakeFiles/string_span_tests.dir/string_span_tests.cpp.o' '-c'
'-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -E -quiet -v -I /home/user/gsl/build
-I /home/user/gsl/tests/.. -I /home/user/gsl/tests/./unittest-cpp -imultiarch
x86_64-linux-gnu -D_GNU_SOURCE -D GSL_THROW_ON_CONTRACT_VIOLATION
/home/user/gsl/tests/string_span_tests.cpp -mtune=generic -march=x86-64
-std=c++14 -Wall -Wno-missing-braces -fno-strict-aliasing -O3 -fpch-preprocess
-fstack-protector-strong -Wformat-security -o string_span_tests.ii
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/5"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/user/gsl/build
 /home/user/gsl/tests/..
 /home/user/gsl/tests/./unittest-cpp
 /usr/include/c++/5
 /usr/include/x86_64-linux-gnu/c++/5
 /usr/include/c++/5/backward
 /usr/lib/gcc/x86_64-linux-gnu/5/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-D' 'GSL_THROW_ON_CONTRACT_VIOLATION' '-I'
'/home/user/gsl/build' '-I' '/home/user/gsl/tests/..' '-I'
'/home/user/gsl/tests/./unittest-cpp' '-v' '-save-temps' '-fno-strict-aliasing'
'-std=c++14' '-O3' '-Wall' '-Wno-missing-braces' '-o'
'CMakeFiles/string_span_tests.dir/string_span_tests.cpp.o' '-c'
'-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -fpreprocessed string_span_tests.ii
-quiet -dumpbase string_span_tests.cpp -mtune=generic -march=x86-64
-auxbase-strip CMakeFiles/string_span_tests.dir/string_span_tests.cpp.o -O3
-Wall -Wno-missing-braces -std=c++14 -version -fno-strict-aliasing
-fstack-protector-strong -Wformat-security -o string_span_tests.s
GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.2) version 5.4.0 20160609
(x86_64-linux-gnu)
compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR
version 3.1.4, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.2) version 5.4.0 20160609
(x86_64-linux-gnu)
compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR
version 3.1.4, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 15157934e8203caff79287fd8f2d2843
/home/user/gsl/tests/string_span_tests.cpp: In member function ‘virtual void
Suitestring_span_tests::Testzstring::RunImpl() const’:
/home/user/gsl/tests/string_span_tests.cpp:865:329: warning: assuming signed
overflow does not occur when assuming that (X - c) > X is always false
[-Wstrict-overflow]
In file included from /home/user/gsl/tests/../gsl/string_span:24:0,
 from /home/user/gsl/tests/string_span_tests.cpp:19:
/home/user/gsl/tests/../gsl/span:475:9: warning: assuming signed overflow does
not occur when assuming that (X - c) > X is always false [-Wstrict-overflow]
 Expects(count >= 0 && count <= size());
 ^
/home/user/gsl/tests/string_span_tests.cpp: In member function ‘virtual void
Suitestring_span_tests::Testwzstr

[Bug c++/78130] Strict overflow warning appears to be invalid

2016-10-27 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78130

--- Comment #3 from Rian Quinn  ---
Created attachment 39908
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39908&action=edit
ii and s file

[Bug c++/78130] Strict overflow warning appears to be invalid

2016-10-27 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78130

--- Comment #6 from Rian Quinn  ---
Correct me if I'm wrong, but it would appear that this is indeed an bug with
GCC (based on current activity). If that is the case, what would be your
recommendations on how to resolve this issue in the GSL. At the moment, our
current approach is to disable strict overflow, but that seems a bit harsh. 

Any other options?

[Bug c++/68738] New: call to overridden function segfaults

2015-12-06 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68738

Bug ID: 68738
   Summary: call to overridden function segfaults
   Product: gcc
   Version: 5.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rianquinn at gmail dot com
  Target Milestone: ---

Using the TARGET=elf-x86_64 compiler (OS development), I get a strange crash
with C++. The class definition is as follows:

class Blah1
{
public:
Blah1() {}
virtual ~Blah1() {}

virtual int foo() { return 0; }
};

class Blah2 : public Blah1
{
public:
Blah2() {}
~Blah2() {}

int boo() { return 1; }
int foo() override { return 1; }
};

Blah2 g_blah2;

int do_something()
{
Blah2 *p_blah2 = &g_blah2;
int i = p_blah2->foo();  // <- crash here
}

The compiled assembly for this looks something like:

 c68:   48 89 45 e8 mov%rax,-0x18(%rbp)
 c6c:   48 8b 45 e8 mov-0x18(%rbp),%rax
 c70:   48 8b 00mov(%rax),%rax
 c73:   48 83 c0 10 add$0x10,%rax
 c77:   48 8b 00mov(%rax),%rax
 c7a:   48 8b 55 e8 mov-0x18(%rbp),%rdx
 c7e:   48 89 d7mov%rdx,%rdi
 c81:   ff d0   callq  *%rax

What's strange to me is it's not attempting to lookup the global symbol from
the GOT. If I change the code to:

int do_something()
{
Blah2 &p_blah2 = g_blah2;
int i = p_blah2.foo();  // <- works fine
}

And the compiled assembly looks like:

ca3:e8 88 fe ff ff  callq  b30 <_ZN5Blah23fooEv@plt>

Which has the GOT lookup like you would expect. Not sure what's going on here,
but it seems like a bug with G++. 

Thanks,
- Rian

[Bug c++/68738] call to overridden function segfaults

2015-12-07 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68738

--- Comment #2 from Rian Quinn  ---
Yeah I'm am pretty sure it is specific to TARGET=elf-x86_64 (i.e. no OS
specified). When I ran the same test on Ubuntu's native GCC it ran fine.
objdump showed pretty different assembly for the Ubuntu case, vs. the
cross-compiled case. For the code that does not crash (using the reference
instead of the pointer) the code is identical.

[Bug c++/68738] call to overridden function segfaults

2015-12-07 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68738

--- Comment #3 from Rian Quinn  ---
Just for completeness, here is the exact code out objdump output:

class Blah1
{
public:
Blah1() {}
virtual ~Blah1() {}

virtual int foo() { return 0; }
};

class Blah2 : public Blah1
{
public:
Blah2() {}
~Blah2() {}

int foo() override { return 1; }
};

Blah2 g_blah2;

void
do_something()
{
Blah2 *bp1 = &g_blah2;
Blah2 &bp2 = g_blah2;
bp1->foo();   // Crashes
bp2.foo();// Does not crash
}

Using the cross-compiler (TARGET=x86_64-elf) you get the following:

0cd5 <_Z12do_somethingv>:
 cd5:   55  push   %rbp
 cd6:   48 89 e5mov%rsp,%rbp
 cd9:   48 83 ec 10 sub$0x10,%rsp
 cdd:   48 8b 05 3c 07 20 00mov0x20073c(%rip),%rax# 201420
<_DYNAMIC+0x150>
 ce4:   48 89 45 f8 mov%rax,-0x8(%rbp)
 ce8:   48 8b 05 31 07 20 00mov0x200731(%rip),%rax# 201420
<_DYNAMIC+0x150>
 cef:   48 89 45 f0 mov%rax,-0x10(%rbp)
 cf3:   48 8b 45 f8 mov-0x8(%rbp),%rax
 cf7:   48 8b 00mov(%rax),%rax
 cfa:   48 83 c0 10 add$0x10,%rax
 cfe:   48 8b 00mov(%rax),%rax
 d01:   48 8b 55 f8 mov-0x8(%rbp),%rdx
 d05:   48 89 d7mov%rdx,%rdi
 d08:   ff d0   callq  *%rax
 d0a:   48 8b 45 f0 mov-0x10(%rbp),%rax
 d0e:   48 89 c7mov%rax,%rdi
 d11:   e8 5a fe ff ff  callq  b70 <_ZN5Blah23fooEv@plt>
 d16:   90  nop
 d17:   c9  leaveq
 d18:   c3  retq

For the Native Ubuntu compiler I get:

00400b58 <_Z12do_somethingv>:
  400b58:   55  push   %rbp
  400b59:   48 89 e5mov%rsp,%rbp
  400b5c:   48 83 ec 10 sub$0x10,%rsp
  400b60:   48 c7 45 f0 50 22 60movq   $0x602250,-0x10(%rbp)
  400b67:   00
  400b68:   48 c7 45 f8 50 22 60movq   $0x602250,-0x8(%rbp)
  400b6f:   00
  400b70:   48 8b 45 f0 mov-0x10(%rbp),%rax
  400b74:   48 8b 00mov(%rax),%rax
  400b77:   48 83 c0 10 add$0x10,%rax
  400b7b:   48 8b 00mov(%rax),%rax
  400b7e:   48 8b 55 f0 mov-0x10(%rbp),%rdx
  400b82:   48 89 d7mov%rdx,%rdi
  400b85:   ff d0   callq  *%rax
  400b87:   48 8b 45 f8 mov-0x8(%rbp),%rax
  400b8b:   48 89 c7mov%rax,%rdi
  400b8e:   e8 9f 06 00 00  callq  401232 <_ZN5Blah23fooEv>
  400b93:   90  nop
  400b94:   c9  leaveq
  400b95:   c3  retq


The flags I am passing to the cross-compiler are:

-fpic -fno-rtti -fno-sized-deallocation -fno-exceptions -fno-use-cxa-atexit
-fno-threadsafe-statics

- Rian

[Bug c++/68738] call to overridden function segfaults

2015-12-28 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68738

--- Comment #4 from Rian Quinn  ---
To expand on this issue, any attempt to use the following pattern will result
in instability:

some_type *p = &var;
*p or p-> // Crash

A couple of situations that I have seen include:
- allocate memory in global or local space (i.e. static). In this case, the
crash does not occur all the time. I would have to run our code several times
before the code crashes. What was strange with this example was the pointers
were all fine (i.e. if I printed out the pointers, they were what I expected,
but random attempting to access that pointer using the pointer to reference
pattern above would result in a crash sometimes. 

- Getting a pointer to a reference to a member variable of a class would result
in a crash consistently. For example, create two member variables in a class
p_blah and m_blah, and then in the constructor set as follows: p_blah(&m_blah),
the pointer is the correct memory address, but attempts to access the pointer
segfault. 

Also, running all of this code on the Linux version of TARGET=elf-x86_64 works
fine (at least on Ubuntu). Also, everything else seems to be working great. The
only issue we ever see is any attempt to use the above pattern. Once this is
done, the code will either crash instantly, or will crash at random times. For
now, we are avoiding this pattern completely.

[Bug c++/68738] call to overridden function segfaults

2016-01-08 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68738

Rian Quinn  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #5 from Rian Quinn  ---
It appears to be resolved by simply executing the symbols located in .ctors /
.dtors. Although these sections are documented as being dedicated for globally
defined constructors / destructors, on x86_64, they actually point to a set of
functions labeled:

_GLOBAL__sub_I_XXX
_GLOBAL__sub_D_XXX

which appear to call:

_Z41__static_initialization_and_destruction_0ii

Once this symbol is executed, not only are the globally defined constructors /
destructors executed, but the crashes that were identified in this bug report
are also addressed. This includes crashes for pointers to globally defined
classes, but also pointers to member variables.

[Bug c++/71978] New: -mrealignstack and the unwinder

2016-07-22 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71978

Bug ID: 71978
   Summary: -mrealignstack and the unwinder
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: rianquinn at gmail dot com
  Target Milestone: ---

I think there is an issue with GCC 6.1, -mrealignstack and expressions. We use
-mrealignstack because without it, "-O3" crashes when we set the arch to
sandybridge (as SSE instructions are inserted, and the stack ends up being
misaligned). 

We have our own custome unwinder, and it worked great until we started testing
6.1 (i.e. this issue does not occur with 5.X). With 6.1, DWARF expressions are
used. It appears that the CFA offset "sign" is backwards. Here is offending
FDE:

0d98 0044 0d04 FDE cie=0098
pc=00019282..00019d80
  Augmentation data: 96 63 00 00

  DW_CFA_advance_loc: 5 to 00019287
  DW_CFA_def_cfa: r10 (r10) ofs 0
  DW_CFA_advance_loc: 9 to 00019290
  DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0)
  DW_CFA_advance_loc: 7 to 00019297
  DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -16; DW_OP_deref)
  DW_CFA_expression: r12 (r12) (DW_OP_breg6 (rbp): -8)
  DW_CFA_advance_loc: 8 to 0001929f
  DW_CFA_expression: r3 (rbx) (DW_OP_breg6 (rbp): -24)
  DW_CFA_advance_loc2: 2775 to 00019d76
  DW_CFA_restore: r3 (rbx)
  DW_CFA_advance_loc: 2 to 00019d78
  DW_CFA_restore: r10 (r10)
  DW_CFA_def_cfa: r10 (r10) ofs 0
  DW_CFA_advance_loc: 2 to 00019d7a
  DW_CFA_restore: r12 (r12)
  DW_CFA_advance_loc: 1 to 00019d7b
  DW_CFA_restore: r6 (rbp)
  DW_CFA_advance_loc: 4 to 00019d7f
  DW_CFA_def_cfa: r7 (rsp) ofs 8
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

As you can see, the CFA is defined as -16 from rbp which is wrong. It should be
+16 from rbp. Besides the fact that it doesn't make sense for the CFA to be
inside the existing CFA... if the other registers are 0, -8 and -24... how
could the start of the CFA be -16, in the middle of register state. 

The result is RIP which is -8 from the CFA, ends up being a heap address and
the unwinder gets mad. To prove to myself that the offset should have been +16,
I swapped the sign just for CFA offset, and the unwinder worked great again. To
pull this hack off, I had to store a flag for DW_OP_breg6. When it's
calculating the location of the CFA, it swaps the sign, otherwise it keeps the
sign as is. Doing this, the unwinder successfully throws exceptions again. 

Just for more complete reference, here is an FDE from the same library that
doesn't use expressions. In this case, you can see the offset being +16... so
it's only an issue with 6.1 with -mrealignstack in FDEs that use expressions. 

00b8 0024 0024 FDE cie=0098
pc=00020b20..00020b5d
  Augmentation data: 3f 6f 00 00

  DW_CFA_advance_loc: 1 to 00020b21
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r6 (rbp) at cfa-16
  DW_CFA_advance_loc: 3 to 00020b24
  DW_CFA_def_cfa_register: r6 (rbp)
  DW_CFA_advance_loc: 56 to 00020b5c
  DW_CFA_restore: r6 (rbp)
  DW_CFA_def_cfa: r7 (rsp) ofs 8
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

Also... the GCC 6.1 compiler is x86_64-elf-g++ (i.e. generic 64bit cross
compiler).

[Bug target/71978] -mrealignstack and the unwinder

2016-07-22 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71978

--- Comment #2 from Rian Quinn  ---
We throw here:
https://github.com/rianquinn/hypervisor/blob/expression_support/bfvmm/src/vmcs/src/vmcs_intel_x64.cpp#L514

The following is were the issue is (meaning the unwinder unwinds until it hits
this function, and fails to move onto the next frame as this is the first
function that it hits that has expressions)
https://github.com/rianquinn/hypervisor/blob/expression_support/bfvmm/src/vmcs/src/vmcs_intel_x64.cpp#L41

Here is were I put in the hack in the unwinder to make it work:
https://github.com/rianquinn/hypervisor/blob/expression_support/bfunwind/src/dwarf4.cpp#L1015

Usually, I would pass in "0" as the initial value for the DWARF expression
parsing, but I changed this to "1" which I look for which tells me this is a
DW_CFA_def_cfa_expression and not a DW_CFA_expression (as I set "1" on
private_decode_cfa). With this hack in place, the unwinder works fine. 

Here is the assembly for the function that it cannot get passed:
00019282
<_ZN14vmcs_intel_x646launchERKNSt3__110shared_ptrI20vmcs_intel_x64_stateEES5_>:
   19282:   4c 8d 54 24 08  lea0x8(%rsp),%r10
   19287:   48 83 e4 f0 and$0xfff0,%rsp
   1928b:   41 ff 72 f8 pushq  -0x8(%r10)
   1928f:   55  push   %rbp
   19290:   48 89 e5mov%rsp,%rbp
   19293:   41 54   push   %r12
   19295:   41 52   push   %r10
   19297:   53  push   %rbx
   19298:   48 81 ec 18 02 00 00sub$0x218,%rsp
   1929f:   48 89 bd e8 fd ff ffmov%rdi,-0x218(%rbp)
   192a6:   48 89 b5 e0 fd ff ffmov%rsi,-0x220(%rbp)
   192ad:   48 89 95 d8 fd ff ffmov%rdx,-0x228(%rbp)
   192b4:   48 8b 05 cd c6 07 00mov0x7c6cd(%rip),%rax#
95988 <_GLOBAL_OFFSET_TABLE_+0x128>
   192bb:   48 8b 18mov(%rax),%rbx
   192be:   48 89 5d d8 mov%rbx,-0x28(%rbp)
   192c2:   31 db   xor%ebx,%ebx
   192c4:   48 8b 8d e8 fd ff ffmov-0x218(%rbp),%rcx
   192cb:   48 8d 85 60 ff ff fflea-0xa0(%rbp),%rax
   192d2:   ba 00 00 00 00  mov$0x0,%edx
   192d7:   48 89 cemov%rcx,%rsi
   192da:   48 89 c7mov%rax,%rdi
   192dd:   e8 aa 41 00 00  callq  1d48c
<_ZNSt3__18functionIFvvEEC1IZN14vmcs_intel_x646launchERKNS_10shared_ptrI20vmcs_intel_x64_stateEES9_EUlvE_EET_PNS_9enable_ifIXaasrNS2_10__callableISB_XaantsrNS_7is_sameISB_S2_EE5valuesrNS_11__invokableIRSB_JEEE5valueEEE5valuentsrSF_5valueEvE4typeE>
   192e2:   48 8d 95 60 ff ff fflea-0xa0(%rbp),%rdx
   192e9:   48 8d 45 90 lea-0x70(%rbp),%rax
   192ed:   48 89 d6mov%rdx,%rsi
   192f0:   48 89 c7mov%rax,%rdi
   192f3:   e8 c8 f7 ff ff  callq  18ac0
<_ZN14vmcs_intel_x64C1ERKNSt3__110shared_ptrI20intrinsics_intel_x64EE-0x270>
   192f8:   48 8d 85 60 ff ff fflea-0xa0(%rbp),%rax
   192ff:   48 89 c7mov%rax,%rdi
   19302:   e8 99 f4 ff ff  callq  187a0
<_ZN14vmcs_intel_x64C1ERKNSt3__110shared_ptrI20intrinsics_intel_x64EE-0x590>
   19307:   48 8b 85 e8 fd ff ffmov-0x218(%rbp),%rax
   1930e:   48 8b 00mov(%rax),%rax
   19311:   48 83 c0 20 add$0x20,%rax
   19315:   48 8b 00mov(%rax),%rax
   19318:   48 8b 95 e8 fd ff ffmov-0x218(%rbp),%rdx
   1931f:   48 89 d7mov%rdx,%rdi
   19322:   ff d0   callq  *%rax
   19324:   48 8b 85 e8 fd ff ffmov-0x218(%rbp),%rax
   1932b:   48 8b 00mov(%rax),%rax
   1932e:   48 83 c0 30 add$0x30,%rax
   19332:   48 8b 00mov(%rax),%rax
   19335:   48 8b 95 e8 fd ff ffmov-0x218(%rbp),%rdx
   1933c:   48 89 d7mov%rdx,%rdi
   1933f:   ff d0   callq  *%rax
   19341:   48 8b 85 e8 fd ff ffmov-0x218(%rbp),%rax
   19348:   48 83 c0 08 add$0x8,%rax
   1934c:   48 89 85 f8 fd ff ffmov%rax,-0x208(%rbp)
   19353:   48 8b 85 f8 fd ff ffmov-0x208(%rbp),%rax
   1935a:   48 8b 00mov(%rax),%rax
   1935d:   48 8b 10mov(%rax),%rdx
   19360:   48 81 c2 a8 01 00 00add$0x1a8,%rdx
   19367:   48 8b 12mov(%rdx),%rdx
   1936a:   48 8b 8d e8 fd ff ffmov-0x218(%rbp),%rcx
   19371:   48 83 c1 18 add$0x18,%rcx
   19375:   48 89 cemov%rcx,%rsi
   19378:   48 89 c7mov%rax,%rdi
   1937b:   ff d2   callq  *%rdx
   1937d:   83 f0 01   

[Bug target/71978] -mrealignstack and the unwinder

2016-07-22 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71978

--- Comment #4 from Rian Quinn  ---
Is this it? Never done that before:
https://github.com/rianquinn/hypervisor/tree/expression_support/tmp

[Bug target/71978] -mrealignstack and the unwinder

2016-08-03 Thread rianquinn at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71978

Rian Quinn  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #5 from Rian Quinn  ---
Turns out this was an issue with our unwinder. For whatever reason, I missed
the "DW_OP_deref" opcode in the output which was needed to make all of this
make sense. Our unwinder was missing the last instruction as we were using "<"
instead of "<=". 

I closed this as the bug is invalid.