Intel C++ compiler can't handle deep templates? - c++

I have a project in C++ using marray library. For now it compiles and runs quite fine with MinGW g++ 4.7 and msvc2010 on Windows 7 x64 and also with g++ 4.7 on Linux Mint x64. I decided to give a try to Intel C++ compiler v. 12.1.4 for Linux. It was able to compile the code but when it tries to execute any line bothering expression templates (like c = a + b where all three terms are matrices) it breaks down with segmentation fault. This issue affects both debug and release versions of the app.
I also tried to compile unit tests and tutorial code for marray library and again, Intel C++ compiles the code but fails to run it if it has any expression templates. Is Intel C++ really as bad with deep templates or am I missing something? Do I need to set any special compiler flags to make template expressions work? Or maybe it is just something wrong with the particular library I'm using, not the expression templates technique in general?
I also tried to set the -ftemplate-depth-n flag using a wide variety on n up to ridiculously large values of 10^10 and still had no luck in running neither my app nor marray unit tests/tutorial without the segmentation fault.
Upd.: Here is the gdb log for tutorial-marray from the mentioned library compiled with icpc in debug mode.
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/dmitry/SOFT/Development/marray_orig/tutorial-marray...done.
(gdb) l 126
121 size_t shape[] = {3, 4, 2};
122 marray::Marray<int> a(shape, shape + 3, 2);
123 marray::Marray<int> b(shape, shape + 3, 2);
124 marray::Marray<int> c;
125
126 ++a;
127 --a;
128
129 a += 2;
130 a -= 2;
(gdb) break 126
Breakpoint 1 at 0x452de8: file /home/dmitry/SOFT/Development/marray_orig/marray/src/tutorial/tutorial.cxx, line 126.
(gdb) run
Starting program: /home/dmitry/SOFT/Development/marray_orig/tutorial-marray
A(c,r,0) =
1 0 0
0 0 0
0 0 0
0 0 0
A(c,r,1) =
0 0 0
0 0 0
0 0 0
0 0 2
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2
Breakpoint 1, main () at /home/dmitry/SOFT/Development/marray_orig/marray/src/tutorial/tutorial.cxx:126
126 ++a;
(gdb) next
127 --a;
(gdb) next
129 a += 2;
(gdb) next
130 a -= 2;
(gdb) next
131 a /= 2;
(gdb) next
132 a *= 2;
(gdb) next
134 c = a + b;
(gdb) next
Program received signal SIGSEGV, Segmentation fault.
0x0000000000420fcf in marray::ViewExpression<marray::View<int, false, std::allocator<unsigned long> >, int>::operator marray::View<int, false, std::allocator<unsigned long> > const& (this=0x7fffffffcd88)
at /home/dmitry/SOFT/Development/marray_orig/marray/include/marray/marray.hxx:5409
5409 { return static_cast<const E&>(*this); }
(gdb)
Looks like the problem doesn't originate from the expression template technique in general, array arithmetics with numbers works fine. The problem arises when I'm trying to add one array to another.
Upd. 2: Actually the whole thing looks quite like the problem mentioned here. The solution should be in rewriting operator E&() { return static_cast(*this); } into something like E& get_ref() { return static_cast(*this); } and the same thing for const reference. And, of course, change the usage of these things within the code. Will try it as soon as I can and report the results.

The problem is similar to the one reported here. The actual reason of the issue is that the code generated by Intel C++ compiler handles expressions like this:
operator E&()
{
return static_cast<E&>(*this);
}
as recursive calls of this operator. A simple workaround is to change the operator into method like
E& get_ref()
{
return static_cast<E&>(*this);
}
The drawback is that you have to change every line of code which used that operator. Fortunately, it wasn't too hard with the mentioned marray library, so now both my app and the tutorials and unit tests of that library work like a charm with Intel C++ compiler.

Related

Why cuda-gdb shows unexpected memory values?

