Segfault taking element from QList - c++

I get a SEGFAULT at the first line in the if-block, takeFirst().
if (!sendQueue.isEmpty()) {
QString nxtcmd = sendQueue.takeFirst();
port->write(nxtcmd.toLatin1());
port->flush();
}
I have code pushing 96 command strings into the queue with
if (completionHandlerQueue.empty()) {
…
} else {
sendQueue.append(cmd_str);
}
The latter happens in my main GUI code. The first bit is called by a signal by QExtSerialPort (when data is there to be read).
sendQueue is a member and declared as such:
class SB::ModuleCommunicator : public QObject
{
…
private:
…
QStringList sendQueue;
Now I'm not using threads and I assumed the Qt Event Loop would make everything work smoothly, but the full backtrace does tell me that there are in fact 3 threads.
According to documentation, Qt Containers are only thread-safe for read only access.
But the Queue is already full with all 96 strings when it crashes. So I don't think anything is appending while the list is being modified.
Is this a thread issue? How can I find out?
Here is the stacktrace:
0 _int_malloc malloc.c 3530 0x7ffff61c7410
1 __GI___libc_malloc malloc.c 2924 0x7ffff61c9f95
2 QListData::detach(int) /usr/lib/x86_64-linux-gnu/libQtCore.so.4 0 0x7ffff6cd397b
3 QList<QString>::detach_helper qlist.h 709 0x412169
4 QList<QString>::detach_helper qlist.h 725 0x411cf2
5 QList<QString>::detach qlist.h 139 0x411e72
6 QList<QString>::begin qlist.h 267 0x423610
7 QList<QString>::first qlist.h 282 0x422dda
8 QList<QString>::takeFirst qlist.h 490 0x422885
9 SB::ModuleCommunicator::handleMsg ModuleCommunicator.cpp 116 0x41f9be
10 SB::ModuleCommunicator::onReadyRead ModuleCommunicator.cpp 393 0x421f4d
11 SB::ModuleCommunicator::qt_static_metacall moc_ModuleCommunicator.cpp 52 0x435e1e
12 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) /usr/lib/x86_64-linux-gnu/libQtCore.so.4 0 0x7ffff6dc9281
13 QextSerialPortPrivate::_q_canRead qextserialport.cpp 313 0x40c505
14 QextSerialPort::qt_static_metacall moc_qextserialport.cpp 97 0x40dbfa
15 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) /usr/lib/x86_64-linux-gnu/libQtCore.so.4 0 0x7ffff6dc9281
16 QSocketNotifier::activated(int) /usr/lib/x86_64-linux-gnu/libQtCore.so.4 0 0x7ffff6e162fe
17 QSocketNotifier::event(QEvent*) /usr/lib/x86_64-linux-gnu/libQtCore.so.4 0 0x7ffff6dd260b
18 QApplicationPrivate::notify_helper(QObject*, QEvent*) /usr/lib/x86_64-linux-gnu/libQtGui.so.4 0 0x7ffff72d7894
19 QApplication::notify(QObject*, QEvent*) /usr/lib/x86_64-linux-gnu/libQtGui.so.4 0 0x7ffff72dc713
20 QCoreApplication::notifyInternal(QObject*, QEvent*) /usr/lib/x86_64-linux-gnu/libQtCore.so.4 0 0x7ffff6db4e9c
... <More>
UDPATE:
So it seems I have a transient error here. Now it crashed at
for (int i = 0; i < msgBuffer->size(); i++) {
with msgBuffer being yet another QStringList member of my Class. This piece of code is in the 'onReadyRead()' Slot that gets called when QExtSerialPort has data for me.
So I think the error is related to that package.
I'm using Qt 4.8 on Ubuntu 12.04 with QExtSerialPort v1.2rc from https://code.google.com/p/qextserialport

Related

Qt Creator applications crashes on MacOS 12.4 [M1/Silicon]

I was able to compile and run my application on this Mac with the specified setup. From one day to another I couldn't execute the application (even in Debug mode). The error occurs without any actual signing besides the things that are happening in the default debug/release build.
What I've tried to solve this issue:
Made clean builds, even re-cloned the repository
Restarted the MacBook (as specified in the official MacOS docs according to this signing error)
Reinstalled QtCreator
Run system updates (e.g. for the console tools)
I ran out of ideas what to do next. Any input is appreciated. In the following there is the MacOS crash report:
Process: Sample [6739]
Path: /Users/USER/*/Sample.app/Contents/MacOS/Sample
Identifier: com.yourcompany.Sample
Version: ???
Code Type: ARM-64 (Native)
Parent Process: qtcreator_processlauncher [6187]
User ID: 501
Date/Time: 2022-06-10 09:56:06.0533 +0200
OS Version: macOS 12.4 (21F79)
Report Version: 12
Anonymous UUID: 3C17814C-6324-03D6-2715-B4F55ACF44E5
Sleep/Wake UUID: 74437E44-7126-4975-8C2B-014AB410B1BE
Time Awake Since Boot: 35000 seconds
Time Since Wake: 6363 seconds
System Integrity Protection: enabled
Crashed Thread: 0
Exception Type: EXC_BAD_ACCESS (SIGKILL (Code Signature Invalid))
Exception Codes: UNKNOWN_0x32 at 0x0000000100db0000
Exception Codes: 0x0000000000000032, 0x0000000100db0000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace CODESIGNING, Code 2
VM Region Info: 0x100db0000 is in 0x100db0000-0x100dd0000; bytes after start: 0 bytes before end: 131071
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
mapped file 100d74000-100db0000 [ 240K] r--/rwx SM=COW ...t_id=e753674d
---> mapped file 100db0000-100dd0000 [ 128K] r-x/rwx SM=COW ...t_id=e753674d
VM_ALLOCATE (reserved) 100dd0000-100dec000 [ 112K] rw-/rwx SM=NUL ...(unallocated)
Thread 0 Crashed:
0 dyld 0x100fa8008 dyld3::MachOFile::isMachO(Diagnostics&, unsigned long long) const + 20
1 dyld 0x100f892cc dyld4::Loader::mapSegments(Diagnostics&, dyld4::RuntimeState&, char const*, unsigned long long, dyld4::Loader::CodeSignatureInFile const&, bool, dyld3::Array<dyld4::Loader::Region> const&, bool, bool, dyld4::Loader::FileValidationInfo const&) + 1096
2 dyld 0x100f892cc dyld4::Loader::mapSegments(Diagnostics&, dyld4::RuntimeState&, char const*, unsigned long long, dyld4::Loader::CodeSignatureInFile const&, bool, dyld3::Array<dyld4::Loader::Region> const&, bool, bool, dyld4::Loader::FileValidationInfo const&) + 1096
3 dyld 0x100f8eb88 invocation function for block in dyld4::JustInTimeLoader::makeJustInTimeLoaderDisk(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, bool, unsigned int) + 68
4 dyld 0x100f8e528 dyld4::JustInTimeLoader::withRegions(dyld3::MachOAnalyzer const*, void (dyld3::Array<dyld4::Loader::Region> const&) block_pointer) + 292
5 dyld 0x100f8eadc invocation function for block in dyld4::JustInTimeLoader::makeJustInTimeLoaderDisk(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, bool, unsigned int) + 480
6 dyld 0x100f93d58 dyld4::SyscallDelegate::withReadOnlyMappedFile(Diagnostics&, char const*, bool, void (void const*, unsigned long, bool, dyld4::FileID const&, char const*) block_pointer) const + 132
7 dyld 0x100f8e8c8 dyld4::JustInTimeLoader::makeJustInTimeLoaderDisk(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, bool, unsigned int) + 204
8 dyld 0x100f886d0 invocation function for block in dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&) + 1384
9 dyld 0x100f87bc0 dyld4::Loader::forEachResolvedAtPathVar(dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, dyld4::ProcessConfig::PathOverrides::Type, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) + 780
10 dyld 0x100f877ec invocation function for block in dyld4::Loader::forEachPath(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) + 148
11 dyld 0x100f7db18 dyld4::ProcessConfig::PathOverrides::forEachImageSuffix(char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const + 176
12 dyld 0x100f7e34c invocation function for block in dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const + 160
13 dyld 0x100f7d0f0 dyld4::ProcessConfig::PathOverrides::forEachInColonList(char const*, char const*, void (char const*, bool&) block_pointer) + 204
14 dyld 0x100f7dd9c dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const + 344
15 dyld 0x100f87740 dyld4::Loader::forEachPath(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) + 172
16 dyld 0x100f87f60 dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&) + 864
17 dyld 0x100f8cb60 invocation function for block in dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&) + 380
18 dyld 0x100fa9264 invocation function for block in dyld3::MachOFile::forEachDependentDylib(void (char const*, bool, bool, bool, unsigned int, unsigned int, bool&) block_pointer) const + 148
19 dyld 0x100f75f98 dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const + 168
20 dyld 0x100fa90ac dyld3::MachOFile::forEachDependentDylib(void (char const*, bool, bool, bool, unsigned int, unsigned int, bool&) block_pointer) const + 172
21 dyld 0x100f8c8c8 dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&) + 164
22 dyld 0x100f795c0 dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 1092
23 dyld 0x100f7906c start + 488
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000100db0000 x1: 0x000000016f6edcd8 x2: 0x0000000000020000 x3: 0x0000000000040012
x4: 0x0000000000000003 x5: 0x0000000000000000 x6: 0x0000000000000000 x7: 0x0000000000000000
x8: 0x0000000100fec62c x9: 0x0000000100fedea8 x10: 0x000000001e000000 x11: 0x0800000000028000
x12: 0x0000000000000001 x13: 0x0000000000000001 x14: 0x0000000000011b00 x15: 0x0000000000000000
x16: 0x00000000000000c5 x17: 0x6ae100016f6ed4b8 x18: 0x0000000000000000 x19: 0x000000016f6edcd8
x20: 0x0000000100c70060 x21: 0x000000000003c000 x22: 0x0000000000000003 x23: 0x000000016f6ed7c8
x24: 0x0000000000000040 x25: 0x0000000000000000 x26: 0x000000016f6ed54c x27: 0x0000000000000000
x28: 0x0000000100db0000 fp: 0x000000016f6ed110 lr: 0x7a6f800100f892cc
sp: 0x000000016f6ed100 pc: 0x0000000100fa8008 cpsr: 0x00001000
far: 0x0000000100db0000 esr: 0x92000007 (Data Abort) byte read Translation fault
Binary Images:
0x100f74000 - 0x100fd3fff dyld (*) <d9c2a46e-8dc4-3950-9d6a-f799e8ccb683> /usr/lib/dyld
0x0 - 0xffffffffffffffff ??? (*) <00000000-0000-0000-0000-000000000000> ???
External Modification Summary:
Calls made by other processes targeting this process:
task_for_pid: 0
thread_create: 0
thread_set_state: 0
Calls made by this process:
task_for_pid: 0
thread_create: 0
thread_set_state: 0
Calls made by all processes on this machine:
task_for_pid: 0
thread_create: 0
thread_set_state: 0
VM Region Summary:
ReadOnly portion of Libraries: Total=6048K resident=0K(0%) swapped_out_or_unallocated=6048K(100%)
Writable regions: Total=9360K written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=9360K(100%)
This is the $ codesign output:
Format=app bundle with Mach-O thin (arm64)
CodeDirectory v=20400 size=43712 flags=0x20002(adhoc,linker-signed) hashes=1363+0 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha256=250886c9e93ae2aa977a592f451a52885ecd1701
CandidateCDHashFull sha256=250886c9e93ae2aa977a592f451a52885ecd17015c94bbeafa49d2cbb2274ed3
Hash choices=sha256
CMSDigest=250886c9e93ae2aa977a592f451a52885ecd17015c94bbeafa49d2cbb2274ed3
CMSDigestType=2
CDHash=250886c9e93ae2aa977a592f451a52885ecd1701
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements=none

Understanding a gdb backtrace

I get a gdb backtrace shown below consistently. Would this indicate a failure in doing malloc( ) ? If so, I also let a "free -m" run on the Linux box and I can't seem to find a discrepancy. xsd__anyType is a typedef of soap_dom_element
(gdb) bt
#0 0x0000007f9af24090 in raise () from /tmp/../lib/libc.so.6
#1 0x0000007f9af12894 in abort () from /tmp/../lib/libc.so.6
#2 0x0000007f9af5c950 in ?? () from /tmp/../lib/libc.so.6
#3 0x0000007f9af62d64 in ?? () from /tmp/../lib/libc.so.6
#4 0x0000007f9af66158 in ?? () from /tmp/../lib/libc.so.6
#5 0x0000007f9af67550 in malloc () from /tmp/../lib/libc.so.6
#6 0x0000007f9b8b909c in soap_malloc () from /opt/ad/lib/libjci_gsoap.so
#7 0x0000007f9b8d4d40 in ?? () from /opt/ad/lib/libjci_gsoap.so
#8 0x0000007f9b8d5834 in soap_in_xsd__anyType(soap*, char const*, soap_dom_element*, char const*) () from /opt/ad/lib/libjci_gsoap.so
#9 0x0000007f9b8d5874 in soap_in_xsd__anyType(soap*, char const*, soap_dom_element*, char const*) () from /opt/ad/lib/libjci_gsoap.so
#10 0x0000007f9b8d5874 in soap_in_xsd__anyType(soap*, char const*, soap_dom_element*, char const*) () from /opt/ad/lib/libjci_gsoap.so
#11 0x0000007f9b8d5874 in soap_in_xsd__anyType(soap*, char const*, soap_dom_element*, char const*) () from /opt/ad/lib/libjci_gsoap.so
#12 0x0000007f9b8d6fe4 in operator>>(std::istream&, soap_dom_element&) () from /opt/ad/lib/libjci_gsoap.so
#13 0x0000000000507274 in tev::Events::getSubscriptionReference[abi:cxx11](char const*) const (this=this#entry=0x7f99eb25b0,
msgBuf=0x7f99ec0218 "POST /onvif/event_service HTTP/1.0\r\nContent-Type: application/soap+xml; charset=utf-8\r\nHost: 192.168.184.35\r\nContent-Length: 1438\r\nAccept-Encoding: gzip, deflate\r\nX-Forwarded-For: ::ffff:192.168.185.1"...) at /home/jbloomrp/sandboxes/acvs-illustra-global/toolchain/arm/linaro-aarch64-2018.08-gcc8.2/work/amb_cv22_evk/arm/release/linaro-aarch64-2018.08-gcc8.2/aarch64-linux-gnu/include/c++/8.2.1/bits/unique_ptr.h:342
If malloc is a failure, then I should see it spiral towards 0 which doesn't seem to be the case.
Swap: 0 0 0
total used free shared buff/cache available
Mem: 1983 995 703 147 285 826
Swap: 0 0 0
total used free shared buff/cache available
Mem: 1983 1038 659 147 285 782
Swap: 0 0 0
Even at the lowest I could see free mem was still 659.

Skip innermost frames in backtrace

I would like to create a backtrace in gdb (in a script). The command bt 2 prints only the 2 innermost frames, while bt -2 prints only the 2 outermost frames.
What I'd like to do is to skip the 2 innermost frames, and show all outer frames. I've tried
up 2
bt
(and similarly up-silently, frame, select-frame), but it doesn't affect the output of bt. To be clear, I want to get rid of the first to lines in this output:
#0 0x0000003167e0f33e in waitpid () from /lib64/libpthread.so.0
#1 0x00007f2779835de8 in print_trace() () at /path/to/MyAnalysis.cxx:385
#2 0x00007f2779836ec9 in MyAnalysis::getHistHolder(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) () at /path/to/MyAnalysis.cxx:409
#3 0x00007f27798374aa in MyAnalysis::execute() () at /path/to/MyAnalysis.cxx:599
#4 0x00007f2783a9670f in EL::Worker::algsExecute() () from /blah/lib/libEventLoop.so
...
Any way to do this?
Calling return twice seems to work, but then the application is left in an invalid state afterwards, so I can't use it.
Your argument to "bt" depends on current number of frames present. Probably this can also be done in gdb directly (not sure), but this python script does exactly this:
import gdb
class TopBt (gdb.Command):
""" tbt n Shows backtrace for top n frames """
def __init__ (self):
super(TopBt, self).__init__ ("tbt", gdb.COMMAND_DATA)
def framecount():
n = 0
f = gdb.newest_frame()
while f:
n = n + 1
f = f.older()
return n
def invoke (self, arg, from_tty):
top = int(arg[0])
btarg = -(TopBt.framecount() - top)
if btarg < 0:
gdb.execute("bt " + str(btarg))
TopBt()
Save this to some file (tbt.py), source it in gdb (source tbt.py). Now you have new command tbt. tbt N will print backtrace for all but top N frames.
If it's ok for the stack to be capped at some pre-determined length, you can provide an explicit long list, like this for up to 40 frames starting at frame 4:
frame apply level 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 43 -q frame
Frame numbers beyond what's available appear to be ignored.

Application crashes while appending data on string

I have a cross platform console application. The purpose of it is to transfer data between two peers. Sometimes packets received are not complete so we append the data into a string while the complete packet has been arrived. But it get crashed in appending data in string after sometime. Here is the back tarce -
1 libsystem_c.dylib 0x93b77acf pthread_kill + 101
2 libsystem_c.dylib 0x93bae4f8 abort + 168
3 libc++abi.dylib 0x9698180c abort_message + 151
4 libc++abi.dylib 0x9697f275 default_terminate() + 34
5 libc++abi.dylib 0x9697f2b5 safe_handler_caller(void (*)()) + 13
6 libc++abi.dylib 0x9697f31d std::terminate() + 23
7 libc++abi.dylib 0x96980412 __cxa_throw + 110
8 libstdc++.6.dylib 0x90e23d6c std::__throw_length_error(char const*) + 104
9 libstdc++.6.dylib 0x90e4f3a9 std::string::append(char const*, unsigned long) + 175
10 libConnector.dylib 0x13905228 ConnectionSocket::AdjustPartialData(char const*, int)
14 libConnector.dylib 0x1383e0b6 ConnectionChannel::ProcessData(int, void const*, int, char*, int) + 7886
15 libConnector.dylib 0x13861ecb ConnectionManager::BaseThreadImpl() + 1185
16 libConnector.dylib 0x13861a23 ConnectionManager::BaseThread(void*) + 17
17 libsystem_c.dylib 0x93b76557 _pthread_start + 344
18 libsystem_c.dylib 0x93b60cee thread_start + 34
Can someone give any idea about this issue?
EXAMPLE CODE:
AdjustPartialData(char* const pData, int dataLen)
{
if (true == packetIncomplete)
{
partialDataBuffer.append(pData, dataLen); // crash occurs in this line
}
}
if partialDataBuffer.size() + dataLen > partialDataBuffer.max_size() then append throws a length_error (http://en.cppreference.com/w/cpp/string/basic_string/append)
Either partialDataBuffer or dataLen are too big.
Finally I have resolved the issue by discarding the extra data which causes the overflow. Previously I thought this will not be feasible solution as it could lead to possible data loss. But I found that TCP stream size shouldn't be greater than 65535 which is 16 bit. But found another issue when the following condition added -
if(partialDataBuffer.size() + dataLen >= partialDataBuffer.max_size())
{
// do not append data
}
else partialDataBuffer.append(pData, dataLen);
The issue was in windows platform it always crashes even though size of partialDataBuffer is much less than partialDataBuffer.max_size(). So, for resolving this issue I have done the following -
try{
partialDataBuffer.append(pData, dataLen);
}
catch(...)
{
// got exception, return
}
And it worked fine for me.
N.B: I have posted my answer because it will be helpful for others who are facing similar issue.

Mysterious write violation on my variable

I have an library that don't give correct output. I guess it is possibly an write violation, and focused it on this section of code:
void Page::build_default_frame(PosType genome_display_length)
{
Frame* frame = new Frame(*this,
margin_left,
margin_top,
width - margin_left - margin_right,
genome_display_length);
default_frame = frame;
frames.insert(default_frame);
}
The default_frame is a boost intrusive_ptr<Frame>.
Before execute the sentence default_frame = frame, the content of object frame was all right, but after that, its contents were modified to weird value. So I set two watches on two member variables of frame object:
(gdb) watch -l frame->genome_scale.genome_display_length
Hardware watchpoint 4: -location frame->genome_scale.genome_display_length
(gdb) watch -l frame->genome_scale.frame_width
Hardware watchpoint 5: -location frame->genome_scale.frame_width
and then continue. It suddenly reports write operation on these address:
(gdb) c
Continuing.
Hardware watchpoint 4: -location frame->genome_scale.genome_display_length
Old value = 1000
New value = 16
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:39
39 ../sysdeps/x86_64/dl-trampoline.S: No such file or directory.
(gdb) bt
#0 _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:39
#1 0x00007ffff7b93dd0 in geno_eye::Page::build_default_frame (this=0x6071b0, genome_display_length=1000)
at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:127
#2 0x00007ffff7b93cc1 in geno_eye::Page::Page (this=0x6071b0, context=0x607750, width=300, height=300,
genome_display_length=1000) at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:29
#3 0x00000000004016b8 in geno_eye::__tester__::run (this=0x7fffffffe1c8)
at /home/yangxi/projects/GenoEye/t/t_page.cpp:15
#4 0x00000000004015d1 in main () at /home/yangxi/projects/GenoEye/t/t_page.cpp:36
(gdb) c
Continuing.
Hardware watchpoint 5: -location frame->genome_scale.frame_width
Old value = 240
New value = 3.1228427039313504e-317
_dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:40
40 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) bt
#0 _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:40
#1 0x00007ffff7b93dd0 in geno_eye::Page::build_default_frame (this=0x6071b0, genome_display_length=1000)
at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:127
#2 0x00007ffff7b93cc1 in geno_eye::Page::Page (this=0x6071b0, context=0x607750, width=300, height=300,
genome_display_length=1000) at /home/yangxi/projects/GenoEye/src/geno_eye/Page.cpp:29
#3 0x00000000004016b8 in geno_eye::__tester__::run (this=0x7fffffffe1c8)
at /home/yangxi/projects/GenoEye/t/t_page.cpp:15
#4 0x00000000004015d1 in main () at /home/yangxi/projects/GenoEye/t/t_page.cpp:36
The two old values are the correct values for that two member variables. This write operation is happened before executing the = function of boost intrusive_ptr, as I pressed tens of "next", and the code is still in file dl-trampoline.S.
(gdb) n
41 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
42 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
43 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
44 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
45 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
46 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
47 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
48 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
49 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
50 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
51 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
52 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
53 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
54 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
56 in ../sysdeps/x86_64/dl-trampoline.S
(gdb) n
boost::intrusive_ptr<geno_eye::Frame>::operator= (this=0x6071b0, rhs=0x3e8)
at /usr/include/boost/smart_ptr/intrusive_ptr.hpp:134
134 {
What is dl-trampoline.S ? Why it silently write on the memory of my object?
In addition of that, I also run valgrind:
$ valgrind ./t_page
However, instead of invalid write, it reports invalid read to that object, which is happened after the object creation is finished.
This is caused by an reference-to-stack bug.
Object genome_scale holds two references to two member variables of frame object. When I reconstruct my code, it accidentally reference to two stack variables...
So, maybe I should avoid the use of reference types in this situation, as you can easily provide stack stuffs to them and don't get any warns.