public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* std::string clobbers memory when compiling without optimizations
@ 2014-10-03  8:19 Henrik Mannerström
  2014-10-03  9:58 ` Jonathan Wakely
  0 siblings, 1 reply; 7+ messages in thread
From: Henrik Mannerström @ 2014-10-03  8:19 UTC (permalink / raw)
  To: gcc-help

Hello,

I found a program that produces incorrect behavior when compiling with
-Og or without optimization. By running gdb I can pinpoint the problem
to the std::string constructor, but I have to do more research to be
able to step through that with gdb. My minimal working example is not so
minimal, but I have not been able to reproduce the problem with a
smaller program. The Eigen library used is from eigen.tuxfamily.org . On
the line indicated by "Correct output" the program prints what I expect,
two lines later, the contents has changed. With gdb I can see that the
memory content is changed by the std::string namestring(name) line in
the t2s function. Watching the memory location that is changed gives 
std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::basic_string(char const*, std::allocator<char> const&)  as the
offending location. Compiling with  g++-4.9 -std=c++11  gives the error,
but adding -O1 produces correct results.

Do you have any suggestions on what to do next?

BR,
Henrik Mannerström




#include <cxxabi.h>
#include <string>
#include <typeinfo>
#include <cstdlib>

template <typename T>
std::string t2s(T tt) {
  char *name;
  int status;
  name = abi::__cxa_demangle(typeid(tt).name(), 0, 0, &status);
  std::string namestring(name); // Variable Sigma from main is changed
at this line.
  std::free(name);
  return namestring;
}

#include <Eigen/Core>
#include <iostream>

int main() {
  typedef Eigen::Matrix<double, 1, 3> cVector;

  const cVector mean = (cVector() << 1, 2, 3).finished();
  const auto Sigma = (cVector() << 1, 1, 1).finished().asDiagonal();

  std::cout << "Correct diagonal: " << Sigma.diagonal() << std::endl; //
Correct output: 1 1 1

  std::cout << t2s(mean) << std::endl;

  std::cout << "Incorrect diagonal: " << Sigma.diagonal() << std::endl;
// Incorrect output: [random double] 1 1
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: std::string clobbers memory when compiling without optimizations
  2014-10-03  8:19 std::string clobbers memory when compiling without optimizations Henrik Mannerström
@ 2014-10-03  9:58 ` Jonathan Wakely
  2014-10-03 10:09   ` Henrik Mannerström
  0 siblings, 1 reply; 7+ messages in thread
From: Jonathan Wakely @ 2014-10-03  9:58 UTC (permalink / raw)
  To: Henrik Mannerström; +Cc: gcc-help

On 3 October 2014 09:18, Henrik Mannerström wrote:
> Do you have any suggestions on what to do next?

Have you tried valgrind?

Or compiling with GCC's -fstack-protector option?

I can't reproduce the problem, and I think it's pretty unlikely
std::string has that kind of bug without someone noticing years ago.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: std::string clobbers memory when compiling without optimizations
  2014-10-03  9:58 ` Jonathan Wakely
@ 2014-10-03 10:09   ` Henrik Mannerström
  2014-10-03 10:20     ` Jonathan Wakely
  0 siblings, 1 reply; 7+ messages in thread
From: Henrik Mannerström @ 2014-10-03 10:09 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

Hi,

On 10/03/2014 12:58 PM, Jonathan Wakely wrote:
> Have you tried valgrind? Or compiling with GCC's -fstack-protector
> option? I can't reproduce the problem, and I think it's pretty
> unlikely std::string has that kind of bug without someone noticing
> years ago. 

I'm not assuming that std::string has a bug (even though the title might
suggest that), I'm just saying that the gdb watchpoint is triggered
inside that function. I tried valgrind memcheck, but I'm no expert, so
suggestions are welcome. Below is the output with stack-protector, what
do you make out of it? Could it be my installation?

- Henrik


