G2O BlockSolver Initialization Crash on Unix System - c++11

I have a project which possesses and uses G2O library, it runs on both platforms(win/Unix).
(WINDOW PASSED / UNIX CRASHED)
We can see in both platforms, these lines:
g2o::SparseOptimizer optimizer;
g2o::BlockSolver_6_3::LinearSolverType * linearSolver;
linearSolver = new g2o::LinearSolverDense<g2o::BlockSolver_6_3::PoseMatrixType>();
Next steps, in window os we have this:
g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver);
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr);
But Unix system can't compile those lines because it says
my_file_G2o.cpp: *In member function 'int Refiner_G2O::refinePose(cv::Mat&, const std::vector >&, const std::vector&, const cv::Mat&, float, std::vector&)': my_file_G2o.cpp --> no matching function for call to 'g2o::BlockSolver::BlockSolver(g2o::BlockSolver::LinearSolverType&)'*
^
In file included from G2o/include/g2o/core/block_solver.h:199:0,
G2o/include/g2o/core/block_solver.hpp:40:1: note: candidate: g2o::BlockSolver::BlockSolver(std::unique_ptr) [with Traits = g2o::BlockSolverTraits<6, 3>; typename Traits::LinearSolverType = g2o::LinearSolver >]
BlockSolver::BlockSolver(std::unique_ptr linearSolver)
When I see these errors, I complete my Unix code with this new block
auto solver_ptr = g2o::make_unique<g2o::BlockSolver_6_3>(linearSolver); // [SEGFAULT LINE]
auto solver = g2o::make_unique<g2o::OptimizationAlgorithmLevenberg>(solver_ptr);
optimizer.setAlgorithm(solver.get());
So now, I can build/run but I meet a segfault on the line with [SEGFAULT LINE] tag.
EDIT: After step to step debug with debug build I have a few news pieces of information:
g2o::SparseOptimizer optimizer; // debug says: "optimize: g2o::SparseOptimize
g2o::BlockSolver_6_3::LinearSolverType * linearSolver = NULL; // debug says : linearSolver: NULL
linearSolver = new g2o::LinearSolverDense<g2o::BlockSolver_6_3::PoseMatrixType>(); // debug says: linear solver: 0x7fe39cba9140
if (linearSolver == NULL) // debug says : not null.
exit (84);
auto solver_ptr = g2o::make_unique<g2o::BlockSolver< g2o::BlockSolver_6_3 >>(linearSolver);
// DEBUG --> And here, with "step into" he go to this "/usr/include/c++/6/bits/move.h"
and in the ligne 48 we can see this function:
`template<typename T, typename ...ArgTs>
std::unique_ptr<T> make_unique(ArgTs&& ...args) //DEBUG says: args#0:
-var-create: unable to create variable object.
{
return std::unique_ptr<T>(g2o::make_unique<T>(std::forward<ArgTs>
(args)...));
};`
And he segfault because she have a bad args.
I don't understand, why? if someone has an idea I want to understand how in Window it works and not in Unix system, will feel wonderful if you help.
LINUX Version: Ubuntu 16.04
CMAKE Version: 3.11.4
Best regards,

SOLVED:
G2O optimise:
g2o::SparseOptimizer optimizer;
auto linearSolver = std::make_unique<g2o::LinearSolverDense<g2o::BlockSolver_6_3::PoseMatrixType>>();
auto solver = new g2o::OptimizationAlgorithmLevenberg(std::make_unique<g2o::BlockSolver_6_3>(std::move(linearSolver)));
optimizer.setAlgorithm(solver);
MISC.H:
template<typename T, typename ...ArgTs>
std::unique_ptr<T> make_unique(ArgTs&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<ArgTs>(args)...));
};

Related

Has there been any change between kernel 5.15 and 5.4.0 concerning ioctl valid commands?

