Compare storage of string in memory for c++ and golang using gdb

By | December 28, 2022

Probably everybody knows that c++ string is a sequence of characters terminated by 0. In golang string is stored in different way as a structure with 2 members: pointer to character sequence (type uintptr) and length of character sequence (type integer). Below there are 2 examples how to check and modify string in memory for c++ and golang code using gdb debugger.
Let us begin with c++ code:


#include <stdio.h>
int main()
{
   const char str[] = "1234567890";
   printf("%s\n", str);
   return 0;
}

Compiling with debugging flags:


# g++ -g -o str str.cpp

Launch str program under gdb debugger, set break point at line #5 (printf(“%s\n”, str);). When execution stops on breakpoint, examine str string in memory:


# gdb str

Reading symbols from str…done.
(gdb) break 5
Breakpoint 1 at 0x400610: file str.cpp, line 5.
(gdb) run
Starting program: str

Breakpoint 1, main () at str.cpp:5
5   printf(“%s\n”, str);
Missing separate debuginfos, use: debuginfo-install glibc-2.17-105.el7.x86_64
libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64
(gdb) print str
$1 = “1234567890”
(gdb) print &str
$2 = (const char (*)[11]) 0x7fffffffe310
(gdb) x/11cb 0x7fffffffe310
0x7fffffffe310: 49 ‘1’ 50 ‘2’ 51 ‘3’ 52 ‘4’ 53 ‘5’ 54 ‘6’ 55 ‘7’ 56 ‘8’
0x7fffffffe318: 57 ‘9’ 48 ‘0’ 0 ‘\000’
(gdb) c
Continuing.
1234567890
[Inferior 1 (process 2475) exited normally]

Now restart str program, when it stops at breakpoint replace the first symbol of str string from ‘1’ to ‘A’, now output of printf is “A234567890”:


(gdb) run
Starting program: str

Breakpoint 1, main () at str.cpp:5
5   printf(“%s\n”, str);
(gdb) set {char}0x7fffffffe310=65
(gdb) print str
$3 = “A234567890”
(gdb) c
Continuing.
A234567890
[Inferior 1 (process 3705) exited normally]

Repeat the same with golang. The golang source code:


package main

import (
   "fmt"
)

func main() {
   str := "AaBbCcDdEe"
   fmt.Println(str)
}

Compiling without optimization:


# go build -gcflags '-N -l' strgo.go

Launch strgo program under gdb debugger, set break point at line #9 (fmt.Println(str)). When execution stops on breakpoint, examine str string in memory:


Thread 1 “strgo” hit Breakpoint 1, main.main ()
 at /home/alex/golang/strgo/strgo.go:9
9   fmt.Println(str)
(gdb) print str
$5 = 0x4bd917 “AaBbCcDdEe”
(gdb) print &str
$6 = (string *) 0xc000120f40
(gdb) x/2xg 0xc000120f40
0xc000120f40:  0x00000000004bd917  0x000000000000000a

0x00000000004bd917 is pointer to “AaBbCcDdEe”, 0x000000000000000a number of characters.


(gdb) x/10cb 0x4bd917
0x4bd917: 65 ‘A’ 97 ‘a’ 66 ‘B’ 98 ‘b’ 67 ‘C’ 99 ‘c’ 68 ‘D’ 100 ‘d’
0x4bd91f: 69 ‘E’ 101 ‘e’
(gdb) c
Continuing.
AaBbCcDdEe
[LWP 1935 exited]
[LWP 1934 exited]
[LWP 1933 exited]
[LWP 1931 exited]
[LWP 1930 exited]
[Inferior 1 (process 1930) exited normally]

Now restart strgo program, when it stops at breakpoint replace the first symbol of str string from ‘A’ to ‘1’, now output of printf is “1aBbCcDdEe”:


Thread 1 “strgo” hit Breakpoint 1, main.main ()
 at /home/alex/golang/strgo/strgo.go:9
9   fmt.Println(str)
(gdb) set {char}0x4bd917=49
(gdb) print str
$7 = 0x4bd917 “1aBbCcDdEe”
(gdb) c
Continuing.
1aBbCcDdEe
[LWP 1949 exited]
[LWP 1948 exited]
[LWP 1947 exited]
[LWP 1946 exited]
[LWP 1945 exited]
[Inferior 1 (process 1944) exited normally]

Leave a Reply

Your email address will not be published. Required fields are marked *