How to retrieve memory content from a process core file? - linux

i want to analyse each memory block content produced by a particular process. So what i did was using "gcore pid" to get a core dump of the process, but i do not know how to retrieve the content out, can anyone help?

In general, the good tool to analyze a core dump is the gdb debugger.
So you should compile all your code with the -g flag passed to gcc or g++ or clang (to have DWARF debug information inside your ELF executable).
Then, you can analyze the (post-mortem or not) core dump of your program myprog with the command gdb myprog core. Learn how to use gdb. Notice that gdb is scriptable and extensible (in Python and Guile).
You could (but probably should not) analyze the core file otherwise (without gdb). Then you need to understand its detailed format (and that could require months of work). See elf(5) and core(5).
BTW, valgrind could also be useful.
You could even use gdb to analyze a core dump from a program compiled without -g but that is much less useful.

Related

CPU profiler on Google Performance Tool (gperftools) - Process with shared library with NO OUTPUT ISSUE

I had a process on a server. My process uses a shared lib, runing in the linux background. I use CPU profiler in gperftool to examine the functions. The steps is following:
1. in my app,
main ()
{
ProfilerStart("dump.txt");
...code..
ProfilerFlush();
ProfilerStop();
return 0;
}
2. CPUPROFILE_FREQUENCY=1000000 LD_LIBRARY_PATH=/usr/local/lib/libprofiler.so CPUPROFILE=dump.txt ./a.out
3. pprof --text a.out dump.txt
I checked my steps on the other process (not using shared lib), it's ok.
Problem: The dump.txt file is just remain an unchanged file size (8kb or 9kb), can not show the output despite of long time running in 2 or 3 hours (the app receive message from clients). I think that because my app uses the shared lib, some thing wrong here, totally not clear about this.
Can you pls explain me what happened? Any solution?
Thanks a lot,
Part LD_LIBRARY_PATH=/usr/local/lib/libprofiler.so is incorrect in your run.
According to documentation http://goog-perftools.sourceforge.net/doc/cpu_profiler.html
To install the CPU profiler into your executable, add -lprofiler to the link-time step for your executable. (It's also probably possible to add in the profiler at run-time using LD_PRELOAD, but this isn't necessarily recommended.)
you can either add libprofiler to linking step as -lprofiler of your application like
gcc -c myapp.c -o myapp.o
gcc myapp.o mystaticlib.a -Lmypath -lmydynamiclib -lprofiler -o myapp
or add it at with environment variable LD_PRELOAD (not LD_LIBARY_PATH as you did):
LD_PRELOAD=/usr/lib/libprofiler.so ./myapp
When cpu profiler of gperftools is correctly used, it will print information about event count and output file size when application terminates.

Profiling a preloaded shared library with LD_PROFILE

I'm currently trying to profile a preloaded shared library by using the LD_PROFILE environment variable.
I compile the library with "-g" flag and export LD_PROFILE_OUTPUT as well as LD_PROFILE before running an application (ncat in my case) with the preloaded library. So, more precisely what I do is the following:
Compile shared library libexample.so with "-g" flag.
export LD_PROFILE_OUTPUT=`pwd`
export LD_PROFILE=libexample.so
run LD_PRELOAD=`pwd`/libexample.so ncat ...
The preloading itself does work and my library is used, but no file libexample.so.profile gets created. If I use export LD_PROFILE=libc.so.6 instead, there is a file libc.so.6.profile as expected.
Is this a problem of combining LD_PRELOAD and LD_PROFILE or is there anything I might have done wrong?
I'm using glibc v2.12 on CentOS 6.4 if that is of any relevance.
Thanks a lot!
Sorry, I don't know the answer why LD_PROFILE does not work with LD_PRELOAD.
However, for profiling binaries compiled with -g I really like the tool valgrind together with the grapichal tool kcachegrind.
valgrind --tool=callgrind /path/to/some/binary with options
will create a file called something like callgrind.out.1234 where 1234 was the pid of the program when run. That file can be analyzed with:
kcachegrind callgrind.out.1234
In kcachegrind you will easily see in which functions most CPU time is spended, the callee map also shows this in a nise graphical way. The call graph might help to understand how the program works. You will even be able to look at the source code to see how much CPU time is spent on each line.
I hope that you will find valgrind useful even though this was not the answer to your LD_PROFILE question. The drawback of valgrind is that it slows things down both when valgrind is used for profiling and memory checking.

