I am writing a VScode extension and I need to read variables from cpp code. I read through the API and found how to make requests to current DebugSession (https://code.visualstudio.com/api/references/vscode-api#DebugSession) and read the "variables" as following:
const threads = await session.customRequest('threads');
const stacks = await session.customRequest('stackTrace', {threadId: threads.threads[0].id});
const scopes = await session.customRequest('scopes', {frameId: stacks.stackFrames[0].id});
const variables = await session.customRequest('variables', {variablesReference: scopes.scopes[0].variablesReference});
Looking a the variables I see:
As value, it is giving a pointer. So I tried to read it by:
const startMemoryAddress = variable.value.substring(variable.value.indexOf("#")+2);
const memoryResponse = await session.customRequest('readMemory', {memoryReference: startMemoryAddress, count: 12}); // I know it is 12 because I did sizeof in cpp, and also is an Eigen::Vector3f which is 3x4 bytes.
But it crashes.
Up to this point, I have two questions:
Is that the right way of reading the memory?
This method does not extend quite well, because the classes might get complex and have pointers to heap etc... How does the vscode GUI do it to get the frame/shape of the classes to watch them?
Related
I've been trying to get a persistent object from a thread for hours.
I want to write a shared library in C++ that starts a persistent loop in a function.
In the following code snippets there is a class called Process. Process initializes a TCP/IP interface to read and write data from a Simulink model.
This is only for declaration and should not be important for this problem, but now you know what I talk about when mentioning the processes.
main.cpp
I know, it looks kinda ugly/unprofessional, but I'm fairly new to C++..
// frustrated attempt to make everything persistent
static vector<std::thread> processThreads;
static ProcessHandle processHandle;
static vector<std::promise<Process>> promiseProcess;
static vector<std::future<Process>> futureProcess;
EXPORT int initializeProcessLoop(const char *host, int port)
{
std::promise<Process> promiseObj;
futureProcess.push_back(std::future<Process>(promiseObj.get_future()));
processThreads.push_back(std::thread(&ProcessHandle::addProcess, processHandle, host, port, &promiseProcess[0]));
Process val = futureProcess[0].get();
processHandle.handleList.push_back(val);
return (processHandle.handleList.size() - 1);
}
ProcessHandle.cpp
The addProcess function from ProcessHandle creates the Process that should be persistent, adds it to a static vector member of ProcessHandle and passes the promise to the execution loop.
int ProcessHandle::addProcess(const char *address, int port, std::promise<Process> * promiseObj) {
Process process(address, port);
handleList.push_back(process);
handleList[handleList.size() - 1].exec(promiseObj);
return handleList.size() - 1;
}
To the main problem now...
If I change "initializeProcessLoop" to include:
if(processHandle.handleList[0].isConnected())
{
processHandle.handleList[0].poll("/Compare To Constant/const");
}
after i've pushed "val" to the processHandle.handleList everything works fine and I can poll the data as it should be.
If I instead poll it from - for examle - the main function, the loop crashes inside of the "initializeProcessLoop" because "Process val" is reassigned (?) with futureProcess[0].get().
How can I get the Process variable and the threaded loop to be consistent after the function returns?
If there are any questions to the code (and I bet there will be), feel free to ask. Thanks in advance!
PS: Obligatory "English is not my native language, please excuse any spelling errors or gibberish"...
Okay, first I have to declare, that the coding style above and following are by any means not best practice.
While Sam Varshavchik is still right with how to learn C++ the right way, just changing
Process val = futureProcess[0].get();
to
static Process val = futureProcess[0].get();
did the job.
To be clear: don't do this. It's a quick fix but it will backfire in the future. But I hope that it'll help anyone with a similar problem.
If anyone has a better solution (it can't get any worse, can it?), feel free to add your answer to this question.
Suppose I have a code in Java (or any other language) that I want to test. Let's say that I want to test how the code behaves when variable 'myVar' holds an integer value of 10 at a certain line.
One option will be to assign the value 10 to variable 'myVar' at this line. This will work fine, but it will make the code dirty. If I want to test another scenario, I'll have to fix this line. What will happen if I have a huge number of scenarios ?
I was wondering whether there is an option to hold an external file/configuration that will be loaded whenever I want to test this specific scenario without modifying the code?
One of the ways is to use a Json File. Just put your value into the Json file "test.json" at location c:\testfolder with following content:
{
"Scenario":"10"
}
Now you can access the value using following code in C#:
StreamReader file = File.OpenText("c:\testfolder\test.json");
JsonTextReader reader = new JsonTextReader(file);
JObject jObject = (JObject)JToken.ReadFrom(reader);
int a = jObject ["Scenario"];
You can use this variable a which contains value 10 from the Json file.
I have a solution with two different projects. I use SyntaxWalker to process some stuff in ProjectA.Class1. However, ProjectA.Class1 has reference ProjectB.Class2.
Is there way to allow the syntax walker to traverse also through external classes? I can't even do it when both classes are in the same project but in different files (documents). It always goes through the same document. If both classes are in the same file then it works. If I extract them to separate ones, it doesn't...
I am working on a test coverage tool. A user click on the method in VS and then:
I use rewriter to add static variables to each branch.
I run the code so the static variables are set if branch was covered.
I wonder how should I configure a syntax walker\rewriter to recognize other classes in the same solution.
You're going to need access to the Symbol API. A simple rule of thumb I try to go by:
The Syntax API is for individual files
The Symbol API allows you to work with information that spans across files.
You've mentioned in the comments that you'd like to traverse methods and figure out some information about each method declaration. Here's some (naive) code that should get you started with the symbol API.
I've assumed you've got access to a Project that you're analyzing.
Project myProject;
public void ProcessMethod(MethodDeclarationSyntax method)
{
//Get the semantic model
var filePath = method.SyntaxTree.FilePath;
var containingDocument = myProject.Documents.Where(n => n.FilePath == filePath).Single();
var model = containingDocument.GetSemanticModelAsync().Result;
//...
//Do your processing on the current method here...
//...
//Process the invoked methods.
var invocations = method.DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach(var invocation in invocations)
{
var invokedSymbol = model.GetSymbolInfo(invocation).Symbol; //Might be null
var invokedSymbolSyntax = (MethodDeclarationSyntax)invokedSymbol.DeclaringSyntaxReferences.First().GetSyntax(); //Partial methods might be declared in multiple places
ProcessMethod(invokedSymbolSyntax);
}
}
Note:
This approach doesn't handle constructors, destructors, properties, expression-bodied members and any other members I've forgotten. But it should be enough to get you started and introduce you to the symbol API.
Recursion will bite you.
You won't process implementations of interfaces. You'll have to look into the SymbolFinder for that.
i am using assimp libary to load models to my ios app. but for some large model files loading times are too long for an mobil app.
considering the convert process time. i decided to convert my models by a tool before run time.
my main goal is writing this scene to file.
i have very basic c++ experience.
First i tried assimp::expoerter class.
i complied assimp libary with export settings on.
But when i try to use export method i am getting this error message.
No matching member function for call to 'Export'
method is there but i can't use it.
scene = (aiScene*) aiImportFile([[openPanel filename] cStringUsingEncoding:[NSString defaultCStringEncoding]], aiPostProccesFlags | aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_PreTransformVertices | 0 );
if (scene) {
NSString *pPath = [openPanel filename];
pPath =[NSString stringWithFormat:#"%#%#", pPath, #"_new"];
NSLog(#"New file Path : %#", pPath);
Assimp::Exporter *exporter = new Assimp::Exporter();
exportFormatDesc = exporter->GetExportFormatDescription(0);
exporter->Export(scene, exportFormatDesc->id, pPath);
const aiExportDataBlob *blob = exporter->ExportToBlob(scene, exportFormatDesc->id);
size_t blobSize = blob->size;
aiString blobName = blob->name;
}
then by reading Assimp::Exporter Class Reference gives me the idea of using aiExportDataBlob to create file.
ExportToBlob which returns a linked list of memory buffers (blob), each referring to one output file (in most cases there will be only one output file of course, but this extra complexity is needed since Assimp aims at supporting a wide range of file formats).
ExportToBlob is especially useful if you intend to work with the data in-memory.
const aiExportDataBlob *blob = exporter->ExportToBlob(scene, exportFormatDesc->id);
size_t blobSize = blob->size;
aiString blobName = blob->name;
But i have no idea to write this blob to a file.
Any advice or help appreciated.
You're passing NSString * where the function expects const char *. I'm not familiar with Objective-C, but I think you want [pPath UTF8String] to get pointer to a C-style character array from the NSString.
(Also, you're leaking the Exporter: C++ doesn't have garbage collection. I'm sure you don't want to create it with new but, if you do need to for some reason, remember to delete it when you're done).
I am writing an application that uses an ini file to store all status codes (errors, success codes, etc.) A very simple version is this:
[success]
000=Status code not found.
[error]
000=Error code not found.
001=Username/Password not found.
And my CF Component to work with that uses the following code:
component hint="Set of tools to interact with status codes."{
public function init(string codefile) any{
this.codefile = Arguments.codefile;
}
public function getCodeString(string type, string code) string{
var code = getProfileString(Variables.codefile, Arguments.type, Arguments.code);
return code;
}
}
What I assume happens when I call the getProfileString is that Railo opens the file, searches for the key and returns the value. So as my application grows and I have a lot more codes, I expect that this process will slow down. So is there a way that I can open the file in my init method and read it all into the variables scope, and call the getProfileString from there?
You can even parse your ini file in onApplicationStart and push the data into application scope like recommended for a XML file by #Sergii, if you want to stick with the .ini approach.
Do something like that:
var sections = getProfileSections(variables.codeFile);
var sectionEntries = [];
var indx = 0;
for (key in sections){
sectionEntries = listToArray(sections[key]);
application[key] = {};
for (indx=1; indx <= arraylen(sectionEntries); indx++){
application[key][sectionEntries[indx]] = getProfileString(variables.cfgFile,key,sectionEntries[indx]);
}
}
haven't tested this on Railo, but it should work on ColdFusion 9 at least
Because you are using Railo there's possibly easiest solution: put the file into the RAM filesystem.
So full path to the file will look like ram:///some/path/to/config.ini.
Obviously, you need to write the file into the RAM first, possibly on first request.
So slightly modified version of the component may look this way:
component hint="Set of tools to interact with status codes."{
public function init(string codefile, string.ramfile) any{
variables.codefile = arguments.codefile;
variables.ramfile = arguments.ramfile;
}
public function getCodeString(string type, string code) string{
if (NOT fileExists(variables.ramfile)) {
fileCopy(variables.codefile, variables.ramfile);
}
return getProfileString(variables.ramfile, arguments.type, arguments.code);
}
}
Please note that I've changed this.codefile to the variables.codefile in the init.
Any way, I'm also not sure ini file is the most handy and maintainable solution. You need to parse it each time any way, right? If you need a file config, use XML. Just parse it in onApplicationStart and push the data into the application scope.