Bug 13363 - gdb crash when I try to print a std::queue in python pretty printer
Summary: gdb crash when I try to print a std::queue in python pretty printer
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: python (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 7.4
Assignee: Phil Muldoon
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-31 08:48 UTC by asmwarrior
Modified: 2011-11-04 12:08 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
lookup type patch (777 bytes, patch)
2011-11-01 11:25 UTC, Phil Muldoon
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description asmwarrior 2011-10-31 08:48:16 UTC
Hi,I'm bulding a cvs head gdb 2011-10-30 with python enabled. 
I'm using Windows XP.
When I try to print a std::queue, gdb crashed. I use a another gdb to test the crash bug.

My test code is below:

----------------------------------------------------------------

#include <wx/wx.h>
#include <string>
#include <map>
#include <list>
#include <stack>
#include <vector>
#include <queue>

#include <windows.h>


const static std::string apms[5]={"&amp;","&lt;","&gt;","&quot;","&apos;"};


int main()
{
    wxString *psty = (wxString*) NULL;
    wxString wxStr(L"wxString");
    wxStr += L" Value";
    std::string stdStr("std::string");
    stdStr.append(" value");
    std::map<int, std::string> m;
    m[0] = "000";
    m[1] = "111";
    wxString& wxStrRef = wxStr;
    wxStrRef += L" Ref";
    std::string& stdStrRef = stdStr;
    stdStrRef += " Ref";

    std::list<std::string> l = {"a", "b", "c"};
    std::vector<std::string> v = {"a", "b", "c"};
    std::queue<std::string> q;
    q.push("a");
    q.push("b");

    std::stack<std::string> s;
    s.push("a");
    s.push("b");
    asm("int $3");

    return 0;
}
-------------------------------------------------
You can remove all the other stuffs and leave only the std::queue code.

I build it in mingw gcc 4.4.5, here is the debug log: 
gdb-python27.exe is the "debugger", and gdb.exe is the "debugee".
the command "source stl.gdb" is just loading the std c++'s python pretty printer. 

E:\code\test_gdb>gdb-python27.exe gdb.exe
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from e:\code\test_gdb\gdb.exe...done.
(gdb) r
Starting program: e:\code\test_gdb\gdb.exe
[New Thread 3644.0x1148]
GNU gdb (GDB) 7.3.50.20111030-cvs
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) [New Thread 3644.0x194]
[New Thread 3644.0x1370]
file a1.exe
Reading symbols from e:\code\test_gdb\a1.exe...done.
(gdb) source stl.gdb
(gdb) r
Starting program: e:\code\test_gdb\a1.exe
[New Thread 4964.0x1700]

Program received signal SIGTRAP, Trace/breakpoint trap.
main () at e:\code\cb\test_code\gdbpython-demo\main.cpp:41
41          return 0;
(gdb) python print 3
3
(gdb) p q
$1 =
Program received signal SIGSEGV, Segmentation fault.
0x77c47a64 in strncmp () from C:\WINDOWS\system32\msvcrt.dll
(gdb) bt
#0  0x77c47a64 in strncmp () from C:\WINDOWS\system32\msvcrt.dll
#1  0x005a6474 in typy_lookup_typename (type_name=0x0, block=0x0)
    at ../../gdb/gdb/python/py-type.c:586
#2  0x005a66f3 in typy_lookup_type (demangled=0x5015a90, block=0x0)
    at ../../gdb/gdb/python/py-type.c:650
#3  0x005a6867 in typy_legacy_template_argument (type=0x508f3a0, block=0x0,
    argno=0) at ../../gdb/gdb/python/py-type.c:714
#4  0x005a6a09 in typy_template_argument (self=0x2d147b8, args=0x2d2c7d0)
    at ../../gdb/gdb/python/py-type.c:759
#5  0x1e08883b in python27!PyCFunction_Call ()
   from E:\code\common_bin\python27.dll
#6  0x1e0bf781 in python27!PyEval_GetFuncDesc ()
   from E:\code\common_bin\python27.dll
#7  0x02d50080 in ?? ()
#8  0x1e1d57f8 in python27!PySuper_Type ()
   from E:\code\common_bin\python27.dll