$ g++-4.9 -std=gnu++1y mvu.cc  -o mvu
$ ./mvu
Correct diagonal: 1 1 1
Eigen::Matrix<double, 1, 3, 1, 1, 3>
Incorrect diagonal: 1.81749e-316            1            1
$ g++-4.9 -std=gnu++1y -fstack-protector-all mvu.cc  -o mvu
$ ./mvu
Correct diagonal: 1 1 1
Eigen::Matrix<double, 1, 3, 1, 1, 3>
Incorrect diagonal: 1 2 3
$ g++-4.9 -std=gnu++1y -O1 -fstack-protector-all  mvu.cc  -o mvu
$ ./mvu
Correct diagonal: 1 1 1
Eigen::Matrix<double, 1, 3, 1, 1, 3>
Incorrect diagonal: 1 1 1

g++-4.9 (Ubuntu 4.9.1-3ubuntu2~14.04.1) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: std::string clobbers memory when compiling without optimizations
  2014-10-03 10:09   ` Henrik Mannerström
@ 2014-10-03 10:20     ` Jonathan Wakely
  2014-10-03 10:31       ` Henrik Mannerström
  2014-10-03 10:31       ` Marc Glisse
  0 siblings, 2 replies; 7+ messages in thread
From: Jonathan Wakely @ 2014-10-03 10:20 UTC (permalink / raw)
  To: Henrik Mannerström; +Cc: gcc-help

On 3 October 2014 11:08, Henrik Mannerström wrote:
> Hi,
>
> On 10/03/2014 12:58 PM, Jonathan Wakely wrote:
>> Have you tried valgrind? Or compiling with GCC's -fstack-protector
>> option? I can't reproduce the problem, and I think it's pretty
>> unlikely std::string has that kind of bug without someone noticing
>> years ago.
>
> I'm not assuming that std::string has a bug (even though the title might
> suggest that), I'm just saying that the gdb watchpoint is triggered
> inside that function. I tried valgrind memcheck, but I'm no expert, so
> suggestions are welcome. Below is the output with stack-protector, what
> do you make out of it? Could it be my installation?
>
> - Henrik
>
>
> $ g++-4.9 -std=gnu++1y mvu.cc  -o mvu
> $ ./mvu
> Correct diagonal: 1 1 1
> Eigen::Matrix<double, 1, 3, 1, 1, 3>
> Incorrect diagonal: 1.81749e-316            1            1
> $ g++-4.9 -std=gnu++1y -fstack-protector-all mvu.cc  -o mvu
> $ ./mvu
> Correct diagonal: 1 1 1
> Eigen::Matrix<double, 1, 3, 1, 1, 3>
> Incorrect diagonal: 1 2 3

I get the same "1 2 3" result using -fstack-protector-all and valgrind.

My guess is that Sigma holds a dangling reference to some temporary
object that has gone out of scope, and the function call t2s
overwrites that stack memory, then when you return to main you go
through the dangling reference.

Are you sure you're using the Eigen types correctly?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: std::string clobbers memory when compiling without optimizations
  2014-10-03 10:20     ` Jonathan Wakely
  2014-10-03 10:31       ` Henrik Mannerström
