Good day!
I have a core file, and I disassembled (using gdb) the method that
crashed and I was told that the the value assigned to r44 below
causes the crash.
I am not well verse with assembly so I would like to ask what does
0x480 offset mean and how to locate its value?/address? by using
the core file in gdb.
Is it safe to assume that 0x480 is located in the function
MovePage()?
;;; 1052 if( MovePage( len ) == FALSE ) {
0xc00000000c0c55c0:2 <TMF::PrintLog(char*)+0x32>: adds r44=0x480,r32;;
0xc00000000c0c55d0:0 <TMF::PrintLog(char*)+0x40>: ld8 r43=[ret2]
0xc00000000c0c55d0:1 <TMF::PrintLog(char*)+0x41>: (p6) st4 [r35]=ret3
Thanks in advance.
Assigning a value to r44 almost certainly does not cause a crash.
Please edit your question to supply output from GDB where, disas and info registers commands. Then we should be able to tell you precisely where it crashed (and possibly why).
Related
I have pretty large C++ code base of a shared library which is messed up with complicated conditional macro spaghetti so IDE has troubles with that. I examined it with GDB to find the initial value of a global variable as follows:
$ gdb libcomplex.so
(gdb) p some_global_var
$1 = 1024
So I figured out the value the variable was initialized with.
QUESTION: Is it possible to find out which source file (and maybe line number) it was initialized at with GDB?
I tried list some_global_var, but it simply prints nothing:
(gdb) list some_global_var
(gdb)
So on x86 you can put a limited number of hardware watchpoints on that variable being changed:
If you are lucky, on a global you can get away with
watch some_global_var
But the debugger may still decide that is not a fixed address, and do a software watchpoint.
So you need to get the address, and watch exactly that:
p &some_global_var
(int*)0x000123456789ABC
watch (int*)0x000123456789ABC
Now, when you restart, the debugger should pop out when the value is first initialised, perhaps to zero, and/or when it is initialised to the unexpected value. If you are lucky, listing the associated source code will tell you how it came to be initialised. As others have stated you may then need to deduce why that line of code generated that value, which can be a pain with complex macros.
If that doesn't help you, or it stops many times unexpectedly during startup, then you should initially disable the watchpoint, then starti to restart you program and stop as soon as possible. Then p your global, and if it does not yet have the magic value, enable the watchpoint and continue. Hopefully this will skip the irrelevant startup and zoom in on the problem value.
You could use rr (https://rr-project.org/) to record a trace of the program, then you could reverse-execute to find the location. E.g.:
rr replay
(gdb) continue
...
(gdb) watch -l some_global_var
(gdb) reverse-continue
I am a gdb novice, and I was trying to debug some GSSAPI code, and was using fin to see the return value from the frame. As seen in the snip pasted below, the call from gssint_mechglue_initialize_library() seems to be 0 but the actual check seems to fail. Can someone please point out if I am missing something obvious here?
Thanks in advance!
One possible explanation for the observed behavior is that you are debugging optimized code, and that line 1001 isn't really executed.
You can confirm this with a few nexts, or by executing fin again and observing whether GSS_S_COMPLETE or something else is returned from gssint_select_mech_type.
When optimization is on, code motion performed by the optimizer often prevents correct assignment of actual code sequences to line numbers (as instructions "belonging" to different lines are mixed and re-ordered). This often causes the code to "jump around" when e.g. doing nexti command.
For ease of debugging, recompile with -O0, or make sure to remove any -O2 and the like from your compile lines.
It works when, in the loop, I set every element to 0 or to entry_count-1.
It works when I set it up so that entry_count is small, and I write it by hand instead of by loop (sorted_order[0] = 0; sorted_order[1] = 1; ... etc).
Please do not tell me what to do to fix my code. I will not be using smart pointers or vectors for very specific reasons. Instead focus on the question:
What sort of conditions can cause this segfault?
Thank you.
---- OLD -----
I am trying to debug code that isn't working on a unix machine. The gist of the code is:
int *sorted_array = (int*)memory;
// I know that this block is large enough
// It is allocated by malloc earlier
for (int i = 0; i < entry_count; ++i){
sorted_array[i] = i;
}
There appears to be a segfault somewhere in the loop. Switching to debug mode, unfortunately, makes the segfault stop. Using cout debugging I found that it must be in the loop.
Next I wanted to know how far into the loop the segfault happend so I added:
std::cout << i << '\n';
It showed the entire range it was suppose to be looping over and there was no segfault.
With a little more experimentation I eventually created a string stream before the loop and write an empty string into it for each iteration of the loop and there is no segfault.
I tried some other assorted operations trying to figure out what is going on. I tried setting a variable j = i; and stuff like that, but I haven't found anything that works.
Running valgrind the only information I got on the segfault was that it was a "General Protection Fault" and something about default response to 11. It also mentions that there's a Conditional jump or move depends on uninitialized value(s), but looking at the code I can't figure out how that's possible.
What can this be? I am out of ideas to explore.
This is clearly a symptoms of invalid memory uses within your program.This would be bit difficult to find by looking out your code snippet as it is most likely be the side effect of something else bad which has already happened.
However as you have mentioned in your question that you are able to attach your program using Valgrind. as it is reproducible. So you may want to attach your program(a.out).
$ valgrind --tool=memcheck --db-attach=yes ./a.out
This way Valgrind would attach your program in the debugger when your first memory error is detected so that you can do live debugging(GDB). This should be the best possible way to understand and resolve your problem.
Once you are able to figure it out your first error, fix it and rerun it and see what are other errors you are getting.This steps should be done till no error is getting reported by Valgrind.
However you should avoid using the raw pointers in modern C++ programs and start using std::vector std::unique_ptr as suggested by others as well.
Valgrind and GDB are very useful.
The most previous one that I used was GDB- I like it because it showed me the exact line number that the Segmentation Fault was on.
Here are some resources that can guide you on using GDB:
GDB Tutorial 1
GDB Tutorial 2
If you still cannot figure out how to use GDB with these tutorials, there are tons on Google! Just search debugging Segmentation Faults with GDB!
Good luck :)
That is hard, I used valgrind tools to debug seg-faults and it usually pointed to violations.
Likely your problem is freed memory that you are writing to i.e. sorted_array gets out of scope or gets freed.
Adding more code hides this problem as data allocation shifts around.
After a few days of experimentation, I figured out what was really going on.
For some reason the machine segfaults on unaligned access. That is, the integers I was writing were not being written to memory boundaries that were multiples of four bytes. Before the loop I computed the offset and shifted the array up that much:
int offset = (4 - (uintptr_t)(memory) % 4) % 4;
memory += offset;
After doing this everything behaved as expected again.
For my university project I need to WRITE protect the whole address space of the process. I was reading the /proc/self/maps file and parsing the mapping.
So for each entry of the format 08048000-0804c000 r-xp 00000000 08:03 7971106 /bin/cat, I am reading the first two entry(here 08048000 & 0804c000), converting them to decimal. Lets assume the decimal equivalent is A & B respectively. Then I do mprotect((int*)A, B-A, PROT_READ). But this approach is giving me segmentation fault. I can't find out what I did wrong here. May be I've some knowledge gap here which is causing the problem. Someone can give me some suggestions?
Assuming that your implementation is correct, I'd still expect to see segmentation faults.
After all, you're telling the kernel that you don't want to be allowed to write to any part of your memory. Afterwards, you'll just continue to run your process and the next time you try to write anything at all you'll get a segmentation fault because that's no longer allowed.
That'll most likely be when you return from mprotect() after "protecting" the stack.
Thinking a bit more, it's even possible that you're getting segmentation faults while executing memory (i.e. a shared lib, or your executable code) after you've "protected" it.
In fact, all of the bits of memory where it's safe to apply read-only / do-not-execute flags already have those flags set.
I suspect that's the insight this univerity project was meant to give you.
I'm compiling a program on remote linux server. The program compiled. However when I run it the program ends abruptly. So I debugged the program using DDT. It spits out the following error:
Process 0:
Memory error detected in ClassName::function (filename.cpp:6462).
Thread 1 attempted to dereference a null pointer or execute an SSE instruction with an
incorrectly aligned memory address (the latter may sometimes occur spuriously if guard
pages are enabled)
Tip: Use the stack list and the local variables to explore your program's current
state and identify the source of the error.
Can anyone please tell me what exactly this error means?
The line where the program stops looks like this:
SumUtility = ParaEst[0] + hhincome * ParaEst[71] + IsBlack * ParaEst[61] + IsBachAss * (ParaEst[55]);
This is within a switch case.
These are the variable types
vector<double> ParaEst;
double hhincome;
int IsBlack, Is BachAss;
Thanks for the help!
It means that:
ParaEst is NULL or a bad Pointer
ParaEst's individual array values are not aligned to 16-byte boundaries, required for SSE.
hhincome, IsBlack, or IsBachAss are not aligned to 16-byte boundaries and are SSE type values.
SumUtility is not aligned to 16-bytes and is a SSE type field.
If you could post the assembly code of the exact line that failed along with the register values of that assembler line, we could tell you exactly which of the above conditions have failed. It would also help to see the types of each variable shown to help narrow root the cause.
Ok... The problem finally got fixed.
The issue was that the expression where the code was breaking down was in a newly defined function. However for some weird reason running the make-file did not incorporate these changes and was still compiling using the previously compiled .o file. This resulted in garbage values being assigned to the variables within this new function. To top things off the program calls this function as a first step. Hence there was this systematic breakdown. The technical aspect of this was what Michael alluded to.
After this I would always recommend to use a make clean option in the make file. The issue of why running the make file is failing to compile the modified source file is an issue that definitely warrants further discussion.
Thanks for the responses!!