#9  0x00000001 in ?? ()
#10 0x02a4e684 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) frame 1
#1  0x005a6474 in typy_lookup_typename (type_name=0x0, block=0x0)
    at ../../gdb/gdb/python/py-type.c:586
586           if (!strncmp (type_name, "struct ", 7))
(gdb) info locals
type = 0x0
except = {reason = 0, error = GDB_NO_ERROR, message = 0x0}
(gdb) info args
type_name = 0x0
block = 0x0
(gdb)


So, it looks like the crash is here:

\gdb\python\py-type.c

static struct type *
typy_lookup_typename (const char *type_name, const struct block *block)
{
  struct type *type = NULL;
  volatile struct gdb_exception except;

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      if (!strncmp (type_name, "struct ", 7))
    type = lookup_struct (type_name + 7, NULL);
      else if (!strncmp (type_name, "union ", 6))
    type = lookup_union (type_name + 6, NULL);
      else if (!strncmp (type_name, "enum ", 5))
    type = lookup_enum (type_name + 5, NULL);
      else
    type = lookup_typename (python_language, python_gdbarch,
                type_name, block, 0);
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      return NULL;
    }

  return type;
}

It looks like the input argument "type_name" and "block" is all ZERO.

BTW: If I use a gdb 2011-10-27 build, then there is no such crash. So, I guess it was a regression in 2011-10-27 to 2011-10-30.

Thanks.
asmwarrior

PS: I originally wrote a post in gdb maillist, see: http://sourceware.org/ml/gdb/2011-10/msg00226.html
Comment 1 Phil Muldoon 2011-10-31 12:34:35 UTC
I tried reproducing this today with the current repository HEAD, but I cannot reproduce it.  Do you have a custom pretty-printer? What is stl.gdb?

(gdb) list
1	#include <queue>
2	#include <string>
3	
4	int main()
5	{
6	    std::queue<std::string> q;
7	    q.push("a");
8	    q.push("b");
9	    
10	    return 0;
(gdb) b 10
Breakpoint 1 at 0x400aac: file repo.cc, line 10.
(gdb) r

Breakpoint 1, 
main () at repo.cc:10
10	    return 0;
(gdb) py print 3
3
(gdb) p q
$1 = std::queue wrapping: std::deque with 2 elements = {"a", "b"}
Comment 2 Phil Muldoon 2011-10-31 12:45:39 UTC
Can you rerun your testcase on your setup, but first type:

set python print-stack on

lookup_type seems to be failing to find a type from the demangled argument, and typename is NULL.  But until I can reproduce locally, it is really difficult to discern what is going
Comment 3 asmwarrior 2011-10-31 14:35:03 UTC
stl.gdb is below:

python
import sys
sys.path.insert(0, '')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

I have a folder libstdcxx from gcc trunk.

Note: if the program build from gcc 4.6.2, then gdb no crash, but if the test program is built from gcc 4.4.x, then gdb will crash on “print std::queue”. or “print std::stack”.
Comment 4 Phil Muldoon 2011-10-31 14:57:42 UTC
[pmuldoon@localhost gdb]$ rpm -q gcc
gcc-4.5.1-4.fc14.x86_64

I have above ^^.  I do not have access to a windows based machine, so I am trying to figure out the next step.  There is a logic error in the Python GDB code that should be a NULL check for:

type_name = cp_comp_to_string (demangled, 10);

Before passing type_name to lookup_typename.  This logic is in typy_lookup_type.  That will avoid the crash, but GDB will still not have a typename to lookup.  It would help if we could track down the particular GCC revision where this works, adn does not work, so we can attempt to find if a GCC bug has been filed.
Comment 5 asmwarrior 2011-11-01 01:41:18 UTC
Hi Phil Muldoon:
I just do a test on whether your commit will cause the crash, the result is: YES!

Here is my test:
I currently build the gdb with:
-------------------------
mkdir 2011-11-01
cd 2011-11-01
CFLAGS="-O0 -g" \
../gdb/configure \
--prefix=/mingw \
--host=mingw32 \
--build=mingw32 \
--target=mingw32 \
--with-python=/python/python \
--with-expat \
--disable-nls
-------------------------
Now, first, I build the gdb git version: 
Revision: eaafbca6b136e71ae0fafb8dbfda92c9fad14a29
Author: gdbadmin
Date: 2011-10-31 8:00:03
Message:
*** empty log message ***
----
Modified : gdb/version.in
)

