How can I get the internal error message to log? - c++

I'm using perror:
perror("Error message:");
When the above is used it displays the message passed to the string followed by the actual error that occurred. This is a standard function, however I want to log this to a file, how to I get the actual error that goes with this so I can log it?

You can use the code below:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
FILE* filePtr;
filePtr = fopen (logFilePath, "a");
//...
//some code
//...
if(critical_part){
fprintf(filePtr, "errno :%s Error in critical part - line 123\n",strerror(errno));
}
}

Related

error occur when I call execvp to run java

I use chdir() to switch the directory, and then use execvp() to execute "java Main". I'm sure there is Main.class, but something went wrong. I want to know why.
#include <cstdio>
#include <unistd.h>
using namespace std;
int main(){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/keane/Judge/temp");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3];
array[0] = "java";
array[1] = "Main";
array[2] = NULL;
execvp("java", array);
return 0;
}
the error is could not find the main class , and I can run java Main in that directory.
What drives me crazy is that I can't use system("java Main"), and the error is that Error: Could not find or load main class Main, and it's just like this on my computer
update:
#include <unistd.h>
#include <cstdlib>
int main(){
chdir("/home/keane/Judge/temp");
system("pwd");
system("ls");
system("java Main");
return 0;
}
the output on console is:
/home/keane/Judge/temp
1.out 3.out 5.out Main.class stdout_spj.txt
2.out 4.out ce.txt Main.java
Error: Could not find or load the main class Main
my final solution is to reboot the computer and add -cp . to the java command.
althought I don't why is necessary.
thanks everyone!
This works as intended on my system, maybe you need to add -cp . to your java call.
EDIT: to elaborate: -cp (for classpath) tells java where to look for user provided .class files. This does not necessarily include the current working directory by default.
The execution of execvp() is non-blocking and takes ownership of the caller, that means that when it starts if the program ends too quickly you will never be able to see the result, to solve this I use fork(). The wait is just to avoid using sleep as I used at the begining. Its all in c.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char** argv){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3] = {"java", "Main", NULL};
if(fork() == 0) {
if(execvp("java", array) < 0) {
fprintf(stderr, "Error spawning command: %s\n", strerror(errno));
}
} else {
printf("Command spawned\n");
wait(NULL); // Wait to the forked process to end (avoid using sleep)
}
return 0;
}

VS2013 c++ connect mysql --- error in Libmysql.dll

main.cpp
#include "sqlConnection.h"
#include <iostream>
int main() {
sqlConnection *sqlC = new sqlConnection();
sqlC->ifSucceed();
}
sqlConnection.h
#include <Windows.h>
#include <stdio.h>
#include <winsock.h>
#include "mysql.h"
#include <iostream>
#pragma once
using namespace std;
class sqlConnection
{
public:
sqlConnection();
~sqlConnection();
void ifSucceed();
MYSQL mysql;
MYSQL_RES *result;
MYSQL_ROW row;
};
sqlConnection.cpp
#include "sqlConnection.h"
sqlConnection::sqlConnection()
{
mysql_init(&mysql);
mysql_real_connect(&mysql, "xxxxx", "xxxx", "xxxx", "librarySys", 7726, NULL, 0);
}
void sqlConnection::ifSucceed() {
char *sql = "select * from tb_bookcase";
mysql_query(&mysql, sql);
result = mysql_store_result(&mysql);
if ((row = mysql_fetch_row(result)) != NULL) {
cout << "succeed!" << endl;
} else {
cout << "faiiiiiiiiled" << endl;
}
}
sqlConnection::~sqlConnection() {
}
IF there is a libmysql.dll in source file error the message : There
are untreated exception:0x00007FFED00441E6 (libmysql.dll) (in the
librarySys.exe ) 0xC0000005: Access conflict happened when reading
0x0000000000000010.
And then I have to stop. VS give me choice, to change PDB, the binary file path and retry. But I do not know how to do it.
If I delete the libmysql.dll , the error message is:
The program can not be started for losing libmysql.dll in the
computer.Try to reinstall this program to solve this problem.
It's so confusing! I have tried many ways to connect. There are always error messages.
All mysql_* functions return a value that indicates success or failure. Your code disregards them. You ought to confirm whether calls were successful before proceeding to the next call. I surmise you actually failed to connect to the DB and your MYSQL is remains invalid.
Use your debugger. There's no point in coding in the dark. With your debugger you will quickly see whether your MYSQL object has been properly initialized.
Another thing:
sqlConnection *sqlC = new sqlConnection();
There is no reason for this to be heap allocated.

Pantheios write to extenal file

