How do I write je_malloc_stats_print() result into a file instead of stderr?
Now what I can do is only je_malloc_stats_print(NULL, NULL, NULL) to stderr;
The first parameter is a callback function pointer, and the second is for passing data to the callback. You can use these parameters to implement writing to a file. From the jemalloc manual page:
void malloc_stats_print(
void (*write_cb) (void *, const char *) ,
void *cbopaque,
const char *opts);
/*Actually The default function, it uses inside print the stat data on STDERR output stream. To print it to a file, It needs to provide a callback function, which it will call to print the buf stream into. */
int g_fd;
void print_my_jemalloc_data(void *opaque, const char *buf);
int main()
{
int fd = open("heap_stats.out,O_CREAT|O_WRONLY,0666);
g_fd = fd;
malloc_stats_print(print_my_jemalloc_data,NULL,NULL);
/*Passing my callback routine which jemalloc will use internally to print data into*/
return 0;
}
void print_my_jemalloc_data(void *opaque,const char *buf)
{
write(g_fd,buf,strlen(buf));`enter code here`
}
You may replace your function, with same signature, and replace at malloc_stat_print API, first parameter call back function. It will be passed on buf, which you may print in your defined file stream, which you have opened before..
Related
I am using a TCP server to send a char array. The function send() takes a char *, but, before that, it has to listen and accept a connection. Given that, I want to send the most recent data when an incoming connection is accepted. Previously, I used two threads. One updated the value in the buffer, the other simply waited for connections, then sent data.
I understand that there can be problems with not locking a mutex, but aside from that, would this same scheme work if I passed the char * to a send function, rather than updating it as a global variable?
Some code to demonstrate:
#include <pthread.h>
char buf[BUFLEN];
void *updateBuffer(void *arg) {
while(true) {
getNewData(buf);
}
}
void *sendData(void *arg) {
//Setup socket
while(true) {
newfd = accept(sockfd, (struct sockaddr *)&their_addr, &size);
send(newfd, buf, BUFLEN, 0);
close(newfd);
}
}
This would send the updated values whenever a new connection was established.
I want to try this:
#include <pthread.h>
char buf[BUFLEN];
void *updateBuffer(void *arg) {
while(true) {
getNewData(buf);
}
}
void *sendData(void *arg) {
TCPServer tcpServer;
while(true) {
tcpServer.send(buf);
}
}
Where the function tcpServer.send(char *) is basically the same as sendData() above.
The reason for doing this is so that I can make the TCP server into a class, since I'll need to use the same code elsewhere.
From my understanding, since I am passing the pointer, it's basically the same as when I just call send(), since I also pass a pointer there. The value will continue to update, but the address won't change, so it should work. Please let me know if that is correct. I'm also open to new ways of doing this (without mutex locks, preferably).
Yes, that is the way most of us do a send, pass a pointer to a buffer either void * or char *
I would coded like this:
int sendData(const char * buffer, const int length)
{
Socket newfd;
Int NumOfConnects=0;
while ((newfd=accept(sockfd, (struct sockaddr *)&their_addr, &size)) > 0)
{
// It would be necessary here to lock the buffer with a Mutex
send(newfd, buffer, length, 0);
// Release the Mutex
close(newfd);
NumOfConnects++;
}
// there is an error in the accept
// this could be OK,
// if the main thread has closed the sockfd socket indicating us to quit.
// returns the number of transfers we have done.
return NumOfConnects;
}
One thing to consider about using a pointer to a buffer which is modify in another thread; Could it be that in the middle of a send the buffer changes and the data sent is not accurate.
But that situation you've already noticed as well. Using a Mutex is suggested as you indicated.
I am working in visual c++, usually I do it on .NET, because I need a method which is available only on this language. What I want to do is obtain the frames per second of a video file. The best I could make was creating a project with this main() method, in which (after Debug) I could see the result is saving fine in the res variable.
void main()
{
// initialize the COM library
CoInitialize(NULL);
// get a property store for the video file
IPropertyStore* store = NULL;
SHGetPropertyStoreFromParsingName(L"C:\\Users\\Public\\Videos\\Sample Videos\\Wildlife.wmv",
NULL, GPS_READWRITE, __uuidof(IPropertyStore), (void**)&store);
// get the frame rate
PROPVARIANT variant;
store->GetValue(PKEY_Video_FrameRate, &variant);
int res = variant.intVal;
store->Release();
}
Now, I want to create this method generic, in order to obtain the frameRate of any video. For example, if the method's name is frameRate:
char* path = "C:\\Users\\Public\\Videos\\Sample Videos\\Wildlife.wmv";
int fps = frameRate(path);
Thanks
Does this not work?
int getFrameRate(std::wstring path)
{
// initialize the COM library
CoInitialize(NULL);
// get a property store for the video file
IPropertyStore* store = NULL;
SHGetPropertyStoreFromParsingName(path.c_str(),
NULL, GPS_READWRITE, __uuidof(IPropertyStore), (void**)&store);
// get the frame rate
PROPVARIANT variant;
store->GetValue(PKEY_Video_FrameRate, &variant);
int res = variant.intVal;
store->Release();
return res;
}
The assumption here is that SHGetPropertyStoreFromParsingName takes a string as its first parameter. In C++ I recommend staying away from char*, std::string is preferable in almost all situations. The only difficulty I see is making sure path is the correct type.
If you don't want to recompile your code for every video path, then you can read the path from the program parameters. To do that, modify you main() as follows:
int main(int argc, char* argv[])
{
if (argc != 2)
{
std::cout << "You have to specify the video path!" << std::endl;
return 1;
}
const char* path = arg[1];
// Rest of the program logic
return 0;
}
You can pass more than one parameter, if you want to. Note that there is always at least 1 argument (arg[0] is the program name). For further reading on the topic go here.
In my project, I use to load textures by specifying its file name. Now, I made this function const char* app_dir(std::string fileToAppend); that returns the mains argv[0] and change the application name by the fileToAppend. Since I cannot make the string manipulation easy with a char*, I use the std::string. My texture loader takes a const char* for file name so need to switch back to c_str(), now it generates a sequence of ASCII symbol characters (bug). I already fix the problem by changing the return type of the app_dir() to std::string. But why is that happening?
EDIT
sample code:
//in main I did this
extern std::string app_filepath;
int main(int argc, char** arv) {
app_filepath = argv[0];
//...
}
//on other file
std::string app_filepath;
void remove_exe_name() {
//process the app_filepath to remove the exe name
}
const char* app_dir(std::string fileToAppend) {
string str_app_fp = app_filepath;
return str_app_fp.append(fileToAppend).c_str();
//this is the function the generates the bug
}
I already have the functioning one by changing its return type to std::string as I said earlier.
A big no no :) returning pointer to local objects
return str_app_fp.append(fileToAppend).c_str();
Change your function to
std::string app_dir(const std::string& fileToAppend) {
string str_app_fp = app_filepath + fileToAppend;
return str_app_fp;
}
And on the return value use c_str()
When you using function const char* app_dir(std::string fileToAppend); you get pointer to the memory that allocated on the stack and already deleted when the function ends.
(5) 0x1c6235e1 in ProxyClass::Method_C (this=0xb3a0c8, sendFilePath=...) at ./src/ProxyClass.cpp:112
(6) 0x2c8706c1 in Class1::Method_B (this=0x1fc5a1, profile=0x2c8f2340 "fileProfile1", filePathAndFileName=0x0) at ./src/Class1.cpp:860
(7) 0x2c4ae4c0 in Method_B (profile=0x42c <Address 0x42c out of bounds>, filePathAndFileName=0x0) at ./src/Class1_interface.cpp:310
(8) 0x2c1e5c3c in Method_A (profile=0x42c <Address 0x42c out of bounds>, filename=0x2c601c1c "/tmp/temporaryfile.tmp") at ./src/file.cpp:890
I have the above core file snippet that is debugged with gnu gdb. This core file is created on an embedded system running Linux. There is no manipulation to the variables within the function calls...
My questions are below:
How come the profile looks like Address 0x42c out of bounds on 8th frame and while there is no change to profile until the 9th frame how can that become something meaningful("fileSchema")?
My embedded system crashes because the filename(char *) equals to 0x2c601c1c and the path is printed like this on the 8 th frame "/tmp/temporaryfile.tmp". However, again without manipulation to filename variable, Method_A calls Method_B but the char pointer suddenly becomes null on 7th frame (filePathAndFileName=0x0). Then, my system crashes. How can that char * pointer transforms to NULL with manipulation?
The crash occurs on the 6th frame because in Class1::Method_B the following line is executed "std::string filePath( filePathAndFileName);". A null char pointer is being tried to get initialized to a string and I think it causes the crash and the Abort signal (Program terminated with signal 6, Aborted.). How can I avoid that char * to become null within the pass of that variable between the methods? Any idea why it becomes null?
static TUint16 Method_A(char* profile, char* filename)
{
TUint16 a; //after the call of Method_B,the other part of this method being processed but anyway the code never passes to there because of th crash..
Method_B(profile,filename);
...
...
...
return a;
}
unsigned char Method_B_interface(char* profile, char* filePathAndFileName)
{
unsigned char returnValue = 0;
if ( callbackObject->Method_B( profile, filePathAndFileName ) )
{
returnValue = 1;
}
return returnValue;
}
bool Class1::Method_B(char* profile, char* filePathAndFileName)
{
bool returnValue = true;
std::string filePathString( filePathAndFileName );
std::string profileString( profile );
if(profileString == "fileProfile1")
{
if(xClass != NULL)
{
returnValue = xClass->Method_C(filePathString);
}
}
...
...
...
return returnValue;
}
bool ProxyClass::Method_C(const std::string& exportFilePathAndFileName)
{
bool returnValue;
std::string message = "dummy", parameters;
Serializer::serialize( message, exportFilePathAndFileName );
proxyRequest->synchCall( message, parameters );
getResponse(parameters);
Serializer::deserialize( parameters, returnValue );
return returnValue;
}
//Block.h
#pragma once
class Block
{
public:
CRect pos;
int num;
public:
Block(void);
~Block(void);
};
//view class
public:
Block currentState[5]; // stores the current state of the blocks
void CpuzzleView::OnDraw(CDC* pDC)
{
CpuzzleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//draw the 4 blocks and put text into them
for(int i=0;i<4;i++)
{
pDC->Rectangle(currentState[i].pos);
// i'm getting an error for this line:
pDC->TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
}
pDC->TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
The error says that no instance of overloaded function CDC::TextOutW() matches the argument list . But the prototype for the function is:
CDC::TextOutW(int x, int y, const CString &str )
all i've done is that instead of the 2 points i've directly given the point object returned by CenterPoint() ... shouldn't it work?
That's because you didn't supplied arguments list correctly. Please read compiler error message carefully, it's usually helps to solve the problem.
TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
In this call you passed CPoint object and int. This is not correct, you need to pass int, int and CString (or const char* and int length).
To fix this you shall do something like this:
CString strState;
strState.Format("%d", currentState[i].num); // Or use atoi()/wtoi() functions
TextOut(currentState[i].pos.CenterPoint().x, currentState[i].pos.CenterPoint().x, strState);