And I just do the test, and the result the bad, gdb crashes. see the log:(looks like the command "set python print-stack on" does not show anything on the crash.

-------------------------------
E:\test_gdb>gdb-python27.exe gdb.exe
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from e:\test_gdb\gdb.exe...done.
(gdb) r
Starting program: e:\test_gdb\gdb.exe
[New Thread 1016.0x4d4]
GNU gdb (GDB) 7.3.50.20111031-cvs
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) [New Thread 1016.0xe64]
[New Thread 1016.0x8b4]
file a1.exe
Reading symbols from e:\test_gdb\a1.exe...done.
(gdb) source stl.gdb
(gdb) r
Starting program: e:\test_gdb\a1.exe
[New Thread 3252.0xc04]

Program received signal SIGTRAP, Trace/breakpoint trap.
main () at E:\code\cb\test_code\gdbpython-demo\main.cpp:41
41      E:\code\cb\test_code\gdbpython-demo\main.cpp: No such file or directory.

        in E:\code\cb\test_code\gdbpython-demo\main.cpp
(gdb) python print 1
1
(gdb) set python print-stack on
(gdb) python print 1
1
(gdb) p q
$1 =
Program received signal SIGSEGV, Segmentation fault.
0x005ac3a0 in typy_lookup_typename (type_name=0x0, block=0x0)
    at ../../gdb/gdb/python/py-type.c:586
586           if (!strncmp (type_name, "struct ", 7))
(gdb) bt
#0  0x005ac3a0 in typy_lookup_typename (type_name=0x0, block=0x0)
    at ../../gdb/gdb/python/py-type.c:586
#1  0x005ac647 in typy_lookup_type (demangled=0x534bb60, block=0x0)
    at ../../gdb/gdb/python/py-type.c:650
#2  0x005ac7bb in typy_legacy_template_argument (type=0x4e94378, block=0x0,
    argno=0) at ../../gdb/gdb/python/py-type.c:714
#3  0x005ac95d in typy_template_argument (self=0x2c84608, args=0x2c9c870)
    at ../../gdb/gdb/python/py-type.c:759
#4  0x1e08883b in python27!PyCFunction_Call ()
   from F:\cb\common_bin\python27.dll
#5  0x1e0bf781 in python27!PyEval_GetFuncDesc ()
   from F:\cb\common_bin\python27.dll
#6  0x02cc0198 in ?? ()
#7  0x1e1d57f8 in python27!PySuper_Type () from F:\cb\common_bin\python27.dll
#8  0x00000001 in ?? ()
#9  0x029be64c in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) q
A debugging session is active.

        Inferior 1 [process 1016] will be killed.

Quit anyway? (y or n) y

E:\test_gdb>
--------------------------------------------------------

Then I have look at your commit:
Revision: babf52b2dc571b5823c9985dde9015b9d011ce03
Author: pmuldoon
Date: 2011-10-27 17:14:26
Message:
2011-10-27  Phil Muldoon  <pmuldoon@redhat.com>

* python/py-breakpoint.c (bppy_set_enabled): Use TRY_CATCH.
	(bppy_set_task): Ditto.
	(bppy_delete_breakpoint): Ditto.
	* python/py-symbol.c (gdbpy_lookup_symbol): Ditto.
	(gdbpy_lookup_global_symbol): Ditto.
	* python/py-lazy-string.c (stpy_convert_to_value): Ditto.
	* python/py-frame.c (frapy_is_valid): Ditto.
	(frame_info_to_frame_object): Ditto.
	* python/py-type.c (typy_lookup_type): Ditto.
	(typy_getitem): Ditto.
	(typy_has_key): Ditto.
	(typy_richcompare): Use TRY_CATCH.  Do not return Py_NE on error.
----
Modified : gdb/ChangeLog
Modified : gdb/python/py-breakpoint.c
Modified : gdb/python/py-frame.c
Modified : gdb/python/py-lazy-string.c
Modified : gdb/python/py-symbol.c
Modified : gdb/python/py-type.c


