Bug 25957 - Unable to call std::map::operator[] from gdb
Summary: Unable to call std::map::operator[] from gdb
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.3.1
: P2 normal
Target Milestone: 18.1
Assignee: Keith Seitz
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-05-09 11:32 UTC by Jan Engelhardt
Modified: 2026-05-12 18:31 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
Project(s) to access:
ssh public key:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Engelhardt 2020-05-09 11:32:26 UTC
# 7-liner test program
» g++ x.cpp -v -ggdb3 -O0 -fno-inline
gcc version 9.3.1 20200406 [revision 6db837a5288ee3ca5ec504fbd5a765817e556ac2] (SUSE Linux) 
...
» gdb a.out 
GNU gdb (GDB; openSUSE Tumbleweed) 8.3.1
(gdb) b main
Breakpoint 1 at 0x11dd: file x.cpp, line 5.
(gdb) r
Starting program: /dev/shm/a.out 

Breakpoint 1, main () at x.cpp:5
5               z[99] = 42;
(gdb) l
1       #include <map>
2       std::map<int, int> z;
3       int main()
4       {
5               z[99] = 42;
6               return 0;
7       }
(gdb) p z[99]
Attempt to take address of value not located in memory.
(gdb) p z.operator[](99)
Attempt to take address of value not located in memory.

Which value is not in memory? And why is it not in memory? What more does one need beside -O0 -ggdb3?
Comment 1 Hannes Domani 2020-05-12 13:07:17 UTC
The argument of operator[] is a reference:
_Key & operator[](const _Key &);

A simpler example is:

int const_ref_arg(const int &x)
{
  return x;
}
int ref_arg(int &x)
{
  return x;
}
int y;
int main()
{
  return const_ref_arg(y) + ref_arg(y);
}

I'm not really surprised that it can't handle literals, since it would have to create extra space on the stack, and pass its reference to the function:

(gdb) p const_ref_arg(0)
Attempt to take address of value not located in memory.

But I did think it would work with an existing variable:

(gdb) p const_ref_arg(y)
Attempt to take address of value not located in memory.

It works with the non-const variant:

(gdb) p ref_arg(y)
$1 = 0
Comment 2 Sourceware Commits 2026-03-17 18:10:46 UTC
The master branch has been updated by Keith Seitz <kseitz@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=883363daadfa6fc4f9221546f448bfa6a87dd447

commit 883363daadfa6fc4f9221546f448bfa6a87dd447
Author: Keith Seitz <keiths@redhat.com>
Date:   Thu Oct 16 08:29:05 2025 -0700

    infcall: Add support for integer literals as reference function parameters
    
    This patch attempts to mitigate the shortcomings of passing literals
    to inferior function calls requiring references.  The specific use case here
    is std::map's operator[]:
    
    std::map int_map<int, int>;
    int_map[1] = 10;
    (gdb) print int_map[1]
    Attempt to take address of value not located in memory.
    
    This is occurring because while value_coerce_to_target understands
    that some values need to be allocated and copied to the inferior's
    memory, it only considers the actual parsed type of the argument value,
    ignoring the actual type of the function parameter. That is,
    in this specific case, the value's parsed type is TYPE_CODE_INT, but
    the function requires TYPE_CODE_REF. We need to account for the
    reference.
    
    In value_arg_coerce, we have special handling for references, but it
    has not specifically dealt with this case. It now checks if the
    reference is in memory, and if it isn't, it copies it, if the type
    is trivially copyable.
    
    As a result of this patch, the last remaining failure in c++/15372 is now
    fixed, and that bug can be closed.
    
    With this patch, we can now print map entries with integer keys:
    
    (gdb) print int_map[1]
    $1 = (std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::mapped_type &) @0x41f2d4: 10
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=15372
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=25957
    Approved-By: Andrew Burgess <aburgess@redhat.com>
Comment 3 Keith Seitz 2026-03-31 18:18:31 UTC
I believe the basics of this now work.