By building dmalloc lib with following setting in conf.h file
#define HAVE_VPRINTF 0
#define HAVE_SNPRINTF 0
#define HAVE_VSNPRINTF 0
and run my code after linking , log file content have unformatting address info to function names and line numbers.
Unformatted log o/p is given below.
Venkatesh:~/Dmalloc/dmalloc-5.5.2$ cat logfile
%ld: %lu: Dmalloc version '%s' from '%s'
%ld: %lu: flags = %#x, logfile '%s'
%ld: %lu: interval = %lu, addr = %#lx, seen # = %ld, limit = %ld
%ld: %lu: starting time = %s
%ld: %lu: process pid = %ld
%ld: %lu: error details: %s
%ld: %lu: pointer '%#lx' from '%s' prev access '%s'
%ld: %lu: dump of proper fence-top bytes: '%.*s'
%ld: %lu: dump of '%#lx'%+d: '%.*s'
%ld: %lu: next pointer '%#lx' (size %u) may have run under from '%s'
%ld: %lu: ERROR: %s: %s (err %d)
If I define HAVE_VSNPRINTF to 1, then I log file has only dmalloc log header, no information about errors as given below.
Venkatesh:~/Dmalloc/dmalloc-5.5.2$ cat logfile
1450864250: 5: Dmalloc version '5.5.2' from 'http://dmalloc.com/'
1450864250: 11: flags = 0x4f4e503, logfile 'logfile'
1450864250: 17: interval = 100, addr = 0, seen # = 0, limit = 0
1450864250: 25: starting time = 1450864250
1450864250: 31: process pid = 10270
My test code is as below.
#include <stdio.h>
#include <stdlib.h>
#ifdef DMALLOC
#include "dmalloc.h"
#endif
int main ()
{
char *p;
p = malloc (50);
p[51] = 'c'; //Writing character beyond allocated range
return 0;
}
Dmalloc optins I am using is :
DMALLOC_OPTIONS=debug=0x4f4ed03,inter=100,log=logfile
Related
I am trying to implement a basic example to record a few seconds of audio in FreeBSD, which uses a modified OSS version.
Following the sample files included in the FreeBSD source code and the OSS programming guide I have prepared the following sample program:
#include <sys/soundcard.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define MAX_FILENAME_LENGTH 1024
#define MAX_SECONDS_TO_RECORD 3600 // UP TO 1 HOUR RECORDING
#define MAX_BUFFER_LENGTH 8000*MAX_SECONDS_TO_RECORD
int main(int argc, char *argv[]) {
unsigned char buffer[MAX_BUFFER_LENGTH]; // BUFFER TO STORE AUDIO
char dspfile[MAX_FILENAME_LENGTH]; // /dev/dsp FILENAME
int fd; // /dev/dsp FILE DESCRIPTOR
unsigned int seconds_to_record; // NUMBER OF SECONDS TO RECORD
unsigned long samples_to_record; // NUMBER OF SAMPLES TO RECORD
unsigned long samples_recorded; // NUMBER OF SAMPLES RECORDED
int format; // FORMAT
int channels; // CHANNELS (1=MONO 2=STEREO)
int sampling_rate; // SAMPLING RATE
int error; // AUX VARIABLE ERROR
// STEP 1: READ /dev/dsp PARAMETER
if(argc!=3) {
fprintf(stderr, "ERROR: Incorrect number of arguments.\n");
fprintf(stderr, "USAGE: %s /dev/dsp seconds\n", argv[0]);
exit(1);
} else if( strlen(argv[1]) >= MAX_FILENAME_LENGTH ) {
fprintf(stderr, "ERROR: /dev/dsp filename parameter too long. Maximum size is %d.\n", MAX_FILENAME_LENGTH);
exit(1);
} else {
strncpy(dspfile, argv[1], MAX_FILENAME_LENGTH);
sscanf(argv[2], "%u", &seconds_to_record);
}
if( seconds_to_record >= MAX_SECONDS_TO_RECORD) {
fprintf(stderr, "ERROR: Too many seconds requested. Maximum recording time is %u.\n", MAX_SECONDS_TO_RECORD);
exit(1);
}
// STEP 2: OPEN FILE
fd = open(dspfile, O_RDWR);
if(fd==-1) {
fprintf(stderr, "ERROR: Can not open /dev/dsp file %s. Error code %d %s\n", dspfile, errno, strerror(errno));
exit(1);
}
// STEP 3: CONFIGURE MONO, 8 BITS UNSIGNED SAMPLES, 8KHz SAMPLING RATE
channels = 1;
error = ioctl(fd, SNDCTL_DSP_CHANNELS, &channels);
if(error==-1) {
fprintf(stderr, "ERROR: Can not configure 1 channel. Error code %d %s\n", errno, strerror(errno));
exit(-1);
}
format = AFMT_U8;
error = ioctl(fd, SNDCTL_DSP_SETFMT, &format);
if(error==-1) {
fprintf(stderr, "ERROR: Can not configure audio format. Error code %d %s\n", errno, strerror(errno));
exit(-1);
}
sampling_rate = 8000;
error = ioctl(fd, SNDCTL_DSP_SPEED, &sampling_rate);
if(error==-1) {
fprintf(stderr, "ERROR: Can not configure sampling rate. Error code %d %s\n", errno, strerror(errno));
exit(-1);
}
// STEP 4: RECORD N SAMPLES CORRESPONDING TO THE REQUESTED NUMBER OF SECONDS TO RECORD
samples_to_record = seconds_to_record * 8000;
samples_recorded = 0;
while(samples_to_record > 0) {
ssize_t samples_read = read(fd, buffer + samples_recorded, samples_to_record);
samples_to_record -= (unsigned long)samples_read;
samples_recorded += (unsigned long)samples_read;
write(STDOUT_FILENO, buffer + samples_recorded, samples_read);
}
// STEP 5: CLOSE FILE
if(close(fd)==-1) {
fprintf(stderr, "ERROR: Can not close /dev/dsp file %s. Error code %d %s\n", dspfile, errno, strerror(errno));
exit(1);
}
// DISENGAGE
return(0);
}
But I get a 24000 bytes empty file.
Doing the following works:
cat /dev/dsp > test.raw
cat test.raw > /dev/dsp
So it seems that I am missing something wrong or I am missing one step.
_utime with NULL as a time parameter is updating given file's modification time but when I set time to other value as shown in the example it does not affect and it is giving error as "Invalid argument", please let me know how to use it.
Following is the sample program I want to make it work.
#include <stdio.h>
#include <errno.h>
#include <warning.h>>
#include <time.h>
#include <sys/utime.h>
#include <sys/types.h>
void main (void) {
struct _utimbuf updatedtime;
char *file_path = "file_name.txt";
int ret;
// here _utime update the modification time to the current time.
ret = _utime(file_path, NULL);
if(ret == -1)
printf("ret: %d \t GetLastError: %d \t strerror: %s\n", ret, errno, strerror(errno));
updatedtime.modtime = time(0) - 100000;
// here, _utime has no effect on the time.
ret = _utime(file_path, &updatedtime);
if(ret == -1)
printf("ret: %d \t GetLastError: %d \t strerror: %s\n", ret, errno, strerror(errno));
}
As referred in example for changing the file modification time with _utime() we need to give valid values in both of the fields of the structure _utimbuf, In the example given in the question, It was only changing the modification time and access time was an invalid value.
The following code is working as expected.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <sys/utime.h>
#include <sys/types.h>
void main (void) {
struct _utimbuf updatedtime;
char *file_path = "C:\\Users\\test_dir\\file_name.txt";
char sys_cmd[100];
int ret;
sprintf(sys_cmd, "dir %s", file_path);
ret = _utime(file_path, NULL);
if(ret == -1)
printf("GetLastError: %d \t strerror: %s\n", errno, strerror(errno));
updatedtime.modtime = time(0) - 100000;
updatedtime.actime = time(0);
system(sys_cmd);
ret = _utime(file_path, &updatedtime);
if(ret == -1)
printf("GetLastError: %d \t strerror: %s\n", errno, strerror(errno));
system(sys_cmd);
}
output:
Volume in drive C has no label.
Volume Serial Number is 10FD-414D
Directory of C:\Users\test_dir
09-08-2020 15:24 158 file_name.txt
1 File(s) 158 bytes
0 Dir(s) 59,508,273,152 bytes free
Volume in drive C has no label.
Volume Serial Number is 10FD-414D
Directory of C:\Users\test_dir
10-08-2020 19:11 158 file_name.txt
1 File(s) 158 bytes
0 Dir(s) 59,508,273,152 bytes free
I want to read out linux kernel statistics of a single thread using netlink socket and taskstats.
I could get taskstats to work using a python wrapper (https://github.com/facebook/gnlpy) but I want to do a C implementation.
After setting up the socket, the message parameters and sending, the receiving
nl_recvmsgs_default(sock)
always returns an error code -7 ("Invalid input data or parameter") or -12 ("Object not found") depending on how I create the message to send.
I checked all method invocations before nl_recvmsgs_default(sock) but dont get any error back. I guess I am missing a part in setting up the message or socket, but dont know what part it is.
#include <stdlib.h>
#include <unistd.h>
#include <linux/taskstats.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
int callback_message(struct nl_msg *, void *);
int main(int argc, char ** argv) {
struct nl_sock * sock;
struct nl_msg * msg;
int family;
sock = nl_socket_alloc();
// Connect to generic netlink socket on kernel side
genl_connect(sock);
// get the id for the TASKSTATS generic family
family = genl_ctrl_resolve(sock, "TASKSTATS");
// Allocate a new netlink message and inherit netlink message header.
msg = nlmsg_alloc();
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, 0, TASKSTATS_CMD_GET, TASKSTATS_VERSION))
//error code: -7 NLE_INVAL "Invalid input data or parameter",
nla_put_string(msg, TASKSTATS_CMD_ATTR_REGISTER_CPUMASK, "0");
//error code: -12 NLE_OBJ_NOTFOUND "Obj not found"
//nla_put_string(msg, TASKSTATS_CMD_ATTR_PID, "583");
nl_send_auto(sock, msg);
nlmsg_free(msg);
// specify a callback for inbound messages
nl_socket_modify_cb(sock, NL_CB_MSG_IN, NL_CB_CUSTOM, callback_message, NULL);
// gives error code -7 or -12 depending on the two nla_put_string alternatives above
printf("recv code (0 = success): %d", nl_recvmsgs_default(sock));
}
int callback_message(struct nl_msg * nlmsg, void * arg) {
struct nlmsghdr * nlhdr;
struct nlattr * nlattrs[TASKSTATS_TYPE_MAX + 1];
struct nlattr * nlattr;
struct taskstats * stats;
int rem;
nlhdr = nlmsg_hdr(nlmsg);
int answer;
if ((answer = genlmsg_parse(nlhdr, 0, nlattrs, TASKSTATS_TYPE_MAX, NULL))
< 0) {
printf("error parsing msg\n");
}
if ((nlattr = nlattrs[TASKSTATS_TYPE_AGGR_TGID]) || (nlattr =
nlattrs[TASKSTATS_TYPE_AGGR_PID]) || (nlattr =
nlattrs[TASKSTATS_TYPE_NULL])) {
stats = nla_data(nla_next(nla_data(nlattr), &rem));
printf("---\n");
printf("pid: %u\n", stats->ac_pid);
printf("command: %s\n", stats->ac_comm);
printf("status: %u\n", stats->ac_exitcode);
printf("time:\n");
printf(" start: %u\n", stats->ac_btime);
printf(" elapsed: %llu\n", stats->ac_etime);
printf(" user: %llu\n", stats->ac_utime);
printf(" system: %llu\n", stats->ac_stime);
printf("memory:\n");
printf(" bytetime:\n");
printf(" rss: %llu\n", stats->coremem);
printf(" vsz: %llu\n", stats->virtmem);
printf(" peak:\n");
printf(" rss: %llu\n", stats->hiwater_rss);
printf(" vsz: %llu\n", stats->hiwater_vm);
printf("io:\n");
printf(" bytes:\n");
printf(" read: %llu\n", stats->read_char);
printf(" write: %llu\n", stats->write_char);
printf(" syscalls:\n");
printf(" read: %llu\n", stats->read_syscalls);
printf(" write: %llu\n", stats->write_syscalls);
} else {
printf("unknown attribute format received\n");
}
return 0;
}
The code you provided works fine for me, except for a syntax error in line 26. Make sure you are running the program as root. Note that you are creating a listener for exiting tasks, yet reading a single message, which is, as far as I understand, an ACK. Reading from the socket in a while(1) loop shows parsed messages whenever a task exits on CPU 0.
EDIT: In the case where you are getting stats for a single PID, you should use nla_put_u32 instead:
nla_put_u32(msg, TASKSTATS_CMD_ATTR_PID, 583);
where 583 is an existing process id.
I'm learning ALSA programming by this article and I've tried to compile the following example:
/*
This example opens the default PCM device, sets
some parameters, and then displays the value
of most of the hardware parameters. It does not
perform any sound playback or recording.
*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
/* All of the ALSA library API is defined
* in this header */
#include <alsa/asoundlib.h>
int main() {
int rc;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val, val2;
int dir;
snd_pcm_uframes_t frames;
/* Open PCM device for playback. */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
fprintf(stderr,
"unable to open pcm device: %s\n",
snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(¶ms);
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate (CD quality) */
val = 44100;
snd_pcm_hw_params_set_rate_near(handle,
params, &val, &dir);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
fprintf(stderr,
"unable to set hw parameters: %s\n",
snd_strerror(rc));
exit(1);
}
/* Display information about the PCM interface */
printf("PCM handle name = '%s'\n",
snd_pcm_name(handle));
printf("PCM state = %s\n",
snd_pcm_state_name(snd_pcm_state(handle)));
snd_pcm_hw_params_get_access(params,
(snd_pcm_access_t *) &val);
printf("access type = %s\n",
snd_pcm_access_name((snd_pcm_access_t)val));
snd_pcm_hw_params_get_format(params, (snd_pcm_format_t *) &val);
printf("format = '%s' (%s)\n",
snd_pcm_format_name((snd_pcm_format_t)val),
snd_pcm_format_description(
(snd_pcm_format_t)val));
snd_pcm_hw_params_get_subformat(params,
(snd_pcm_subformat_t *)&val);
printf("subformat = '%s' (%s)\n",
snd_pcm_subformat_name((snd_pcm_subformat_t)val),
snd_pcm_subformat_description(
(snd_pcm_subformat_t)val));
snd_pcm_hw_params_get_channels(params, &val);
printf("channels = %d\n", val);
snd_pcm_hw_params_get_rate(params, &val, &dir);
printf("rate = %d bps\n", val);
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
printf("period time = %d us\n", val);
snd_pcm_hw_params_get_period_size(params,
&frames, &dir);
printf("period size = %d frames\n", (int)frames);
snd_pcm_hw_params_get_buffer_time(params,
&val, &dir);
printf("buffer time = %d us\n", val);
snd_pcm_hw_params_get_buffer_size(params,
(snd_pcm_uframes_t *) &val);
printf("buffer size = %d frames\n", val);
snd_pcm_hw_params_get_periods(params, &val, &dir);
printf("periods per buffer = %d frames\n", val);
snd_pcm_hw_params_get_rate_numden(params,
&val, &val2);
printf("exact rate = %d/%d bps\n", val, val2);
val = snd_pcm_hw_params_get_sbits(params);
printf("significant bits = %d\n", val);
snd_pcm_hw_params_get_tick_time(params,
&val, &dir);
printf("tick time = %d us\n", val);
val = snd_pcm_hw_params_is_batch(params);
printf("is batch = %d\n", val);
val = snd_pcm_hw_params_is_block_transfer(params);
printf("is block transfer = %d\n", val);
val = snd_pcm_hw_params_is_double(params);
printf("is double = %d\n", val);
val = snd_pcm_hw_params_is_half_duplex(params);
printf("is half duplex = %d\n", val);
val = snd_pcm_hw_params_is_joint_duplex(params);
printf("is joint duplex = %d\n", val);
val = snd_pcm_hw_params_can_overrange(params);
printf("can overrange = %d\n", val);
val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
printf("can mmap = %d\n", val);
val = snd_pcm_hw_params_can_pause(params);
printf("can pause = %d\n", val);
val = snd_pcm_hw_params_can_resume(params);
printf("can resume = %d\n", val);
val = snd_pcm_hw_params_can_sync_start(params);
printf("can sync start = %d\n", val);
snd_pcm_close(handle);
return 0;
}
The problem is that if I compile it with
gcc test.c -std=c99 -lasound
I get the following:
test.c: In function ‘main’:
test.c:36:3: warning: implicit declaration of function ‘alloca’ [-Wimplicit-function-declaration]
snd_pcm_hw_params_alloca(¶ms);
^
But this warning does not appear if I don't use
-std=c99
Why do I even get this warning?
Why there is no such problem with the standard C version?
According to man alloca you should add alloca.h to your includes when you are using alloca():
#include <alloca.h>
This is not usual function, because it should directly modify stack of the function from which it is called. It is handled specially in the compiler, for example in gcc (as described in the man)
Notes on the GNU version
Normally, gcc(1) translates calls to alloca() with inlined code.
This is not done when either the -ansi, -std=c89, -std=c99, or the
-std=c11 option is given and the header <alloca.h> is not included.
Otherwise, (without an -ansi or -std=c* option) the glibc version of
<stdlib.h> includes <alloca.h> and that contains the lines...
You are using alloca because snd_pcm_info_alloca is defined as macro with alloca (thank you, Matt McNabb)
#define snd_pcm_info_alloca(ptr) do { assert(ptr); *ptr = (snd_pcm_info_t *) alloca(snd_pcm_info_sizeof()); memset(*ptr, 0, snd_pcm_info_sizeof()); } while (0)
Incomplete ALSA doc about snd_pcm_info_alloca says
snd_pcm_hw_params_alloca(ptr)
allocate an invalid snd_pcm_hw_params_t using standard alloca
but the alloca is not standard; when you use it you should include alloca.h
I think that example in http://www.linuxjournal.com/article/6735?page=0,1 is incorrect; and good examples like http://webpages.lss.supelec.fr/perso/kowalski/?download=playback.c or https://gitorious.org/alsa/alsa-tools/source/f768eb0ff4124ac7e795cee09acb797fd01b63f1:ac3dec/output.c have #include <alloca.h>.
This snd_pcm_hw_params_alloca macro should be used with caution, incorrect usage may lead to use after free errors: http://mailman.alsa-project.org/pipermail/alsa-devel/2008-March/006700.html
I want to change a directory into a file, I did some research. In Linux, inode structure stores the metadata about the file and directory. I want to change the file protection mode from Directory to file,
Print some general file info
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
struct stat file_stats;
if(argc != 2)
fprintf(stderr, "Usage: fstat FILE...\n"), exit(EXIT_FAILURE);
if((stat(argv[1], &file_stats)) == -1) {
perror("fstat");
return 1;
}
printf("filename: %s\n", argv[1]);
printf(" device: %lld\n", file_stats.st_dev);
printf(" inode: %ld\n", file_stats.st_ino);
printf(" protection: %o\n", file_stats.st_mode);
printf(" number of hard links: %d\n", file_stats.st_nlink);
printf(" user ID of owner: %d\n", file_stats.st_uid);
printf(" group ID of owner: %d\n", file_stats.st_gid);
printf(" device type (if inode device): %lld\n",file_stats.st_rdev);
printf(" total size, in bytes: %ld\n", file_stats.st_size);
printf(" blocksize for filesystem I/O: %ld\n", file_stats.st_blksize);
printf(" number of blocks allocated: %ld\n", file_stats.st_blocks);
printf(" time of last access: %ld : %s", file_stats.st_atime, ctime(&file_stats.st_atime));
printf(" time of last modification: %ld : %s", file_stats.st_mtime, ctime(&file_stats.st_mtime));
printf(" time of last change: %ld : %s", file_stats.st_ctime, ctime(&file_stats.st_ctime));
return 0;
}
Is there any way to change the directory into a file?? How to modify inode structure by C program?
To open any file, you have to use open system call. But currently open system call doesn't allow anyone to open a directory for writing. In case you call open with a directory for writing, it will return error (-1) and set errno to EISDIR.
Still you want to do it, you have to re-implement the open system call of Linux filesystem driver.