1

I am calling a C++ application from the python script (OS Ubuntu 14.04) like this:

import sys, subprocess
run = subprocess.Popen(['app'] + args, stdout = subprocess.PIPE,
                       stderr = subprocess.PIPE)
stdout, stderr = run.communicate()
if stderr:
    sys.stderr.write('Error in app: ' + stderr.decode('utf-8'))
    sys.exit(1)

Then I get the following error message (although the address is different every time):

*** Error in `/usr/bin/app': double free or corruption (!prev): 0x00007f50eae98070 ***

The app itself is a third-party binary, that means, I have no access to the source code. However, even under suggestion that there is some bug in app that causes deletion attempt the same entity twice there are 3 strangenesses in the behaviour that I cannot understand:

  1. The error occurs randomly and rather rare (around 20% of all runs on the very same data). Some other users of the app get this error as well; however, some of them never get it.
  2. It does not get caught in the stderr stream of the subprocess (and therefore sys.exit(1) does not get executed).
  3. Sometimes I see top instead of !prev in the brackets.

Can someone explain me, how these features can be originated or even give an example C++ code that reproduces this behaviour?

Roman
  • 2,225
  • 5
  • 26
  • 55
  • 2
    Well, clearly the bug is in code that you didn't post. double free means you freed the same thing twice, e.g. `int* p = new int; delete p; delete p;` – Barry Sep 02 '15 at 12:59
  • 2
    As for the *not appearing on `stderr`*: gcc (and probably glibc) [open `/dev/tty` directly](http://stackoverflow.com/questions/31301711/how-can-a-unix-program-display-output-on-screen-even-when-stdout-and-stderr-are/31302382#31302382) to output such fatal errors bypassing IO redirection. – dhke Sep 02 '15 at 13:00

1 Answers1

7

Double free is exactly what it means :

int *a = new int;
delete a;
delete a;

For corruption something like :

int *a = new int[10];
a++;
delete a;

This message is generated by glibc when an app request to free some memory that was already freed, or the address does not correspond to an address obtained at allocation time.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • In this case I observe the error permanently and **not** from time to time – Roman Sep 02 '15 at 13:04
  • 3
    @Roman The problem with this is that when a double free occurs, the behaviour is undefined. Thus no one can guarantee code that reproduces the issue. For example, if the pointer is NULL, double-freeing such a value is perfectly ok. But if for some reason that pointer is not NULL, then that is no doubt an error, thus increasing the chance it will get reported. – PaulMcKenzie Sep 02 '15 at 13:06
  • @Roman This is an example of a double free (that is exactly what you requested no?), but this kind of code can be embedded in a complex structure of conditions/loops that sometimes are all true and sometimes not, depending on the context. – Jean-Baptiste Yunès Sep 02 '15 at 13:12