I am compiling the following fragment of code with nvcc -g -G gdbfail.cu.
#include <cstdio>
#include <cinttypes>
__global__ void mykernel() {
uint8_t* ptr = (uint8_t*) malloc(8);
for (int i = 0; i < 8; i++) {
ptr[i] = 7 - i;
}
for (int i = 0; i < 8; i++) { // PUT BREAKPOINT HERE
printf("%" PRIx8 " ", ptr[i]);
}
printf("\n");
}
int main() {
uint8_t* ptr = (uint8_t*) malloc(8);
for (int i = 0; i < 8; i++) {
ptr[i] = 7 - i;
}
for (int i = 0; i < 8; i++) { // PUT BREAKPOINT HERE
printf("%" PRIx8 " ", ptr[i]);
}
printf("\n");
mykernel<<<1,1>>>();
cudaDeviceSynchronize();
}
When I run cuda-gdb ./a.out and put breakpoint at line 10 (b 10), run the code (r), and trying to print values at the address located in ptr I get surprising results
(cuda-gdb) x/8b ptr
0x7fffcddff920: 7 6 5 4 3 2 1 0
(cuda-gdb) x/8b 0x7fffcddff920
0x7fffcddff920: 0 0 0 0 0 0 0 0
When I am doing the same thing in the host code (b 23, r), I get expected results:
(cuda-gdb) x/8b ptr
0x5555556000a0: 7 6 5 4 3 2 1 0
(cuda-gdb) x/8b 0x5555556000a0
0x5555556000a0: 7 6 5 4 3 2 1 0
Why cuda-gdb doesn't show correct memory values when it is provided with address as a number (0x7fffcddff920) instead of a symbol (ptr)?
Evidently, not all gdb command features that are usable in host code are also usable in device code. When used in device code, the supported commands may have different syntax or expectations. This is indicated in the cuda-gdb docs.
Those docs indicate that the way to inspect memory is the print command and indicate some additional decode syntax that is needed for a "bare" address/pointer. Here is your example:
$ cuda-gdb ./t1869
NVIDIA (R) CUDA Debugger
11.4 release
Portions Copyright (C) 2007-2021 NVIDIA Corporation
GNU gdb (GDB) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./t1869...
(cuda-gdb) b 10
Breakpoint 1 at 0x403b05: file t1869.cu, line 14.
(cuda-gdb) r
Starting program: /home/user2/misc/t1869
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
7 6 5 4 3 2 1 0
[Detaching after fork from child process 25822]
[New Thread 0x7fffef475700 (LWP 25829)]
[New Thread 0x7fffeec74700 (LWP 25830)]
[Switching focus to CUDA kernel 0, grid 1, block (0,0,0), thread (0,0,0), device 0, sm 0, warp 0, lane 0]
Thread 1 "t1869" hit Breakpoint 1, mykernel<<<(1,1,1),(1,1,1)>>> () at t1869.cu:10
10 for (int i = 0; i < 8; i++) { // PUT BREAKPOINT HERE
(cuda-gdb) x/8b ptr
0x7fffbcdff920: 7 6 5 4 3 2 1 0
(cuda-gdb) p/x *(#global unsigned char *)0x7fffbcdff920#8
$1 = {0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0}
(cuda-gdb)
Note the above print command needs some help in interpreting which "space" you are expecting the memory address to refer to (e.g. #shared, #global, etc.)
If we give your command the same "help" we get the expected result:
(cuda-gdb) x/8b ptr
0x7fffbcdff920: 7 6 5 4 3 2 1 0
(cuda-gdb) x/8b (#global unsigned char *)0x7fffbcdff920
0x7fffbcdff920: 7 6 5 4 3 2 1 0
(cuda-gdb)

Why memset works to initialize 2D array in C++ with zero but failed to set when declared like this `array[n][k+1]={0}`? [duplicate]

#include <iostream>
using namespace std;
int main() {
int rows = 10;
int cols = 9;
int opt[rows][cols] = {0};
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << opt[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
Output:
0 32767 1887606704 10943 232234400 32767 1874154647 10943 -1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
I'm using gcc 6.3, in https://www.codechef.com/ide
I'm expecting the first row to be all zeros. Shouldn't that be the case?
EDIT: I tested with const variables for rows and cols, and then it initialized to all zeroes. I feel this should throw a compile error instead of exhibiting this incorrect (and potentially dangerous) behavior.
If we look at the gcc 4.9 release notes it looks like they added support for initializating VLA with the expectation VLA would be supported in a future version of C++:
G++ supports C++1y variable length arrays. G++ has supported GNU/C99-style VLAs for a long time, but now additionally supports initializers and lambda capture by reference. In C++1y mode G++ will complain about VLA uses that are not permitted by the draft standard, such as forming a pointer to VLA type or applying sizeof to a VLA variable. Note that it now appears that VLAs will not be part of C++14, but will be part of a separate document and then perhaps C++17.
We can see it live that before 4.9 complains we can't initialize a VLA
error: variable-sized object 'opt' may not be initialized
int opt[rows][cols] = {0};
^
but in 4.9.1 and after it stops complaining and it does not have the same bug we see in more recent versions.
So it looks like a regression.
Note that clang refuses to allow initialization of a VLA (which they support as an extension) see a live example. Which make sense since C99 does not allow initialization of VLA:
The type of the entity to be initialized shall be an array of unknown size or an object type that is not a variable length array type.
gcc Bug 69517
gcc bug report :SEGV on a VLA with excess initializer elements has a comment that provides some background on this feature:
(In reply to Jakub Jelinek from comment #16)
The bug here is in G++ accepting a VLA initializer with more elements than there is room for in the VLA, and then trashing the stack at runtime with the extra elements. It is a regression with respect to GCC 4.9.3 which implements C++ VLAs as specified in n3639 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html). This is documented in GCC 4.9 changes (https://gcc.gnu.org/gcc-4.9/changes.html) which highlights the feature using the following example:
void f(int n) {
int a[n] = { 1, 2, 3 }; // throws std::bad_array_length if n < 3
...
VLAs were subsequently removed from C++, and also partially (but not completely) removed from G++, which causes C++ programs developed and tested with G++ 4.9 to break when ported to a later version.
C++ VLAs will be safer to use with the patch referenced in comment #9. It patch had to be reverted from GCC 6.0 because it caused problems in Java. Java has been removed and I plan/hope to resubmit the patch for GCC 8. (I wanted to do it for GCC 7 but didn't get to it.)
This appears to be a GCC bug, and the desired behavior is most likely that this shouldn't compile. C99 supports variable-length arrays, but refuses to initialize them: C initializers need to know their type at compile-time, but the type of a variable-length array can't be complete at compile-time.
In GCC, C++ gets variable-length arrays as an extension from its C99 support. Therefore, the behavior governing variable-length array initialization in C++ isn't established by a standard. Clang refuses to initialize a variable-length array even in C++.
Note that even = {0} is technically sort of dangerous (if it worked at all): if rows and cols are 0, you'll be overflowing. Memset is probably your best option.
I posted this question to understand what's wrong with my code or gcc. But, this is how I would do it in C++. Use vectors instead of arrays for variable length array requirements.
#include <iostream>
#include <vector>
int main() {
int rows = 10;
int cols = 9;
std::vector<std::vector<int>> opt(rows, std::vector<int>(cols, 0));
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << opt[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
Output:
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

How can I update my old fortran 77 script to f90 or newer one?

I usually deal with data file with multiple data block, repeating n number of lines for m number of times.
This is one of the example:
9276
4900000
AA 4 4 6260 519 8350 1571 0 0 0 0 0 0 0 0.934 0.933 0.93 0.935 0 0 0 0 0 0 3.867 0.0 1.541
BB 3 3 3388 8391 6637 0 0 0 0 0 0 0 0 0.939 0.565 0.361 0 0 0 0 0 0 0 1.913 2.0 -0.732
CC 3 2 241 694 0 0 0 0 0 0 0 0 0 0.933 0.941 0 0 0 0 0 0 0 0 1.888 2.0 -0.834
...
Top line is total number of line for data block, second line is other value, those two lines are header. Then following 9276 lines are data. One datablock has 9278 lines, and then the same format of datablock repeats from 9279 line, for m number of data block. Usually m become really huge.
So far, I use something like this using f77 format:
program test
parameter (nn = 20000)
integer,dimension(nn,nn) :: conn
integer,dimension(nn) :: aaa,bbb,ccc,ddd,eee
real,dimension(nn) :: fff,ggg,hhh,iii,zzz
real,dimension(nn,nn) :: bos
character*2,dimension(nn) :: elem
open (2, file = 'input.txt', status = 'old')
iframe=0
100 continue
iframe=iframe+1
read (2,15, err = 50,end= 50) nat2
read (2,15) framenum2
do i=1,nat2
read (2,42) elem(i),aaa(i),ccc(i),(conn(i,j),j=1,10),ddd(i),(bos(i,j),j=1,10),fff(i),ggg(i),zzz(i)
enddo
do something using do and if loops
write (120,15) nat2
write (120,15) framenum2
do i=1,nat
write (120,75) elem(i),test(i),result(i)
write (121,76) iframe, zzz2, iii2
enddo
goto 100
I don't need to write formats, they are all properly formatted. As you could see, my script reads data per each datablock, do something, print them, then go to next datablock.
I learned fortran so long time ago, and I didn't cared that much about my style, and didn't think I should learn new style. But these days I feels like I should be more familiar with newer style of fortran. I feel I'm bit too late to learn new language at this point (mostly due to time constraint) so I think I better stick to the fortran...
Anyway, I want to change this to f90 style. But I'm not sure where should I need to begin. How can I improve this style of declaration, open, read, and write to be more efficient and faster? Any suggestion about those? I prefer f90 style but if there are any newer fortran way, I will be interested (if it is freeware and compilable with f90 or intel fortran)

Strange C++ 2D array initialization [duplicate]

#include <iostream>
using namespace std;
int main() {
int rows = 10;
int cols = 9;
int opt[rows][cols] = {0};
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << opt[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
Output:
0 32767 1887606704 10943 232234400 32767 1874154647 10943 -1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
I'm using gcc 6.3, in https://www.codechef.com/ide
I'm expecting the first row to be all zeros. Shouldn't that be the case?
EDIT: I tested with const variables for rows and cols, and then it initialized to all zeroes. I feel this should throw a compile error instead of exhibiting this incorrect (and potentially dangerous) behavior.
If we look at the gcc 4.9 release notes it looks like they added support for initializating VLA with the expectation VLA would be supported in a future version of C++:
G++ supports C++1y variable length arrays. G++ has supported GNU/C99-style VLAs for a long time, but now additionally supports initializers and lambda capture by reference. In C++1y mode G++ will complain about VLA uses that are not permitted by the draft standard, such as forming a pointer to VLA type or applying sizeof to a VLA variable. Note that it now appears that VLAs will not be part of C++14, but will be part of a separate document and then perhaps C++17.
We can see it live that before 4.9 complains we can't initialize a VLA
error: variable-sized object 'opt' may not be initialized
int opt[rows][cols] = {0};
^
but in 4.9.1 and after it stops complaining and it does not have the same bug we see in more recent versions.
So it looks like a regression.
Note that clang refuses to allow initialization of a VLA (which they support as an extension) see a live example. Which make sense since C99 does not allow initialization of VLA:
The type of the entity to be initialized shall be an array of unknown size or an object type that is not a variable length array type.
gcc Bug 69517
gcc bug report :SEGV on a VLA with excess initializer elements has a comment that provides some background on this feature:
(In reply to Jakub Jelinek from comment #16)
The bug here is in G++ accepting a VLA initializer with more elements than there is room for in the VLA, and then trashing the stack at runtime with the extra elements. It is a regression with respect to GCC 4.9.3 which implements C++ VLAs as specified in n3639 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html). This is documented in GCC 4.9 changes (https://gcc.gnu.org/gcc-4.9/changes.html) which highlights the feature using the following example:
void f(int n) {
int a[n] = { 1, 2, 3 }; // throws std::bad_array_length if n < 3
...
VLAs were subsequently removed from C++, and also partially (but not completely) removed from G++, which causes C++ programs developed and tested with G++ 4.9 to break when ported to a later version.
C++ VLAs will be safer to use with the patch referenced in comment #9. It patch had to be reverted from GCC 6.0 because it caused problems in Java. Java has been removed and I plan/hope to resubmit the patch for GCC 8. (I wanted to do it for GCC 7 but didn't get to it.)
This appears to be a GCC bug, and the desired behavior is most likely that this shouldn't compile. C99 supports variable-length arrays, but refuses to initialize them: C initializers need to know their type at compile-time, but the type of a variable-length array can't be complete at compile-time.
In GCC, C++ gets variable-length arrays as an extension from its C99 support. Therefore, the behavior governing variable-length array initialization in C++ isn't established by a standard. Clang refuses to initialize a variable-length array even in C++.
Note that even = {0} is technically sort of dangerous (if it worked at all): if rows and cols are 0, you'll be overflowing. Memset is probably your best option.
I posted this question to understand what's wrong with my code or gcc. But, this is how I would do it in C++. Use vectors instead of arrays for variable length array requirements.
#include <iostream>
#include <vector>
int main() {
int rows = 10;
int cols = 9;
std::vector<std::vector<int>> opt(rows, std::vector<int>(cols, 0));
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << opt[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
Output:
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

Is it possible to determine the cause of a HPUX PA-RISC seg fault without using pmap or wdb?

We are encountering a randomly occurring segmentation fault on a C/C++ HPUX PA-RISC application RELEASE demo compiled with the HPUX PARISC compiler and linker ACC which loads a HPUX PA_RISC RELEASE shared object sl(i.e. so) compiled and linked with ACC. We do not have access to pmap or HPUX wdb. So we are using HP's proprietary debugger adb. Here is how we use use adb:
$ adb
PA-32 adb ($h help $q quiit)
adb>!cp mdMUReadWriteExample a.out
!
adb>:r
a.out: running (process 10947)
segmentation violation
stopped at 1E3C: STW r3,1416(r1)
At this point it appears the offending instruction is somehow related to the above assembly insruction. Our first question is whether 1416 is in decimal format or hexadecimal format.
Our second question is whether the program counter 1E3C is accurate and can be used to gain further information about the offending C/C++ source line of code/
Our third question is that supposing 1416 is in decimal format , then as shown below register 1($r1) contains 0x40015b90. Using hexadecimal arithmetic 1416(base 10(i.e. hex 0x588)) + 0x40015b90 equals 0x40016118. Next , we use nm to find the shared object library address / C++ mangled symbol associated with 0x40016118.
$ grep -n "4001611" /home/marc/acc3_pa_32bit/cameron_nm.txt
27808:40016118 ? static___soa_RSA_cpp_
27823:40016110 ? static___soa_cDateTime_cpp_
Next we modify our makefile to obtain the combined disassembly -- C++ source code. However, when we search all the 50 generated *.s files we cannot mysteriously find the static___soa_RSA_cpp_. Have we skipped a crucial step here ?
adb>$r
pcoqh 0 1E3F
pcoqt 0 1E43
rp 0 0xC0209793
arg0 0 1 arg1 0 7F7F04FC arg2 0 7F7F050 4 arg3 0 7F7F0540
sp 0 7F7F05D0 ret0 0 0 ret1 0 1 dp 0 40016390
r1 0 40015B90 r3 0 7F7F0000 r4 0 4001591 8 r5 0 3C
r6 0 20 r7 0 3E r8 0 7F7F091 0 r9 0 40015918
r10 0 40031918 r11 0 1E800 r12 0 4001611 8 r13 0 400266A4
r14 0 3F r15 0 3F r16 0 3D r17 0 3D
r18 0 3A r19 0 7B03B764 r20 0 0xA98D4 00 r21 0 7F7F0550
r22 0 0 r31 0 1E2B sar 0 23 sr0 0 0xA98D400
sr1 0 3848400 sr2 0 0 sr3 0 0 sr4 0 0xA98D400
In summary, we are trying to determine if it is possible to find the offending C/C++ source lines which cause this random seg fault. Using Centos Linux and valgrind --tool=memcheck we cannot find any buffer overruns. Thank you.
Good evening, I figured out how to obtain a segmentation fault stack trace with HPUX PA-RISC. 4 steps are required 1) #include "unwind.h" #include "signal.h" 2) define an extern "C" U_STACK_TRACK(int) function prototype 3) in the main function declare a SIGSEGV handler: signal(SIGSEGV,U_STACK_TRACE). 4) In the makefile, link to libcl .Regards , Frank Tzepu Chang
$ mdMUReadWriteExample
( 0) 0xc01fef60 _sigreturn [/usr/lib/libc.2]
( 1) 0xc2f27b90 _ct_7CBigNumFv_2 + 0x88 [./libmdMatchup.sl]
( 2) 0xc2f3c83c RSADecrypt_FPCcN21Pc + 0x24 [./libmdMatchup.sl]
( 3) 0xc2f314ec DecryptLicense_9mdLicenseFPCcPc + 0x44 [./libmdMatchup.sl]
( 4) 0xc2f31280 DecryptDecodeTest_9mdLicenseFPCcT1 + 0x40 [./libmdMatchup.s
l]
( 5) 0xc2f30c3c TestLicense_9mdLicenseFPCc + 0xb4 [./libmdMatchup.sl]
( 6) 0xc2d783bc SetLicenseString_12cBatchDedupeFPCc + 0x5c [./libmdMatchup.
sl]
( 7) 0xc2d6c908 SetLicenseString_13mdMUReadWriteFPCc + 0x90 [./libmdMatchup
.sl]
( 8) 0x0000376c main + 0x68 [./mdMUReadWriteExample]
( 9) 0xc01409f8 _start + 0xa0 [/usr/lib/libc.2]
(10) 0x00002008 $START$ + 0x178 [./mdMUReadWriteExample]
Segmentation fault (core dumped)