We have some custom driver working on 5.4.0. It's pretty old and the original developers are no longer supporting it, so we have to maintain it in our systems.
When upgrading to Ubuntu 22 (Kernel 5.15), the driver suddenly stopped working, and sending ioctl with the command SIOCDEVPRIVATE (which used to work in kernel 5.4.0, and in fact is used to get some necessary device information)now gives "ioctl: Operation not supported" error with no extra information anywhere on the logs.
So... has something changed between those two kernels? We did have to adapt some of the structures used to register the driver, but I can't see anything concerning registering valid operations there. Do I have to register valid operations somewhere now?
Alternatively, does somebody know what part of the kernel code is checking for the operation to be supported? I've been trying to find it from ioctl.c, but I can't seem to find where that particular error comes from.
The driver code that supposedly takes care of this (doesn't even reach first line on 5.15):
static int u50_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) {
struct u50_priv *priv = netdev_priv(dev);
if (cmd == SIOCDEVPRIVATE) {
memcpy(&ifr->ifr_data, priv->tty->name, strlen(priv->tty->name));
}
return 0;
}
And the attempt to access it that does no longer work:
struct ifreq ifr = {0};
struct ifaddrs *ifaddr, *ifa;
getifaddrs(&ifaddr);
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
memcpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ);
if (ioctl(lonsd, SIOCDEVPRIVATE, &ifr) < 0) {
perror("ioctl");
syslog(LOG_ERR, "Ioctl:%d: %s\n", __LINE__, strerror(errno));
}
...
and structure for registration
static const struct net_device_ops u50_netdev_ops = {
.ndo_init = u50_dev_init,
.ndo_uninit = u50_dev_uninit,
.ndo_open = u50_dev_open,
.ndo_stop = u50_dev_stop,
.ndo_start_xmit = u50_dev_xmit,
.ndo_do_ioctl = u50_dev_ioctl,
.ndo_set_mac_address = U50SetHWAddr,
};
If you need some code to respond to SIOCDEVPRIVATE, you used to be able to do it via ndo_do_ioctl (writing a compatible function, then linking it in a net_device_ops struct in 5.4). However, in 5.15 it was changed so now you have to implement a ndo_siocdevprivate function, rather than ndo_do_ioctl, which is no longer called, according to the kernel documentation.
source:
https://elixir.bootlin.com/linux/v5.15.57/source/include/linux/netdevice.h
Patch that did this: spinics.net/lists/netdev/msg698158.html

Adding a new Object to V8 using Torque