I looked around and I couldn't find the answer to how exactly to do this. I am trying to use Pantheios for logging and I want to write to an external file (otherwise whats the point). I am following one of the examples provided but It doesn't seem to be making the log file anywhere. Here is the code:
Edit: Also pantheios_be_file_setFilePath is returning -4 (PANTHEIOS_INIT_RC_UNSPECIFIED_FAILURE) so thats.....not helpful
#include "stdafx.h"
#include <pantheios/pantheios.hpp>
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.WindowsConsole.h>
#include <pantheios/implicit_link/be.file.h>
#include <pantheios/frontends/fe.simple.h>
#include <pantheios/backends/bec.file.h>
#include <pantheios/inserters/args.hpp>
PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("LogTest");
int _tmain(int argc, _TCHAR* argv[])
{
try
{
pantheios_be_file_setFilePath(PANTHEIOS_LITERAL_STRING("testlogforme.log"), PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);
pantheios::log(pantheios::debug, "Entering main(", pantheios::args(argc,argv, pantheios::args::arg0FileOnly), ")");
pantheios::log_DEBUG("debug yo");
pantheios::log_INFORMATIONAL("informational fyi");
pantheios::log_NOTICE("notice me!");
pantheios::log_WARNING("warning!!");
pantheios::log_ERROR("error omg");
pantheios::log_CRITICAL("critical!!!");
pantheios::log_ALERT("alert mang");
pantheios::log_EMERGENCY("EMERGENCY!!!!!");
pantheios_be_file_setFilePath(NULL, PANTHEIOS_BEID_ALL);
system("pause");
return EXIT_SUCCESS;
}
catch(std::bad_alloc&)
{
pantheios::log_ALERT("out of memory");
}
catch(std::exception& x)
{
pantheios::log_CRITICAL("Exception: ", x);
}
catch(...)
{
pantheios::puts(pantheios::emergency, "Unexpected unknown error");
}
return EXIT_FAILURE;
}
Maybe I'm not calling a method or maybe its not being saved to a good location?
It turns out that some of the examples out there for pantheios are incorrect. You DO need to call pantheios_init() even if you are in C++. Here Is the example I got to work after deleting all my code and implementing an example that works.
// Headers for main()
#include <pantheios/pantheios.hpp>
#include <pantheios/backends/bec.file.h>
// Headers for implicit linking
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.file.h>
PANTHEIOS_EXTERN_C const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "testLOL";
int main()
{
if(pantheios::pantheios_init() < 0)
{
return 1;
}
pantheios::log_NOTICE("log-1"); // save until log file set
pantheios_be_file_setFilePath("mylogfile.log"); // sets log file; write "log-1" stmt
pantheios::log_NOTICE("log-2"); // write "log-2" stmt
pantheios_be_file_setFilePath(NULL); // close "mylogfile"
pantheios::log_NOTICE("log-3"); // save until log file set
pantheios_be_file_setFilePath("mylogfile2.log"); // sets log file; write "log-3" stmt
pantheios::log_NOTICE("log-4"); // write "log-4" stmt
//system("pause");
return 0;
} // closes "mylogfile2" during program closedown
I found the example on a different post on stack overflow but like I said, the built in examples do not work.

Redirection in Linux with dup2() and create() inside a loop

I am running the code below and I cannot redirect to a file. The file is made, but nothing is put into it. If I remove the last dup2(saveout,1) statement, I can create and write into the file, but I cannot get back to the terminal, which is important. As soon as I put the dup2(saveout,1) back in my code, the redirection stops working, but I can get back to the terminal. I do not understand why this is happening. I would like to redirect and go back into the terminal.
main.cpp
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
using namespace std;
void printmessage() {
printf("this is the message\n");
}
int main(int argc, char** argv) {
int saveout;
int fd;
saveout = dup(1);
for (int i = 0; i < 10; i++) {
fd = creat("/home/carl/example.txt",O_CREAT|O_APPEND);
dup2(fd, 1);
close(fd);
printf("Testing the message");
printmessage();
dup2(saveout,1);
close(saveout);
}
return 0;
}
This is a file rights issue, you should read the man pages of the functions you are using.
creat() takes as first argument the filename, and as second the file creation rights, not its opening mode.
The creat() functions is a simple open() call, with some particular flags, so that you'll just have to set up the rights.
if you want to open your file, and create it if he doesn't exists, use
open(filename, O_CREAT | O_RDWR | O_APPEND, 0600) for example, or
creat(filename, 0600),
which is mostly its equivalent, but you wont be able to append text, as "creat() is equivalent to open() with flags equal to O_CREAT | O_WRONLY | O_TRUNC"
The second dup2(saveout,1); will fail because you closed saveout.
printf is buffered by default. (line-by-line for output to a tty, perhaps differently for output to something else). Before both your calls to dup2(..., 1), you should flush with fflush:
fflush(stdout);

reading linux inode bitmap

I'm going to fetch linux inode bitmaps with c++. I've use this code to fetch super block first:
#include <cstdlib>
#include <linux/ext2_fs.h>
#include <linux/fs.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <fcntl.h>
#include <linux/fs.h>
using namespace std;
/*
*
*/
int main() {
int fd;
char boot[1024];
struct ext2_super_block super_block;
fd = open("/dev/sda1", O_RDONLY);
/* Reads the boot section and the superblock */
read(fd, boot, 1024);
read(fd, &super_block, sizeof (struct ext2_super_block));
/* Prints the Magic Number */
printf("%x\n", super_block.s_magic);
close(fd);
return 0;
}
but every time i run it , i get a error :
In file included from main.cpp:2:0:
/usr/include/linux/ext2_fs.h:181:18: error: ‘S_ISDIR’ was not declared in this scope
/usr/include/linux/ext2_fs.h:183:23: error: ‘S_ISREG’ was not declared in this scope
I couldn't find any good example or tutorial for this.is there anybody to help me?
EDIT :
I've include <linux/stat.h> but still get same error.
#grep -rw S_ISREG /usr/src/linux/include
/usr/src/linux/include/linux/fs.h: if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
/usr/src/linux/include/linux/fs.h.~1~: if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
/usr/src/linux/include/linux/stat.h:#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
So you should find stat.h in yours kernel source tree and include it.
The Linux source code "stat.h" is not the same file as that comes with the C-library. They just happen to have the same name. You will need to set your include path to find the correct stat.h (you may need BOTH, depending on what you are trying to do).