I'm using TortoiseGit under Windows XP, then I just run "revert change by this commit", and build the gdb again. The result gdb does not crash. see the log:
--------------------------
E:\test_gdb>gdb-python27.exe gdb.exe
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from e:\test_gdb\gdb.exe...done.
(gdb) r
Starting program: e:\test_gdb\gdb.exe
[New Thread 2772.0xc3c]
GNU gdb (GDB) 7.3.50.20111031-cvs
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) [New Thread 2772.0xdd4]
[New Thread 2772.0xd40]
file a1.exe
Reading symbols from e:\test_gdb\a1.exe...done.
(gdb) source stl.gdb
(gdb) set python print-stack on
(gdb) r
Starting program: e:\test_gdb\a1.exe
[New Thread 3544.0xdac]

Program received signal SIGTRAP, Trace/breakpoint trap.
main () at E:\code\cb\test_code\gdbpython-demo\main.cpp:41
41      E:\code\cb\test_code\gdbpython-demo\main.cpp: No such file or directory.

        in E:\code\cb\test_code\gdbpython-demo\main.cpp
(gdb) python print 1
1
(gdb) p q
$1 = std::queue wrapping: std::deque with 2 elements = {"a", "b"}
(gdb)
--------------------------------------------

So, I still think that your commit has some relation to the crash of gdb.

BTW: The above test program "a1.exe" is built from gcc 4.4.5.

If I build the "a1.exe" from gcc 4.6.2, then both the gdb with your commit babf52b2dc571b5823c9985dde9015b9d011ce03 or without your commit do NOT crash.

So, your commit is not friendly to gcc 4.4.5?
Any ideas?
Comment 6 Phil Muldoon 2011-11-01 08:30:46 UTC
If you look at the commit for that function, all it adds is an exception handler for GDB exceptions.  Because the function reaches:

type = typy_lookup_typename (type_name, block);

Below the exception handler, then no exceptions have been generated in the preceding function calls in the exception handler block.  This means that all of the above functions succeeded without generating an exception.  So when it reaches the lookup_typename, then it has already passed any/all of the changes in that commit.

So if we look at the commit here:

http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/python/py-type.c.diff?cvsroot=src&r1=1.26&r2=1.27

You will see that that if the demangle type matches any case in the switch statement, then the function will exit with a return type of some kind before it gets to to crashing line.  So it is not exiting, but continuing on to:

type_name = cp_comp_to_string (demangled, 10);

This is obviously failing as the next call has type_name as NULL.   This call is the same as before the commit, except now it is in the exception handling block which should have no effect on the outcome of that call.

But this does not help us solve the problem in your case as I cannot reproduce the error on Linux.  If you feel up to it, you can step into cp_comp_to_string from your GDB in GDB session and see what is going on.  I would especially be interested of the contents on demangled.  The resultant call in cp_comp_to_string is the libiberty function cp_demangle_print.  I doubt there is much interest there.  I am hoping the demangled contents will give us a clue.
Comment 7 Phil Muldoon 2011-11-01 11:25:51 UTC
Created attachment 6043 [details]
lookup type patch
Comment 8 Phil Muldoon 2011-11-01 11:27:32 UTC
My comments seem to have disappeared in the comment #7 attachment.  I found an error in my previous patch (which you point out) in that I return from a GDB exception handler.  This is wrong.  Can you please try that attached patch (#7) and indicate whether the issue still exists?
Comment 9 asmwarrior 2011-11-01 11:58:36 UTC
Ok, I will test your patch as soon as I can.
Comment 10 asmwarrior 2011-11-01 12:55:36 UTC
Hi, Phil Muldoon, I can confirm that your patch fix the issue. Thank you very much!!!!!!
Comment 11 Sourceware Commits 2011-11-04 11:57:08 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	pmuldoon@sourceware.org	2011-11-04 11:57:04

Modified files:
	gdb            : ChangeLog 
	gdb/python     : py-type.c 

Log message:
	2011-11-04  Phil Muldoon  <pmuldoon@redhat.com>
	
	PR Python/13363
	
	* python/py-type.c (typy_lookup_type): Do not return a type in
	an exception handler.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.13483&r2=1.13484
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/python/py-type.c.diff?cvsroot=src&r1=1.27&r2=1.28
Comment 12 Phil Muldoon 2011-11-04 12:08:54 UTC
Fixed and committed as show in comment #11.