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 |
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 |
Repeat the same with golang. The golang source code:
package main import ( func main() { |
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] |