I'm running into a weird bus error when trying to create an object in C++. This is my gdb backtrace when the program crashes:
#0 0xff146ff4 in _malloc_unlocked () from /usr/lib/libc.so.1
#1 0xff146e40 in malloc () from /usr/lib/libc.so.1
#2 0x24430 in __builtin_new (sz=128) at /usr/local/src/gcc-2.95.1/gcc/cp/new1.cc:84
#3 0x1e71c in FileHeader::Allocate (this=0x3f5d8, freeMap=0x3eea0, fileSize=5719)
at ../filesys/filehdr.cc:63
#4 0x1f61c in FileSystem::Create (this=0x3d8b8, name=0xffbff8f3 "test", initialSize=5719)
at ../filesys/filesys.cc:200
#5 0x1ffac in Copy (from=0xffbff8e4 "assignment 2.c", to=0xffbff8f3 "test")
at ../filesys/fstest.cc:52
#6 0x15150 in main (argc=3, argv=0xffbff768) at ../threads/main.cc:116
The relevant line of code from filehdr.cc is:
IndirectHeader * s;
s = new IndirectHeader;
It crashes on the second line. I thought it might be that I wasn't explicitly using my own constructor, but adding one didn't seem to help. It seems to me like there's some other simple problem i'm not noticing but i haven't been able to find it.. Any advice would be appreciated.
What you're seeing in the backtrace is a crash allocating the memory to back your IndirectHeader. It hasn't even started constructing the object yet because it's still trying to allocate memory for it. Most likely there is a bug earlier in your program, that has corrupted the heap.
Related
I'm attempting to wrap a small library I've written in c, and I think I'm on the home stretch to getting it working. The library has some pretty solid tests around it, and I've ran it through valgrind to remove any memory leaks and glaring issues. It works pretty solid on it's own.
However, when I attempt to wrap it using ruby it segfaults. Here's an example project that wraps the library. When the tests in that project are ran, the call to the library segfaults. Running it results in a core abort which I've loaded in gdb to debug, but I'm not sure what's wrong. The core dump says the issue is on this line, but I have no idea what's causing it since the information given is pretty sparse and the code runs well if I run the tests in c land.
The line that the core dump says is segfaulting:
assert( yypParser->yytos!=0 );
You can reproduce it by running rake from the root directory which kicks of a process that ultimately generates a shared object that is loaded by the tests. I'm hoping someone with more experience in c can take a look and potentially point me in the right direction.
Please let me know if any more information is needed.
Snippet from the core dump:
#0 0x00007f150caa2c37 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007f150caa6028 in __GI_abort () at abort.c:89
#2 0x00007f150dba8d8d in die () at error.c:407
#3 rb_bug_context (ctx=ctx#entry=0x7f150f3b1b80, fmt=fmt#entry=0x7f150dbe2f6a "Segmentation fault at %p") at error.c:437
#4 0x00007f150daa45ce in sigsegv (sig=<optimized out>, info=0x7f150f3b1cb0, ctx=0x7f150f3b1b80) at signal.c:890
#5 <signal handler called>
#6 0x00007f150b96b02b in Parse (yyp=0xf9925e0, yymajor=20, yyminor=..., state=0x7ffe17b6a3a0) at parser.c:1919
#7 0x00007f150b96b8e8 in numerize (data=data#entry=0x7f150b96c1aa "one", state=state#entry=0x7ffe17b6a3a0) at ../../../../ext/example_project/fast_numerizer/fast_numerizer.c:102
#8 0x00007f150b960e0b in example_project_c_code_function () at ../../../../ext/example_project/./example_project.c:11
I have the following fragment of code, that accumulates BSON documents from a query cursor, to be processed afterwards:
// Accumulate
std::vector<BSONObj> results;
while (cursor->more()) {
BSONObj r = cursor->nextSafe();
results.push_back(r);
}
...
// Process it (example)
for (unsigned int ix = 0; ix < results.size(); ix++) {
BSONElement be = results[ix].getField("_id");
// Do somtething with 'be'
...
}
This code has worked well from a time (months) but we have recently found that with large documents in DB (around 1.1MB) the results[ix].getField("_id") statement crashes with segfault. This is the top of backtrace:
(gdb) bt
#0 readNative<int> (offset=0, t=<synthetic pointer>, this=<optimized out>) at src/mongo/base/data_view.h:46
#1 readNative<int> (offset=0, this=<optimized out>) at src/mongo/base/data_view.h:53
#2 readLE<int> (offset=0, this=<optimized out>) at src/mongo/base/data_view.h:59
#3 objsize (this=0x7f74340022e0) at src/mongo/bson/bsonobj.h:309
#4 BSONObjIterator (jso=..., this=<synthetic pointer>) at src/mongo/bson/bsonobjiterator.h:42
#5 mongo::BSONObj::getField (this=0x7f74340022e0, name=...) at src/mongo/bson/bsonobj.cpp:635
...
I have solved the problem using results.push_back(r.copy()) instead of results.push_back(r). Thus, probably the error was caused when the r object is destroyed at the end of the while block scope, leaving the copy pushed back in the vector in an unstable state. Pushing back a copy of r without hitting the block scope as a new variable seems to solve the problem.
So, I have the following questions:
What is the best way of storing BSONObj got from a query result in a std::vector? I think I have found a reasonable solution, but not sure if this is the best one.
Why the code using push_back(r) works with small documents? If the right way is to use r.copy() to avoid problems destroying r at the end of while block scope, I understand it should fail always, not only in the case of objects of around 1.1MB.
I'm using MongoDB C++ driver legacy-1.0.7 (in the case it may help or the problem could be related with specific versions of MongoDB C++ driver).
The BSONObj objects returned by nextSafe do not own their data, and are invalidated by subsequent calls to nextSafe.
So, your vector becomes populated with invalid BSONObj objects.
Instead, call BSONObj::getOwned() on the cursor result before pushing back in the vector.
If you run your program under AddressSanitizer or valgrind, you will almost certainly see use-after-free type errors.
I have the following code:
std::ofstream stat("/opt/lic_status");
if ( stat.is_open() )
{
stat << ver;
stat.close();
}
My problem is that on the first line the execution is blocked. A coredump was generated by a watchdog during this block and it looks like this:
(gdb) bt
#0 0x00cb5430 in __kernel_vsyscall ()
#1 0x00b2833b in open () from /lib/libc.so.6
#2 0x00ac37c8 in _IO_new_file_fopen () from /lib/libc.so.6
#3 0x00ab73dd in __fopen_internal () from /lib/libc.so.6
#4 0x00ab9c4c in fopen64 () from /lib/libc.so.6
#5 0x00d6e877 in std::__basic_file<char>::open(char const*, std::_Ios_Openmode, int) () from /usr/lib/libstdc++.so.6
#6 0x00d1d75e in std::basic_filebuf<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode) () from /usr/lib/libstdc++.so.6
#7 0x08b625b8 in open () at /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include /c++/4.4.4/fstream:699
#8 basic_ofstream () at /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/fstream:628
I need to mention that I don't know what was the state of the /opt/lic_status file when the problem occurred. I don't know if it was opened by other process or even if it existed at all.
Does anoyone have any suggestion on what could have caused this?
I only have the coredump, can I get any info out of it?
"I need to mention that I don't know what was the state of the
/opt/lic_status file when the problem occurred. I don't know if it was opened by other process or even if it existed at all."
Based on my understanding none of the above attribute/state of the file can lead the program to block on that particular line(.i.e. where user mode program is calling open() inside the std::ofstream constructor). Whenever user mode program calls open() system call to open the files, system would complete the call with appropriate error code. It will not be the case that system(kernel mode) would not return back to user mode.
Does anyone have any suggestion on what could have caused this? I
only have the coredump, can I get any info out of it?
Entire system(kernel) is not in good state(due to some unknown reason).
The program is multi threaded and some other threads has been stuck somewhere. By looking the call stack of this thread it looks OK as it is executing in the kernel mode and calling open() system call.
If we are experiencing the first case, then I believe we can not do much and core-dump file of the program would not give any extra information to identify/confirm this. Core-dump file just contains the snapshot of that particular process.
However, if we are in second case, then we should try to analyze core-dump file further. We can fire following commands in GDB command prompt once core-dump file is loaded.
$info threads
$thread apply all backtrace
The above command would give the information (if your program is multi-threaded) as well call stack of all threads. This might be helpful to understand your problem. You can ignore the above information if you have already done it.
I'm working on an embedded platform (architecture is SH4), and my program crashed a few minutes ago with a SIGABRT.
Luckily, I was running under gdbserver, and the thread that was interrupted by this signal has this stack dump:
#0 0x2a7f1678 in raise () from /home/[user]/target/lib/libc.so.6
#1 0x2a7f2a4c in abort () from /home/[user]/target/lib/libc.so.6
#2 0x2a81ade0 in __libc_message () from /home/[user]/target/lib/libc.so.6
#3 0x2a81f3a8 in malloc_printerr () from /home/[user]/target/lib/libc.so.6
#4 0x2a8c3700 in _IO_wide_data_2 () from /home/[user]/target/lib/libc.so.6
Do you know what happened here? A bad free()? bad delete ? bad malloc?
What's "_IO_wide_data_2" supposed to do?
I see the malloc_printerr() call that I don't understand either.
Google gives me 234 results on this, but all of them are simply because the guys have that "function" in their backtrace.
It is a stream to stderr for wide character support.
You can break it down into various parts:
_IO : Input/Output.
wide_data : Wide data
2 : stderr
You also have;
_IO_wide_data_0 : stdin
_IO_wide_data_1 : stdout
They are chained as 2->1->0.
malloc_printerr() is used to print various error messages when there is something bad happening/caught in dynamic memory management. But your trace looks capped (have you removed anything?).
It could be a write to stderr where you try to write something not in memory, in corrupted memory, in …
Or it could be lower stack point causing write to stderr.
Or …
A bad free()? bad delete ? bad malloc?
Yes I think it's one of these.
If the bug is easy reproducible, put a breakpoint in malloc.c, malloc_printerr. When debugger stops there, You'll probably get full call stack and find the buggy place in Your code. I still don't know why it happens, that after entering __libc_message, the call stack gets broken.
There is how I found this strange behaviour.
Simple app that deletes the same buffer twice:
void main()
{
char * buf = new char[4*1024];
delete[] buf;
delete[] buf;
}
Inside malloc_printerr the call stack looks like this:
#0 malloc_printerr (action=3, str=0x297d0b5c "double free or corruption (top)", ptr=<value optimized out>) at malloc.c:5887
#1 0x29750be8 in __libc_free (mem=0x411008) at malloc.c:3622
#2 0x29612c70 in operator delete (ptr=<value optimized out>) at ../../../../libstdc++-v3/libsupc++/del_op.cc:49
#3 0x29612cc2 in operator delete[] (ptr=<value optimized out>) at ../../../../libstdc++-v3/libsupc++/del_opv.cc:37
#4 0x0040068a in main (argc=1, argv=0x7bb26814) at double_free.cpp:47
After entering __libc_message:
#0 __libc_message (do_abort=2, fmt=0x297d09c8 "*** glibc detected *** %s: %s: 0x%s *** ") at ../sysdeps/unix/sysv/linux/libc_fatal.c:50
#1 0x2974f3a8 in malloc_printerr (action=3, str=0x297d0b5c "double free or corruption (top)", ptr=<value optimized out>) at malloc.c:5887
#2 0x297f3700 in _IO_wide_data_2 () from /cygdrive/c/STM/SH4-Linux-gcc/opt/STM/STLinux2.3/devkit/sh4/target/lib/libc.so.6
Backtrace stopped: frame did not save the PC
Maybe it has something to do with attribute((noreturn)) and compiler optimization?
Can you reproduce this error while running under GDB? You might get more stack trace information using the various "Stack" commands found here:
GDB Cheat Sheet
You might need to move up or down a few stack frames to determine what happened.
We have a binary that generates coredump. So I ran the gdb command to analyze the issue. Please note the binary and code are in two different locations and we cannot build the whole binary using debugging symbols. Hence how and what details can I find from below backtarce:
gdb binary corefile
(gdb) where
#0 0x101fa37a in f1()
#1 0x10203812 in operator f2< ()
#2 0x085f6244 in f3 ()
#3 0x085f1574 in f4()
#4 0x0805b27b in sigsegv_handler ()
#5 <signal handler called>
#6 0x1018d945 in f5()
#7 0x1018e021 in f6()
..................................
#29 0x08055c5c in main ()
(gdb)
Please provide me gdb commands that I can issue to find what’s data inside each stack frame, what’s the issue probably is, where it is failing, other debugging methods if any?
You can use help in gdb. To navigate the stack : help stack
The main useful commands to navigate the stack are up and down. If you have debugging symbols at hand, you can use list to see where you are. Then to get information, you need print (abbreviated as 'p'). For example, if you have an int called myInt then you just type p myInt. With no debug info it will be harder. From your stack frame it seems that the problem is in f5(). One thing you can do is start your program inside gdb. it will stop right where the segfault happens. When you have hints about the part of your code that segfaults, you can compile this code unit with debugging options.
That the basics. Tell us more if you want more help.
my2c