Now we are at ret instruction and jump to esp
which is when x/10i $esp it's look like this
0xffffd12a: nop
0xffffd12b: nop
0xffffd12c: nop
0xffffd12d: nop
0xffffd12e: nop
0xffffd12f: nop
0xffffd130: nop
0xffffd131: nop
0xffffd132: nop
0xffffd133: nop
and when type si it single step and get segmentation fault
Cannot access memory at address 0x90909090
here is the picture
Also I also use checksec of pwntools at it and it give this result
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
Have no idea now bruh
I also compile as `
gcc chall.c -m32 -fno-stack-protector -no-pie -z execstack -o dicrypto_rev_web
as it has -fno-stack-protector and -z execstack. and also stack has perm rwxp as I check with info proc map
It should working
I want to put Shellcode after that but It seem doesn't work at nop sled.
what I should do?
Related
Background
I've built qemu-system-x86_64.exe on a Windows machine using MSYS2 (x86_64), and I'm debugging a segmentation fault that happens when I try to run it.
Actually I don't think the problem is related to either QEMU or MSYS2, it's a problem of debugging segmentation fault and possibly wrong code generation.
Debugging the Segmentation Fault
The program crashes with segmentation fault error right at the beginning.
When running with gdb, I found out the following:
Starting program: C:\msys64\home\Administrator\qemu\x86_64-softmmu\qemu-system-x86_64.exe
[New Thread 4656.0x1194]
Program received signal SIGSEGV, Segmentation fault.
0x00000000007d3254 in getpagesize () at util/oslib-win32.c:535
535 {
(gdb) bt
#0 0x00000000007d3254 in getpagesize () at util/oslib-win32.c:535
#1 0x000000000086dd39 in init_real_host_page_size () at util/pagesize.c:16
#2 0x00000000007ea1b2 in __do_global_ctors ()
at C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:67
#3 0x00000000007ea20f in __main ()
at C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:83
#4 0x000000000040137f in __tmainCRTStartup ()
at C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:329
#5 0x00000000004014db in WinMainCRTStartup ()
at C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:195
This is strange.
The program crashes when running __do_global_ctors and calling init_real_host_page_size() which calls getpagesize(). These are really simple functions:
uintptr_t qemu_real_host_page_size;
intptr_t qemu_real_host_page_mask;
static void __attribute__((constructor)) init_real_host_page_size(void)
{
qemu_real_host_page_size = getpagesize();
qemu_real_host_page_mask = -(intptr_t)qemu_real_host_page_size;
}
...
int getpagesize(void)
{
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return system_info.dwPageSize;
}
getpagesize() crashes right at the beginning of the function, before it even calls GetSystemInfo.
Here is the disassembly of that code fragment and register values:
(gdb) disassem
Dump of assembler code for function getpagesize:
0x00000000007d3250 <+0>: sub $0x68,%rsp
=> 0x00000000007d3254 <+4>: mov %fs:0x0,%rax
0x00000000007d325d <+13>: mov %rax,0x58(%rsp)
0x00000000007d3262 <+18>: xor %eax,%eax
0x00000000007d3264 <+20>: lea 0x20(%rsp),%rcx
0x00000000007d3269 <+25>: callq *0x68e8b9(%rip) # 0xe61b28 <__imp_GetSystemInfo>
0x00000000007d326f <+31>: mov 0x24(%rsp),%eax
0x00000000007d3273 <+35>: mov 0x58(%rsp),%rdx
0x00000000007d3278 <+40>: xor %fs:0x0,%rdx
0x00000000007d3281 <+49>: jne 0x7d3288 <getpagesize+56>
0x00000000007d3283 <+51>: add $0x68,%rsp
0x00000000007d3287 <+55>: retq
0x00000000007d3288 <+56>: callq 0x85bde0 <__stack_chk_fail>
0x00000000007d328d <+61>: nop
End of assembler dump.
(gdb) info registers
rax 0x6f4b868 116701288
rbx 0x86ec10 8842256
rcx 0x6f4b8b8 116701368
rdx 0xe5a780 15050624
rsi 0x86e220 8839712
rdi 0x6f4ad50 116698448
rbp 0x6f4ad10 0x6f4ad10
rsp 0x22fd80 0x22fd80
r8 0x0 0
r9 0x0 0
r10 0x5000016b 1342177643
r11 0x22f9d8 2292184
r12 0x0 0
r13 0x10 16
r14 0x0 0
r15 0x0 0
rip 0x7d3254 0x7d3254 <getpagesize+4>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x53 83
gs 0x2b 43
It looks like something is wrong with the memory access mov %fs:0x0,%rax.
Who sets FS to 83?
(gdb) starti
Starting program: C:\msys64\home\Administrator\qemu\x86_64-softmmu\qemu-system-x86_64.exe
[New Thread 3508.0x14b0]
Program stopped.
0x00000000778b6fb1 in ntdll!CsrSetPriorityClass ()
from C:\Windows\SYSTEM32\ntdll.dll
(gdb) p $fs
$1 = 83
(gdb) watch $fs
Watchpoint 1: $fs
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x00000000007d3254 in getpagesize () at util/oslib-win32.c:535
535 {
No one sets FS!
Questions
GCC generated code that uses uninitialized register. What could cause that? Was there some initialization code that should have run but didn't?
Any ideas how can I further debug this issue?
FS is an x86 segment register. These are generally not set by the user program, but instead set by the OS or by the runtime libraries, for various special purposes. For instance on Windows x86-64 GS is used to point to a per-thread data block: https://en.wikipedia.org/wiki/Win32_Thread_Information_Block (and FS is not used).
In this case the problem is a bug in the GCC 8 compiler you are using: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86832
In some situations this compiler generates code that assumes FS has been set up for "native TLS", which is wrong because MINGW does not support "native TLS" and FS is not set to anything useful.
The workaround is to avoid compiling with the -fstack-protector-strong compiler option. For QEMU you can do that by passing configure the flag --disable-stack-protector.
(PS: if you want to know how I identified the cause of this segfault: I googled for 'qemu-devel sigsegv getpagesize', which brings up a mailing list thread where somebody else ran into and reported the bug, the problem was diagnosed and a link to the GCC bug found.)
This question already has an answer here:
Testing Shellcode From C - Bus Error 10
(1 answer)
Closed 6 years ago.
If I just execute shell code program It makes segmentation fault like this
desktop:~$ ./sh02
Segmentaion fault (core dumped)
But, when I debug this program with GDB, this program executes /bin/sh successfully
(gdb) disass 0x4005a0
No function contains specified address.
(gdb) shell ps
PID TTY TIME CMD
4075 pts/4 00:00:00 bash
4099 pts/4 00:00:00 gdb
4101 pts/4 00:00:00 sh
4107 pts/4 00:00:00 ps
(gdb)
After debugging with GDB, this program works well ...
I can't find difference between them
Why I can't run /bin/sh via sh02 program before debugging?
const char str[]=
"\x55"
"\x48\x89\xe5"
"\x48\x31\xff"
"\x57"
"\x57"
"\x5e"
"\x5a"
"\x48\xbf\x2f\x2f\x62\x69\x6e"
"\x2f\x73\x68"
"\x57"
"\x54"
"\x5f"
"\x6a\x3b"
"\x58"
"\x0f\x05"
"\x90"
"\x5d"
"\xc3";
int main()
{
int (*func)();
func = (int (*)()) str;
(int)(*func)();
}
Above is sh02.c code.
I read that questions and answers. But I think my case is little bit different. During debugging with GDB and after debugging sh02 program execute /bin/sh successfully. However only before debugging, it makes segmentation fault
I use Ubuntu 16.04 and x64 architecture
When undefined behavior is invoked the program may crash or not crash (by luck). The program does not null terminate the string sent to exec, the results are undefined.
Try this:
"\x48\xbf\x2f\x62\x69\x6e"
"\x2f\x73\x68\x00"
Note that I dropped the extra '/' and added the '\0' at the end of the string.
I was able to determine the issue by using gdb.
Here is the session perhaps this will help you to learn assembly debugging.
parallels#ubuntu:/tmp$ gcc -g -fno-stack-protector -z execstack -o shellcode shellcode2.c
parallels#ubuntu:/tmp$ gdb ./shellcode
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ./shellcode...done.
(gdb) b main
Breakpoint 1 at 0x4004f5: file shellcode2.c, line 25.
(gdb) r
Starting program: /tmp/shellcode
Breakpoint 1, main () at shellcode2.c:25
25 func = (int (*)()) str;
(gdb) n
27 (int)(*func)();
(gdb) stepi
0x0000000000400501 27 (int)(*func)();
(gdb) stepi
0x0000000000400506 27 (int)(*func)();
(gdb) stepi
0x00000000004005c0 in str ()
(gdb) disass
Dump of assembler code for function str:
=> 0x00000000004005c0 <+0>: push %rbp
0x00000000004005c1 <+1>: mov %rsp,%rbp
0x00000000004005c4 <+4>: xor %rdi,%rdi
0x00000000004005c7 <+7>: push %rdi
0x00000000004005c8 <+8>: push %rdi
0x00000000004005c9 <+9>: pop %rsi
0x00000000004005ca <+10>: pop %rdx
0x00000000004005cb <+11>: movabs $0x68732f6e69622f2f,%rdi
0x00000000004005d5 <+21>: push %rdi
0x00000000004005d6 <+22>: push %rsp
0x00000000004005d7 <+23>: pop %rdi
0x00000000004005d8 <+24>: pushq $0x3b
0x00000000004005da <+26>: pop %rax
0x00000000004005db <+27>: syscall
0x00000000004005dd <+29>: nop
0x00000000004005de <+30>: pop %rbp
0x00000000004005df <+31>: retq
0x00000000004005e0 <+32>: add %al,(%rax)
End of assembler dump.
(gdb) b *0x4005db
Breakpoint 2 at 0x4005db
(gdb) c
Continuing.
Breakpoint 2, 0x00000000004005db in str ()
(gdb) info reg
rax 0x3b 59
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x7fffffffdef8 140737488346872
rbp 0x7fffffffdf00 0x7fffffffdf00
rsp 0x7fffffffdef8 0x7fffffffdef8
r8 0x7ffff7dd4e80 140737351863936
r9 0x7ffff7dea560 140737351951712
r10 0x7fffffffddb0 140737488346544
r11 0x7ffff7a36dd0 140737348070864
r12 0x400400 4195328
r13 0x7fffffffe000 140737488347136
r14 0x0 0
r15 0x0 0
rip 0x4005db 0x4005db <str+27>
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) p (char*) $rdi
$1 = 0x7fffffffdef8 "//bin/sh \337\377\377\377\177"
As you can see the string has an extra '/' and no NULL terminator. A simple two character fix and all is well.
This my program:
void test_function(int a, int b, int c, int d){
int flag;
char buffer[10];
flag = 31337;
buffer[0] = 'A';
}
int main() {
test_function(1, 2, 3, 4);
}
I compile this program with the debug option:
gcc -g my_program.c
I use gdb and I disassemble the test_function with intel syntax:
(gdb) disassemble test_function
Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret
End of assembler dump.
And I disassemble the main:
(gdb) disassemble main
Dump of assembler code for function main:
0x08048357 <main+0>: push ebp
0x08048358 <main+1>: mov ebp,esp
0x0804835a <main+3>: sub esp,0x18
0x0804835d <main+6>: and esp,0xfffffff0
0x08048360 <main+9>: mov eax,0x0
0x08048365 <main+14>: sub esp,eax
0x08048367 <main+16>: mov DWORD PTR [esp+12],0x4
0x0804836f <main+24>: mov DWORD PTR [esp+8],0x3
0x08048377 <main+32>: mov DWORD PTR [esp+4],0x2
0x0804837f <main+40>: mov DWORD PTR [esp],0x1
0x08048386 <main+47>: call 0x8048344 <test_function>
0x0804838b <main+52>: leave
0x0804838c <main+53>: ret
End of assembler dump.
I place a breakpoint at this adresse: 0x08048355 (leave instruction for the test_function) and I run the program.
I watch the stack like this:
(gdb) x/16w $esp
0xbffff7d0: 0x00000041 0x08049548 0xbffff7e8 0x08048249
0xbffff7e0: 0xb7f9f729 0xb7fd6ff4 0xbffff818 0x00007a69
0xbffff7f0: 0xb7fd6ff4 0xbffff8ac 0xbffff818 0x0804838b
0xbffff800: 0x00000001 0x00000002 0x00000003 0x00000004
0x0804838b is the return adress, 0xbffff818 is the saved frame pointer (main ebp) and flag variable is stocked 12 bytes further. Why 12?
I don't understand this instruction:
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
Why we don't stock the content's variable 0x00007a69 in ebp-4 instead of 0xbffff8ac?
Same question for buffer. Why 40?
We don't waste the memory? 0xb7fd6ff4 0xbffff8ac and 0xb7f9f729 0xb7fd6ff4 0xbffff818 0x08049548 0xbffff7e8 0x08048249 are not used?
This the output for the command gcc -Q -v -g my_program.c:
Reading specs from /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/specs
Configured with: ../src/configure -v --enable-languages=c,c++ --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --enable-__cxa_atexit --with-system-zlib --enable-nls --without-included-gettext --enable-clocale=gnu --enable-debug i486-linux-gnu
Thread model: posix
gcc version 3.3.6 (Ubuntu 1:3.3.6-15ubuntu1)
/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/cc1 -v -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=6 notesearch.c -dumpbase notesearch.c -auxbase notesearch -g -version -o /tmp/ccGT0kTf.s
GNU C version 3.3.6 (Ubuntu 1:3.3.6-15ubuntu1) (i486-linux-gnu)
compiled by GNU C version 3.3.6 (Ubuntu 1:3.3.6-15ubuntu1).
GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129473
options passed: -v -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=6
-auxbase -g
options enabled: -fpeephole -ffunction-cse -fkeep-static-consts
-fpcc-struct-return -fgcse-lm -fgcse-sm -fsched-interblock -fsched-spec
-fbranch-count-reg -fcommon -fgnu-linker -fargument-alias
-fzero-initialized-in-bss -fident -fmath-errno -ftrapping-math -m80387
-mhard-float -mno-soft-float -mieee-fp -mfp-ret-in-387
-maccumulate-outgoing-args -mcpu=pentiumpro -march=i486
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/i486-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/include
/usr/include
End of search list.
gnu_dev_major gnu_dev_minor gnu_dev_makedev stat lstat fstat mknod fatal ec_malloc dump main print_notes find_user_note search_note
Execution times (seconds)
preprocessing : 0.00 ( 0%) usr 0.01 (25%) sys 0.00 ( 0%) wall
lexical analysis : 0.00 ( 0%) usr 0.01 (25%) sys 0.00 ( 0%) wall
parser : 0.02 (100%) usr 0.01 (25%) sys 0.00 ( 0%) wall
TOTAL : 0.02 0.04 0.00
as -V -Qy -o /tmp/ccugTYeu.o /tmp/ccGT0kTf.s
GNU assembler version 2.17.50 (i486-linux-gnu) using BFD version 2.17.50 20070103 Ubuntu
/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../../crt1.o /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../../crti.o /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/crtbegin.o -L/usr/lib/gcc-lib/i486-linux-gnu/3.3.6 -L/usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../.. /tmp/ccugTYeu.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/crtend.o /usr/lib/gcc-lib/i486-linux-gnu/3.3.6/../../../crtn.o
NOTE: I read the book "The art of exploitation" and I use the VM provides with the book.
The compiler is trying to maintain 16 byte alignment on the stack. This also applies to 32-bit code these days (not just 64-bit). The idea is that at the point before executing a CALL instruction the stack must be aligned to a 16-byte boundary.
Because you compiled with no optimizations there are some extraneous instructions.
0x0804835a <main+3>: sub esp,0x18 ; Allocate local stack space
0x0804835d <main+6>: and esp,0xfffffff0 ; Ensure `main` has a 16 byte aligned stack
0x08048360 <main+9>: mov eax,0x0 ; Extraneous, not needed
0x08048365 <main+14>: sub esp,eax ; Extraneous, not needed
ESP is now 16-byte aligned after the last instruction above. We move the parameters for the call starting at the top of the stack at ESP. That is done with:
0x08048367 <main+16>: mov DWORD PTR [esp+12],0x4
0x0804836f <main+24>: mov DWORD PTR [esp+8],0x3
0x08048377 <main+32>: mov DWORD PTR [esp+4],0x2
0x0804837f <main+40>: mov DWORD PTR [esp],0x1
The CALL then pushes a 4 byte return address on the stack. We then reach these instructions after the call:
0x08048344 <test_function+0>: push ebp ; 4 bytes pushed on stack
0x08048345 <test_function+1>: mov ebp,esp ; Setup stackframe
This pushes another 4 bytes on the stack. With the 4 bytes from the return address we are now misaligned by 8 bytes. To reach 16-byte alignment again we will need to waste an additional 8 bytes on the stack. That is why in this statement there is an additional 8 bytes allocated:
0x08048347 <test_function+3>: sub esp,0x28
0x08 bytes already on stack because of return address(4-bytes) and EBP(4 bytes)
0x08 bytes of padding needed to align stack back to 16-byte alignment
0x20 bytes needed for local variable allocation = 32 bytes.
32/16 is evenly divisible by 16 so alignment maintained
The second and third number above added together is the value 0x28 computed by the compiler and used in sub esp,0x28.
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
So why [ebp-12] in this instruction? The first 8 bytes [ebp-8] through [ebp-1] are the alignment bytes used to get the stack 16-byte aligned. The local data will then appear on the stack after that. In this case [ebp-12] through [ebp-9] are the 4 bytes for the 32-bit integer flag.
Then we have this for updating buffer[0] with the character 'A':
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
The oddity then would be why a 10 byte array of characters would appear from [ebp+40](beginning of array) to [ebp+13] which is 28 bytes. The best guess I can make is that compiler felt that it could treat the 10 byte character array as a 128-bit (16-byte) vector. This would force the compiler to align the buffer on a 16 byte boundary, and pad the array out to 16 bytes (128-bits). From the perspective of the compiler, your code seems to be acting much like it was defined as:
#include <xmmintrin.h>
void test_function(int a, int b, int c, int d){
int flag;
union {
char buffer[10];
__m128 m128buffer; ; 16-byte variable that needs to be 16-bytes aligned
} bufu;
flag = 31337;
bufu.buffer[0] = 'A';
}
The output on GodBolt for GCC 4.9.0 generating 32-bit code with SSE2 enabled appears as follows:
test_function:
push ebp #
mov ebp, esp #,
sub esp, 40 #,same as: sub esp,0x28
mov DWORD PTR [ebp-12], 31337 # flag,
mov BYTE PTR [ebp-40], 65 # bufu.buffer,
leave
ret
This looks very similar to your disassembly in GDB.
If you compiled with optimizations (such as -O1, -O2, -O3), the optimizer could have simplified test_function because it is a leaf function in your example. A leaf function is one that doesn't call another function. Certain shortcuts could have been applied by the compiler.
As for why the character array seems to be aligned to a 16-byte boundary and padded to be 16 bytes? That probably can't be answered with certainty until we know what GCC compiler you are using (gcc --version will tell you). It would also be useful to know your OS and OS version. Even better would be to add the output from this command to your question gcc -Q -v -g my_program.c
Unless you're trying to improve gcc's code itself, understanding why un-optimized code is as bad as it is will mostly be a waste of time. Look at output from -O3 if you want to see what a compiler does with your code, or from -Og if you want to see a more literal translation of your source into asm. Write functions that take input in args and produce output in globals or return values, so the optimized asm isn't just ret.
You shouldn't expect anything efficient from gcc -O0. It makes the most braindead literal translation of your source.
I can't reproduce that asm output with any gcc or clang version on http://gcc.godbolt.org/. (gcc 4.4.7 to gcc 5.3.0, clang 3.0 to clang 3.7.1). (Note that godbolt use g++, but you can use -x c to treat the input as C, instead of compiling it as C++. This can sometimes change the asm output, even when you don't use any features C99 / C11 has but C++ doesn't. (e.g. C99 variable-length arrays).
Some versions of gcc default to emitting extra code unless I use -fno-stack-protector.
I thought at first that the extra space reserved by test_function was to copy its args down into its stack frame, but at least modern gcc doesn't do this. (64bit gcc does store its args into memory when they arrive in registers, but that's different. 32bit gcc will increment an arg in place on the stack, without copying it.)
The ABI does allow the called function to clobber its args on the stack, so a caller that wanted to make repeated function calls with the same args would have to keep storing them between calls.
clang 3.7.1 with -O0 does copy its args down into locals, but that still only reserves 32 (0x20) bytes.
This is about the best answer you're going to get unless you tell us which version of gcc you're using...
While I'm debugging a segmentation fault in x86-Linux, I've ran into this problem:
Here goes the seg-fault message from the GDB
0xe2a5a99f in my_function (pSt=pSt#entry=0xe1d09000, version=43)
Here goes the faulting assembly:
0xe2a5a994 <my_function> push %ebp
0xe2a5a995 <my_function+1> push %edi
0xe2a5a996 <my_function+2> push %esi
0xe2a5a997 <my_function+3> push %ebx
0xe2a5a998 <my_function+4> lea -0x100b0c(%esp),%esp
0xe2a5a99f <my_function+11> call 0xe29966cb <__x86.get_pc_thunk.bx>
0xe2a5a9a4 <my_function+16> add $0x9542c,%ebx
As you can see above, the faulting line is "call get_pc_thunk" which is just getting the pc value.
And, I checked the memory at 0xe29966cb is valid and accessible with the following command:
(gdb) x/10i 0xe29966cb
0xe29966cb <__x86.get_pc_thunk.bx>: nop
0xe29966cc <__x86.get_pc_thunk.bx+1>: nop
0xe29966cd <__x86.get_pc_thunk.bx+2>: nop
0xe29966ce <__x86.get_pc_thunk.bx+3>: nop
0xe29966cf <__x86.get_pc_thunk.bx+4>: nop
0xe29966d0 <__x86.get_pc_thunk.bx+5>: nop
0xe29966d1 <__x86.get_pc_thunk.bx+6>: nop
0xe29966d2 <__x86.get_pc_thunk.bx+7>: nop
0xe29966d3 <__x86.get_pc_thunk.bx+8>: mov (%esp),%ebx
0xe29966d6 <__x86.get_pc_thunk.bx+11>: ret
Which looks perfectly fine.
But Strangely, if I use "si" to step into the "get_pc_thunk" function, it seg-faults without even entering the first nop.
Any help would be appreciated.
A crash on CALL (or PUSH, of MOV (%esp)) instruction almost always is due to stack overflow.
Check your program for infinite (or just very deep) recursion.
Also, this:
0xe2a5a998 <my_function+4> lea -0x100b0c(%esp),%esp
means that my_function is allocating slightly over 1MB of local variables for the current stack frame. And now you know why that may not be a good idea.
I'm debugging an application write in ansi C, a multiple threads program.
Sometime, in the main thread cause a SIGSEGV fault.
(gdb) backtrace full
#0 0x0000000000000000 in ?? ()
No symbol table info available.
#1 0x0000000000000000 in ?? ()
No symbol table info available.
(gdb) info registers
rax 0x1 1
rbx 0x0 0
rcx 0x0 0
rdx 0x2 2
rsi 0x458e7aa0 1166965408
rdi 0x0 0
rbp 0x0 0x0
rsp 0x458e7b60 0x458e7b60
r8 0x458e7b20 1166965536
r9 0x0 0
r10 0x0 0
r11 0x206 518
r12 0x2aaaac400e70 46912522686064
r13 0x2aaaac514090 46912523813008
r14 0x1 1
r15 0x18505f10 407920400
rip 0x0 0
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x63 99
gs 0x0 0
fctrl 0x37f 895
fstat 0x0 0
ftag 0xffff 65535
fiseg 0x0 0
fioff 0x0 0
foseg 0x0 0
fooff 0x0 0
fop 0x0 0
mxcsr 0x1f80 [ IM DM ZM OM UM PM ]
(gdb)
This information is from core file, I'm not very family with debug in Linux environment, Is there anything I can do to find where's the problem?
Edit: all of source files are compiled with flag as follow
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/redisconnector.d" -MT"src/redisconnector.d" -o"src/redisconnector.o" "../src/redisconnector.c"
Your RIP points to 0. It's probably caused by a stack overflow. Your RBP is also 0, so the backtrace gdb command will tell you nothing.
Recompile the application with "-g" option;
Use Gdb not with core files, but to run entire application:
gdb --args ./application application_options
then "run" command of gdb.
Running from gdb will detect SIGSEGV, and gdb will be focused on failed thread.
Well, first you'll need to compile with debugging enabled so that your backtrace has something usable. The flag is gcc -g