@ 2014-10-03 10:31       ` Marc Glisse
  1 sibling, 0 replies; 7+ messages in thread
From: Marc Glisse @ 2014-10-03 10:31 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Henrik Mannerström, gcc-help

On Fri, 3 Oct 2014, Jonathan Wakely wrote:

> On 3 October 2014 11:08, Henrik Mannerström wrote:
>> Hi,
>>
>> On 10/03/2014 12:58 PM, Jonathan Wakely wrote:
>>> Have you tried valgrind? Or compiling with GCC's -fstack-protector
>>> option? I can't reproduce the problem, and I think it's pretty
>>> unlikely std::string has that kind of bug without someone noticing
>>> years ago.
>>
>> I'm not assuming that std::string has a bug (even though the title might
>> suggest that), I'm just saying that the gdb watchpoint is triggered
>> inside that function. I tried valgrind memcheck, but I'm no expert, so
>> suggestions are welcome. Below is the output with stack-protector, what
>> do you make out of it? Could it be my installation?
>>
>> - Henrik
>>
>>
>> $ g++-4.9 -std=gnu++1y mvu.cc  -o mvu
>> $ ./mvu
>> Correct diagonal: 1 1 1
>> Eigen::Matrix<double, 1, 3, 1, 1, 3>
>> Incorrect diagonal: 1.81749e-316            1            1
>> $ g++-4.9 -std=gnu++1y -fstack-protector-all mvu.cc  -o mvu
>> $ ./mvu
>> Correct diagonal: 1 1 1
>> Eigen::Matrix<double, 1, 3, 1, 1, 3>
>> Incorrect diagonal: 1 2 3
>
> I get the same "1 2 3" result using -fstack-protector-all and valgrind.
>
> My guess is that Sigma holds a dangling reference to some temporary
> object that has gone out of scope, and the function call t2s
> overwrites that stack memory, then when you return to main you go
> through the dangling reference.
>
> Are you sure you're using the Eigen types correctly?

He is using "auto" with an expression template library, so I'd say that it 
is unlikely he is using it correctly, indeed...

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: std::string clobbers memory when compiling without optimizations
  2014-10-03 10:20     ` Jonathan Wakely
@ 2014-10-03 10:31       ` Henrik Mannerström
  2014-10-03 12:36         ` Jonathan Wakely
  2014-10-03 10:31       ` Marc Glisse
  1 sibling, 1 reply; 7+ messages in thread
From: Henrik Mannerström @ 2014-10-03 10:31 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On 10/03/2014 01:20 PM, Jonathan Wakely wrote:
> My guess is that Sigma holds a dangling reference to some temporary
> object that has gone out of scope, and the function call t2s
> overwrites that stack memory, then when you return to main you go
> through the dangling reference.
>
> Are you sure you're using the Eigen types correctly?
You are right, the auto type does not force the evaluation of Sigma,
which leaves the dangling reference. Yet again I get burned by trying to
combine Eigen and C++11. How would you classify this, could you call it
a bug in Eigen, or just incompatibility with C++11?

Thank you for you time.

- Henrik

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: std::string clobbers memory when compiling without optimizations
  2014-10-03 10:31       ` Henrik Mannerström
@ 2014-10-03 12:36         ` Jonathan Wakely
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Wakely @ 2014-10-03 12:36 UTC (permalink / raw)
  To: Henrik Mannerström; +Cc: gcc-help

On 3 October 2014 11:30, Henrik Mannerström wrote:
> On 10/03/2014 01:20 PM, Jonathan Wakely wrote:
>> My guess is that Sigma holds a dangling reference to some temporary
>> object that has gone out of scope, and the function call t2s
>> overwrites that stack memory, then when you return to main you go
>> through the dangling reference.
>>
>> Are you sure you're using the Eigen types correctly?
> You are right, the auto type does not force the evaluation of Sigma,
> which leaves the dangling reference. Yet again I get burned by trying to
> combine Eigen and C++11. How would you classify this, could you call it
> a bug in Eigen, or just incompatibility with C++11?

As Marc says, expression templates are often incompatible with 'auto',
that doesn't mean Eigen is incompatible with C++11 in general.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-10-03 12:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-03  8:19 std::string clobbers memory when compiling without optimizations Henrik Mannerström
2014-10-03  9:58 ` Jonathan Wakely
2014-10-03 10:09   ` Henrik Mannerström
2014-10-03 10:20     ` Jonathan Wakely
2014-10-03 10:31       ` Henrik Mannerström
2014-10-03 12:36         ` Jonathan Wakely
2014-10-03 10:31       ` Marc Glisse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).