changing linux memory protection

Is there a way to check which memory protection machenizem is used by the OS?
I have a program that fails with segmentation fault, in one computer (ubuntu) but not in another (RH6).
One of the explanations was memory protection mechanizem used by the OS.
Is there a way I can find / change it?
Thanks,
You might want to learn more about virtual memory, system calls, the linux kernel, ASLR.
Then you could study the role and usage of mmap & munmap system calls (also mprotect). They are the syscalls used to retrieve memory (e.g. to implement malloc & free), sometimes with obsolete syscalls like sbrk (which is increasingly useless).
You should use the gdb debugger (its watch command may be handy), and the valgrind utility. strace could also be useful.
Look also inside the /proc pseudo file system. Try to understand what
cat /proc/self/maps
is telling you (about the process running that cat). Look also inside /proc/$(pidof your-program)/maps
consider also using the pmap utility.
If it is your own source code, always compile it with all warnings and debuggiing info, e.g. gcc -Wall -Wextra -g and improve it till the compiler don't give any warnings. Use a recent version of gcc (ie 4.7) and of gdb (i.e. 7.4).

Program runs with gdb but doesn't run with ./ProgramName

I am writing an editor in assembly 64bit mode in linux. It runs correctly when I debug the program in GDB but it does not run correctly when I run it normally it means it has runtime errors when I use ./programName .
You're probably accessing uninitialized data or have some kind of memory corruption problem. This would explain the program behaving differently when run in the debugger - you're seeing the results of undefined behavior.
Run your program through valgrind's memcheck tool and see what it outputs. Valgrind is a powerful tool that will identify many runtime errors on Linux, including a full stack trace to the error.
If GDB disabling ASLR is what makes it work, perhaps set disable-randomization off in GDB will let your reproduce a crash inside GDB so you can debug it. Force gdb to load shared library at randomized address.
Otherwise enable core dumps from your program, and use GDB on the core dump.
gdb ./prog core.1234.
On x86, you can insert a ud2 instruction in your asm source to intentionally cause a crash at whatever point you want in your code, if you want to get a coredump to examine registers/memory at some point before it crashes on its own. All architectures have an undefined instruction you can use, but I only know the mnemonic for x86's off the top of my head.

Address of instruction causing SIGSEGV in external program

I want to get address of instruction that causes external program to SIGSEGV. I tried using ptrace for this, but I'm getting EIP from kernel space (probably default signal handler?). How GDB is able to get the correct EIP?
Is there a way to make GDB provide this information using some API?
edit:
I don't have sources of the program, only binary executable. I need automation, so I can't simply use "run", "info registers" in GDB. I want to implement "info registers" in my own mini-debugger :)
You can attach to a process using ptrace. I found an article at Linux Gazette.
It looks like you will want PTRACE_GETREGS for the registers. You will want to look at some example code like strace to see how it manages signal handling and such. It looks to me from reading the documentation that the traced child will stop at every signal and the tracing parent must wait() for the signal from the child then command it to continue using PTRACE_CONT.
Compile your program with -g, run gdb <your_app>, type run and the error will occur. After that use info registers and look in the rip register.
You can use objectdump -D <your_app> to get some more information about the code at that position.
You can enable core dumps with ulimit -c unlimited before running your external program.
Then you can examine the core dump file after a crash using gdb /path/to/program corefile
Because it is binary and not compiled with debugging options you will have to view details at the register and machine code level.
Try making a core dump, then analyse it with gdb. If you meant you wanted to make gdb run all your commands at one touch of a key by 'automate', gdb ca do that too. Type your commands into a file and look into the help user-defined section of manuals, gdb can handle canned commands.

Resources