Bug 25234 - Python pretty printer for C++ type fails when printing backtrace from a C function
Summary: Python pretty printer for C++ type fails when printing backtrace from a C fun...
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: python (show other bugs)
Version: 8.3
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 12421 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-11-29 12:26 UTC by Jonathan Wakely
Modified: 2022-06-05 14:38 UTC (History)
4 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2019-11-29 12:26:50 UTC
tmp$ cat cpp.cc
#include <unordered_map>
extern "C" void print(int);

void foo(std::unordered_map<int, int> &map) {
  auto it = map.begin();
  print(it->first);
}

int main() {
  std::unordered_map<int, int> map;
  map[42] = 1;
  foo(map);
  return 0;
}
tmp$ cat c.c
#include <stdio.h>
void print(int i) {
  printf("%d\n", i);
}
tmp$ g++ -g cpp.cc -x c c.c 
tmp$ gdb -q -ex 'br print' -ex r -ex bt a.out
Reading symbols from a.out...
Breakpoint 1 at 0x402b89: file c.c, line 3.
Starting program: /tmp/a.out 

Breakpoint 1, print (i=42) at c.c:3
3         printf("%d\n", i);
#0  print (i=42) at c.c:3
#1  0x00000000004011f7 in foo (Python Exception <class 'IndexError'> list index out of range: 
map=std::unordered_map with 1 element) at cpp.cc:6
#2  0x000000000040123b in main () at cpp.cc:12
(gdb) up
#1  0x00000000004011f7 in foo (map=std::unordered_map with 1 element = {...}) at cpp.cc:6
6         print(it->first);
(gdb) bt
#0  print (i=42) at c.c:3
#1  0x00000000004011f7 in foo (map=std::unordered_map with 1 element = {...}) at cpp.cc:6
#2  0x000000000040123b in main () at cpp.cc:12
(gdb) down
#0  print (i=42) at c.c:3
3         printf("%d\n", i);
(gdb) bt
#0  print (i=42) at c.c:3
#1  0x00000000004011f7 in foo (Python Exception <class 'IndexError'> list index out of range: 
map=std::unordered_map with 1 element) at cpp.cc:6
#2  0x000000000040123b in main () at cpp.cc:12
(gdb) 

The error comes from the C++ pretty printer for parameter to the the foo(std::unordered_map<int, int>&) function, which uses gdb.Type.fields() to look at a base class:

        field = typ.fields()[0]

The printer keeps walking up the inheritance hierarchy until there are no more base classes, which should never happen (in practice the function should return before reaching the ultimate base class). It happens because an earlier call to gdb.lookup_type(...) failed, but should have succeeded.

It seems that gdb.lookup_type is context-sensitive. Within the C++ frame it finds the type, but within the C frame it doesn't.

When printing a C++ frame as part of the 'bt' output, lookup for C++ types should work the same way as it does within that C++ frame.
Comment 1 Jonathan Wakely 2019-11-29 12:30:14 UTC
I see this with any version of GCC and these two versions of GDB:

GNU gdb (GDB) Fedora 8.3-7.fc30
GNU gdb (GDB) Fedora 8.3.50.20190824-24.fc31

I'm adding a workaround to the libstdc++ printers, but it shouldn't be needed really.
Comment 2 Jonathan Wakely 2022-02-03 13:11:07 UTC
This seems to be fixed in GDB 10.1 (I can't test anything older).

I compiled the example with GCC 9.1 (which doesn't have the workaround in the libstdc++ printers) and don't get the IndexError exception now.
Comment 3 Tom Tromey 2022-06-05 14:38:12 UTC
(In reply to Jonathan Wakely from comment #2)
> This seems to be fixed in GDB 10.1 (I can't test anything older).
> 
> I compiled the example with GCC 9.1 (which doesn't have the workaround in
> the libstdc++ printers) and don't get the IndexError exception now.

I thought there was a patch to temporarily change the current
language when printing a frame (assuming the language was "auto"
initially), but I can't easily find it now.

Anyway I am going to close this bug.
Comment 4 Tom Tromey 2022-06-05 14:38:34 UTC
*** Bug 12421 has been marked as a duplicate of this bug. ***