TL;DR: I tried adding a new Object defined exclusively in Torque and use it as a new member for the Name class. This resulted in compilation failures due to function used but never defined errors, pertaining to a function that IS defined in torque-generated files, however for some reason not properly included.
I am unsure how to proceed and trying to just include different combinations of the torque-generated files in the appropriate locations simply led to redefinition errors.
The question: Is it possible to define a new object and use it in the way I intend to, without adding C++ class definitions (that inherit from the torque-generated classes and so forth) and if yes, where do I seem to be going wrong. In the following I will describe the steps I took so far:
Add a myClass.tq/ file to src/objects that includes a definition of my class along the lines of:
#export
#generateBodyDescriptors
class MyClass extends HeapObject {
macro SomeMacro(): Boolean {...}
macro Set(): void { this.i = 1 }
i: uint32;
}
Add this file to BUILD.gn
I then tried to use this new type to add a member to an existing type (the abstract Name type):
Added a new member in src/objects/name.tq
Included torque-generated/src/objects/myClass.tq in src/objects/name.h
String inherits from Name so i had to modify two "constructors" methods in src/objects/string.tq to include the new member
Changed the expected size of String objects in include/v8-interal.h to account for the new member
Added some macros to Name that actually use the new member (check if its internal uint is non-zero and set the value to one)
And lastly I added two methods to the String prototype that I defined as javascript builtins, so that I can verify my changes work.
Concretely, the resulting errors complained about the TorqueGeneratedMyClass::cast(Object) method being used but never defined. This error results from the myClass-tq.inc file. However, the method is defined, in the corresponding myClass-tq-inl.inc file.
I'm not sure if I described the issue concretely enough, but I'm happy to clarify uncertainties and appreciate every help.
Edit:
Complete Changes:
// src/objects/myClass.tq
#export
#generateBodyDescriptors
class MyClass extends HeapObject {
macro IsSet(): Boolean {
return this.i == 0 ? False : True;
}
macro Set(): void { this.i = 1 }
i: uint32;
}
// src/objects/name.h
## -16,6 +17,7 ##
namespace v8 {
namespace internal {
+#include "torque-generated/src/objects/taint-tq.inc"
#include "torque-generated/src/objects/name-tq.inc"
// src/objects/name.tq
## -4,7 +4,18 ##
#abstract
extern class Name extends PrimitiveHeapObject {
+ macro IsSet(): Boolean {
+ return this.test.IsSet();
+ }
+
+ macro Set(): void {
+ this.test.Set();
+ }
+
+ test: MyClass;
raw_hash_field: NameHash;
}
// src/objects/string.tq
## -135,7 +135,10 ## macro AllocateNonEmptySeqOneByteString<Iterator: type>(
dcheck(length != 0 && length <= kStringMaxLength);
return new SeqOneByteString{
map: kOneByteStringMap,
+ test: new StringTaint{tainted: 0},
raw_hash_field: kNameEmptyHashField,
length: Signed(length),
chars: ...content
};
## -146,7 +149,10 ## macro AllocateNonEmptySeqTwoByteString<Iterator: type>(
dcheck(length > 0 && length <= kStringMaxLength);
return new SeqTwoByteString{
map: kStringMap,
+ test: new StringTaint{tainted: 0},
raw_hash_field: kNameEmptyHashField,
length: Signed(length),
chars: ...content
};
// src/builtins/string-test.tq
namespace string {
transitioning javascript builtin StringPrototypeIsSet(js-implicit context: NativeContext, receiver: JSAny)(): Boolean {
const string: String = ToThisString(receiver, 'String.prototype.testIsSet');
return string.IsSet();
}
transitioning javascript builtin StringPrototypeSet(js-implicit context: NativeContext, receiver: JSAny)(): JSAny {
const string: String = ToThisString(receiver, 'String.prototype.testSet');
string.Set();
return Undefined;
}
}
// src/init/bootstrapper.cc
## -2078,6 +2078,10 ## void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Builtin::kStringPrototypeSup, 0, false);
SimpleInstallFunction(isolate_, prototype, "startsWith",
Builtin::kStringPrototypeStartsWith, 1, false);
+ SimpleInstallFunction(isolate_, prototype, "testSet",
+ Builtin::kStringPrototypeTaint, 0, true);
+ SimpleInstallFunction(isolate_, prototype, "testIsSet",
+ Builtin::kStringPrototypeIsTainted, 0, true);
SimpleInstallFunction(isolate_, prototype, "toString",
Builtin::kStringPrototypeToString, 0, true);
SimpleInstallFunction(isolate_, prototype, "trim",
// BUILD.gn
## -1698,6 +1698,7 ## torque_files = [
"src/builtins/string-startswith.tq",
"src/builtins/string-substr.tq",
"src/builtins/string-substring.tq",
+ "src/builtins/string-test.tq",
"src/builtins/string-trim.tq",
"src/builtins/symbol.tq",
"src/builtins/torque-internal.tq",
## -1781,6 +1782,7 ## torque_files = [
"src/objects/swiss-hash-table-helpers.tq",
"src/objects/swiss-name-dictionary.tq",
"src/objects/synthetic-module.tq",
+ "src/objects/myClass.tq",
"src/objects/template-objects.tq",
"src/objects/templates.tq",
"src/objects/torque-defined-classes.tq",
Error:
In file included from ../deps/v8/src/objects/name.h:20,
from ../deps/v8/src/objects/string.h:15,
from ../deps/v8/src/heap/factory.h:25,
from ../deps/v8/src/execution/isolate.h:33,
from ../deps/v8/src/logging/log.h:16,
from ../deps/v8/src/heap/base-space.h:12,
from ../deps/v8/src/heap/spaces.h:16,
from ../deps/v8/src/heap/marking-visitor.h:13,
from ../deps/v8/src/heap/concurrent-marking.h:14,
from ../deps/v8/src/heap/concurrent-marking.cc:5:
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/src/objects/myClass-tq.inc:26:22: warning: inline function ‘static D v8::internal::TorqueGeneratedMyClass<D, P>::cast(v8::internal::Object) [with D = v8::internal::MyClass; P = v8::internal::HeapObject]’ used but never defined
26 | V8_INLINE static D cast(Object object);
| ^~~~
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/src/objects/myClass-tq.inc: In static member function ‘static T v8::internal::ConcurrentMarkingVisitor::Cast(v8::internal::HeapObject) [with T = v8::internal::MyClass]’:
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/src/objects/myClass-tq.inc:26:22: error: inlining failed in call to always_inline ‘static D v8::internal::TorqueGeneratedMyClass<D, P>::cast(v8::internal::Object) [with D = v8::internal::MyClass; P = v8::internal::HeapObject]’: function body not available
../deps/v8/src/heap/concurrent-marking.cc:103:19: note: called from here
103 | return T::cast(object);
| ~~~~~~~^~~~~~~~
make[1]: *** [tools/v8_gypfiles/v8_base_without_compiler.target.mk:1000: /home/ccloud/sap_node/out/Release/obj.target/v8_base_without_compiler/deps/v8/src/heap/concurrent-marking.o] Error 1
make[1]: *** Waiting for unfinished jobs....
In file included from ../deps/v8/src/objects/name.h:20,
from ../deps/v8/src/objects/string.h:15,
from ../deps/v8/src/heap/factory.h:25,
from ../deps/v8/src/execution/isolate.h:33,
from ../deps/v8/src/common/ptr-compr-inl.h:10,
from ../deps/v8/src/execution/isolate-utils-inl.h:8,
from ../deps/v8/src/diagnostics/objects-printer.cc:11:
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/src/objects/myClass-tq.inc:26:22: warning: inline function ‘static D v8::internal::TorqueGeneratedMyClass<D, P>::cast(v8::internal::Object) [with D = v8::internal::MyClass; P = v8::internal::HeapObject]’ used but never defined
26 | V8_INLINE static D cast(Object object);
| ^~~~
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/src/objects/myClass-tq.inc: In member function ‘void v8::internal::HeapObject::HeapObjectPrint(std::ostream&)’:
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/src/objects/myClass-tq.inc:26:22: error: inlining failed in call to always_inline ‘static D v8::internal::TorqueGeneratedMyClass<D, P>::cast(v8::internal::Object) [with D = v8::internal::MyClass; P = v8::internal::HeapObject]’: function body not available
../deps/v8/src/diagnostics/objects-printer.cc:216:21: note: called from here
216 | Name::cast(*this).Name##Print(os); \
| ^
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/instance-types.h:637:3: note: in expansion of macro ‘MAKE_TORQUE_CASE’
637 | V(MyClass, MY_CLASS_TYPE) /* src/objects/myClass.tq?l=1&c=1 */ \
| ^
../deps/v8/src/diagnostics/objects-printer.cc:220:7: note: in expansion of macro ‘TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED’
220 | TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../deps/v8/src/objects/name.h:20,
from ../deps/v8/src/objects/string.h:15,
from ../deps/v8/src/heap/factory.h:25,
from ../deps/v8/src/execution/isolate.h:33,
from ../deps/v8/src/common/ptr-compr-inl.h:10,
from ../deps/v8/src/execution/isolate-utils-inl.h:8,
from ../deps/v8/src/diagnostics/objects-printer.cc:11:
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/src/objects/myClass-tq.inc:26:22: error: inlining failed in call to always_inline ‘static D v8::internal::TorqueGeneratedMyClass<D, P>::cast(v8::internal::Object) [with D = v8::internal::MyClass; P = v8::internal::HeapObject]’: function body not available
26 | V8_INLINE static D cast(Object object);
| ^~~~
../deps/v8/src/diagnostics/objects-printer.cc:216:21: note: called from here
216 | Name::cast(*this).Name##Print(os); \
| ^
/home/ccloud/sap_node/out/Release/obj/gen/torque-generated/instance-types.h:637:3: note: in expansion of macro ‘MAKE_TORQUE_CASE’
637 | V(MyClass, MY_CLASS_TYPE) /* src/objects/myClass.tq?l=1&c=1 */ \
| ^
../deps/v8/src/diagnostics/objects-printer.cc:220:7: note: in expansion of macro ‘TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED’
220 | TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Is it possible to define a new object and use it in the way I intend to, without adding C++ class definitions
Yes.
where do I seem to be going wrong
This part seems suspicious:
the method is defined, in the corresponding myClass-tq-inl.inc file
All generated *.inc files have to be #included somewhere. There's likely some *.cc file that needs it (you didn't provide enough details, so I can't tell for sure).
A couple of more general points:
when asking for programming help (anywhere!), provide reproducible code (in this case: your complete patch, not just a prose description of it).
when asking about compiler errors, provide the complete error message, not just a vague summary like "the errors complained about ...".
while you are of course free to fork V8 and muck with its internals, a word of caution: such modifications are likely to be very labor-intensive to maintain as you update to newer V8 versions (and you will want to update to newer V8 versions, if this isn't just some throwaway experiment). To make your work more future-proof, either attempt to upstream it (which might be difficult in this case, as increasing the size of Name objects will be an unpopular proposition, I expect), or use only the public API (which isn't perfectly stable, but much more stable than random internals). Of course, the latter won't allow you to modify internally used objects; since you didn't describe your higher-level goal I can't tell whether that's a dealbreaker or whether there could be alternative approaches.

Unable to send a &str between threads because it does not live long enough

Given the following simplified program:
#[macro_use] extern crate log;
extern crate ansi_term;
extern crate fern;
extern crate time;
extern crate threadpool;
extern crate id3;
mod logging;
use std::process::{exit, };
use ansi_term::Colour::{Yellow, Green};
use threadpool::ThreadPool;
use std::sync::mpsc::channel;
use std::path::{Path};
use id3::Tag;
fn main() {
logging::setup_logging();
let n_jobs = 2;
let files = vec!(
"/tmp/The Dynamics - Version Excursions/01-13- Move on Up.mp3",
"/tmp/The Dynamics - Version Excursions/01-09- Whole Lotta Love.mp3",
"/tmp/The Dynamics - Version Excursions/01-10- Feel Like Making Love.mp3"
);
let pool = ThreadPool::new(n_jobs);
let (tx, rx) = channel();
let mut counter = 0;
for file_ in files {
let file_ = Path::new(file_);
counter = counter + 1;
let tx = tx.clone();
pool.execute(move || {
debug!("sending {} from thread", Yellow.paint(counter.to_string()));
let tag = Tag::read_from_path(file_).unwrap();
let a_name = tag.artist().unwrap();
debug!("recursed file from: {} {}",
Green.paint(a_name), file_.display());
tx.send(".").unwrap();
// TODO amb: not working..
// tx.send(a_name).unwrap();
});
}
for value in rx.iter().take(counter) {
debug!("receiving {} from thread", Green.paint(value));
}
exit(0);
}
Everything works as expected, unless the one commented line (tx.send(a_name).unwrap();) is put back in. In that case I get the following error:
error: `tag` does not live long enough
let a_name = tag.artist().unwrap();
^~~
note: reference must be valid for the static lifetime...
note: ...but borrowed value is only valid for the block suffix following statement 1 at 39:58
let tag = Tag::read_from_path(file_).unwrap();
let a_name = tag.artist().unwrap();
debug!("recursed file from: {} {}",
Green.paint(a_name), file_.display());
...
Generally I understand what the compiler tells me, but I don't see a problem since the variable tag is defined inside of the closure block. The only problem that I can guess is, that the variable tx is cloned outside and therefore can collide with the lifetime of tag.
My goal is to put all the current logic in the thread-closure inside of the thread, since this is the "processing" I want to spread to multiple threads. How can I accomplish this, but still send some value to the longer existing tx?
I'm using the following Rust version:
$ rustc --version
rustc 1.9.0 (e4e8b6668 2016-05-18)
$ cargo --version
cargo 0.10.0-nightly (10ddd7d 2016-04-08)
a_name is &str borrowed from tag. Its lifetime is therefore bounded by tag. Sending non 'static references down a channel to another thread is unsafe. It refers to something on the threads stack which might not even exist anymore once the receiver tries to access it.
In your case you should promote a_name to an owned value of type String, which will be moved to the receiver thread.
tx.send(a_name.to_owned()).unwrap();

Matlab MEX File: Program Crashes in the second run: Access Violation in Read

I have a C++ code that I am trying to interface with Matlab. My mex file runs fine in the first run but crashes in the second run. However, if I clear all the variables in the Matlab before execution (using clear all) program never crashes. So I have a question in this:
1. Can mex function takes variables from the Matlab workspace without using some special functions? Am I doing it somehow in my code, unintentionally?
I have a posted the mex function that I wrote. It has a one dimensional vector called "block" that is read inside the C++ function called sphere_detector. For the present problem the block size is 1x1920 and it is read in the chunk of 16 elements inside the sphere_detector. Program crashed when I read the SECOND chunk of 16 elements. The first element that I read in the chunk will throw this error:
First-chance exception at 0x000007fefac7206f (sphere_decoder.mexw64) in MATLAB.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
MATLAB.exe has triggered a breakpoint
I checked my block vector, it should have all the values initialized and it has that. So, I am little confused as to why I am facing this problem.
I am using Matlab 2010a and Visual Studio 2010 Professional.
Here is the mex function:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *mod_scheme, *Mt, *Mr, *block_length, *SNR;
mod_scheme = mxGetPr(prhs[0]);
Mt = mxGetPr(prhs[1]);
Mr = mxGetPr(prhs[2]);
block_length = mxGetPr(prhs[3]);
SNR = mxGetPr(prhs[4]);
/* Now take the input block. This is an encoded block and sphere detector will do the transmission too -- I can change it later */
double *block = mxGetPr(prhs[5]);
double *LIST_SIZE = mxGetPr(prhs[6]);
double **cand_sym;
int a = *mod_scheme;
int b = *Mt;
int c = *Mr;
int d = *block_length;
int e = *SNR;
int f = *LIST_SIZE;
int bitSize = (int)(log10(1.0*a)/log10(2.0));
for(int i=0; i<(int)*block_length; ++i)
{
printf("%d\n", (int)block[i]);
}
printf("Hello world %d %d %d %d %d!\n", (int)*mod_scheme, (int)*Mt, (int)*Mr, (int)*block_length, (int)*SNR);
/* Inputs are read correctly now set the outputs */
double *llr, *cand_dist;
/* for llrs */
plhs[0] = mxCreateDoubleMatrix(1, d, mxREAL);
llr = mxGetPr(plhs[0]);
/* for cand_dist */
int no_mimo_sym = d/(b*bitSize);
plhs[1] = mxCreateDoubleMatrix(1, f*no_mimo_sym, mxREAL);
cand_dist = mxGetPr(plhs[1]);
/* for cand_syms */
plhs[2] = mxCreateDoubleMatrix(b*bitSize*no_mimo_sym, f,mxREAL); //transposed version
double *candi;
candi = mxGetPr(plhs[2]);
cand_sym = (double**)mxMalloc(f*sizeof(double*));
if(cand_sym != NULL)
{
for(int i=0;i<f; ++i)
{
cand_sym[i] = candi + i*b*bitSize*no_mimo_sym;
}
}
sphere_decoder(a,b,c,d,e,block,f,llr,cand_dist,cand_sym);
// mxFree(cand_sym);
}
The portion inside the sphere decoder code where I get read exception looks like this:
for(int _block_length=0;_block_length<block_length; _block_length+=Mt*bitSize)
{
printf("Transmitting MIMO Symbol: %d\n", _block_length/(Mt*bitSize));
for(int _antenna = 0; _antenna < Mt; ++_antenna)
for(int _tx_part=0;_tx_part<bitSize; _tx_part++)
{
// PROGRAM CRASHES EXECUTING THIS LINE
bitstream[_antenna][_tx_part] = (int)block_data[_block_length + _antenna*bitSize + _tx_part];
}
............................REST OF THE CODE..................
}
Any help would be appreciated.
With regards,
Newbie
Well I finally managed to solve the problem. It was a very stupid mistake that I made. I had a pointer to a pointer(double *a;) of data type double and by mistake I assigned it memory of integer (I ran a find and replace command where I changed lots of int to double but this one left). Hence heap was getting corrupted. Also I changed my Mex function where I created dynamic variables using calloc and passed them to the C++ function. Once C++ function returned I copied there values to matlab variables and freed them usind free().

Getting the current stack trace on Mac OS X

I'm trying to work out how to store and then print the current stack in my C++ apps on Mac OS X. The main problem seems to be getting dladdr to return the right symbol when given an address inside the main executable. I suspect that the issue is actually a compile option, but I'm not sure.
I have tried the backtrace code from Darwin/Leopard but it calls dladdr and has the same issue as my own code calling dladdr.
Original post:
Currently I'm capturing the stack with this code:
int BackTrace(Addr *buffer, int max_frames)
{
void **frame = (void **)__builtin_frame_address(0);
void **bp = ( void **)(*frame);
void *ip = frame[1];
int i;
for ( i = 0; bp && ip && i < max_frames; i++ )
{
*(buffer++) = ip;
ip = bp[1];
bp = (void**)(bp[0]);
}
return i;
}
Which seems to work ok. Then to print the stack I'm looking at using dladdr like this:
Dl_info dli;
if (dladdr(Ip, &dli))
{
ptrdiff_t offset;
int c = 0;
if (dli.dli_fname && dli.dli_fbase)
{
offset = (ptrdiff_t)Ip - (ptrdiff_t)dli.dli_fbase;
c = snprintf(buf, buflen, "%s+0x%x", dli.dli_fname, offset );
}
if (dli.dli_sname && dli.dli_saddr)
{
offset = (ptrdiff_t)Ip - (ptrdiff_t)dli.dli_saddr;
c += snprintf(buf+c, buflen-c, "(%s+0x%x)", dli.dli_sname, offset );
}
if (c > 0)
snprintf(buf+c, buflen-c, " [%p]", Ip);
Which almost works, some example output:
/Users/matthew/Library/Frameworks/Lgi.framework/Versions/A/Lgi+0x2473d(LgiStackTrace+0x5d) [0x102c73d]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x2a006(tart+0x28e72) [0x2b006]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x2f438(tart+0x2e2a4) [0x30438]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x35e9c(tart+0x34d08) [0x36e9c]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x1296(tart+0x102) [0x2296]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x11bd(tart+0x29) [0x21bd]
It's getting the method name right for the shared object but not for the main app. Those just map to "tart" (or "start" minus the first character).
Ideally I'd like line numbers as well as the method name at that point. But I'll settle for the correct function/method name for starters. Maybe shoot for line numbers after that, on Linux I hear you have to write your own parser for a private ELF block that has it's own instruction set. Sounds scary.
Anyway, can anyone sort this code out so it gets the method names right?
What releases of OS X are you targetting. If you are running on Mac OS X 10.5 and higher you can just use the backtrace() and backtrace_symbols() libraray calls. They are defined in execinfo.h, and there is a manpage with some sample code.
Edit:
You mentioned in the comments that you need to run on Tiger. You can probably just include the implementation from Libc in your app. The source is available from Apple's opensource site. Here is a link to the relevent file.

Resources