I want to understand how does memory leak checkers identify if a free has been called for a given malloc.
malloc can easily be identified by brk system calls, so if i am writing a profiler and do a single stepping on a process which breaks at system calls i can easily understand that malloc has been done.
How can i find if a free has been called for this malloc?
Below is the output from strace. This code has free, how can we tell if free was invoked by checking this strace -
read(0, "13608\n", 4096) = 6
brk(0) = 0x8cc6000
brk(0x8ce7000) = 0x8ce7000
write(1, "File name - /proc/13608/maps\n", 29) = 29
open("/proc/13608/maps", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x55559000
read(3, "00349000-00363000 r-xp 00000000 "..., 4096) = 1046
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4a8\n", 14) = 14
write(1, "Buffer read - 00349000-00363000 "..., 102) = 102
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4aa\n", 14) = 14
write(1, "Buffer read - 00367000-004a6000 "..., 104) = 104
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4bd\n", 14) = 14
write(1, "Buffer read - 08048000-08049000 "..., 123) = 123
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f49a\n", 14) = 14
write(1, "ptr2-ffd1f4a1\n", 14) = 14
write(1, "Buffer read - ffad8000-ffaf1000 "..., 95) = 95
write(1, "\n", 1) = 1
write(1, "ptr1-ffd1f479\n", 14) = 14
write(1, "ptr2-ffd1f479\n", 14) = 14
write(1, "Buffer read - ffffe000-fffff000 "..., 55) = 55
write(1, "\n", 1) = 1
read(3, "", 4096) = 0
close(3) = 0
munmap(0x55559000, 4096) = 0
write(1, "Starting Address - 00349000\n", 28) = 28
write(1, "Ending Address - 00363000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - 00000000\n", 18) = 18
write(1, "PathName - </lib/ld-2.5.so>\n", 28) = 28
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - 00367000\n", 28) = 28
write(1, "Ending Address - 004a6000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - 00000000\n", 18) = 18
write(1, "PathName - </lib/libc-2.5.so>\n", 30) = 30
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - 08048000\n", 28) = 28
write(1, "Ending Address - 08049000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - 00000000\n", 18) = 18
write(1, "PathName - </fs_user/samirba/myP"..., 49) = 49
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - ffad8000\n", 28) = 28
write(1, "Ending Address - ffaf1000\n", 26) = 26
write(1, "Permissions - rw-p\n", 19) = 19
write(1, "Offset - 7ffffffe6000\n", 22) = 22
write(1, "PathName - <[stack]>\n", 21) = 21
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
write(1, "Starting Address - ffffe000\n", 28) = 28
write(1, "Ending Address - fffff000\n", 26) = 26
write(1, "Permissions - r-xp\n", 19) = 19
write(1, "Offset - ffffe000\n", 18) = 18
write(1, "PathName - <EMPTY>\n", 19) = 19
write(1, "\n", 1) = 1
write(1, "\n", 1) = 1
exit_group(0) = ?
There is no one to one relationship between a malloc call and a system call.
Typically, a malloc library will get big blocks from the OS
using e.g. brk system call or mmap system call.
Then these big block(s) will be cut in smaller blocks to serve
successive malloc calls. A free will usually not cause a system call
(e.g. munmap) to be called.
So, you cannot really track malloc and free at system call level.
Valgrind can track the memory leaks because it intercepts (and replaces)
malloc, free, ...
The Valgrind replacements functions are maintaining a list of allocated blocks.
Real leaks (i.e. memory which cannot be reached anymore, i.e. all pointers to it
have been lost/erased) are found by Valgrind using a scan of all the active
memory.
AFAIK, the memory blocks allocated by OS are identified by the starting address. So look for free() that is called with the same argument, which was returned by malloc() previously. As strace logs more low-level mmap and brk calls, use ltrace to log high-level library calls, keeping eye at the return values and arguments.
Related
I'v got a table (2d array), c x r. Need to generate a random pattern of connected cells inside of it. No self-crossings and no diagonal-moves. See related picture for example. ex. 1
с = 6, r = 7, the pattern is shown in numbers.
I'w wrote a function for this and it works fine, but I'm looking for hard optimization. In the code below you can see that if the pattern gets into a dead end it just rebuilds itself from the start. That is very inefficient if the pattern length is close or equals to the number of cells, c*r (42 in the example). So some smart solution is needed for this, like moving the whole pattern symmetrically when it runs out of possible moves or to add some analytics to the function so it never cathes up in the dead ends. Again, for the low values of c, r and patternLength my example works fine, but I'm looking for algorithmic perfection and high performance even on pretty high numbers.
function ClassLogic:generatePattern()
--[[ subfunctions ]]
--choosing next point for the pattern
local move = function( seq )
--getting the last sequence point
local last = seq[#seq]
-- checking the nearness of walls
local
wallLeft,
wallRight,
wallUp,
wallDown =
(last.c==1),
(last.c==config.tableSize.c),
(last.r==1),
(last.r==config.tableSize.r)
-- checking the nearness of already sequenced points
local
spLeft,
spRight,
spUp,
spDown =
(utilities.indexOfTable( seq, { c = last.c - 1, r = last.r } )~=-1),
(utilities.indexOfTable( seq, { c = last.c + 1, r = last.r } )~=-1),
(utilities.indexOfTable( seq, { c = last.c, r = last.r - 1 } )~=-1),
(utilities.indexOfTable( seq, { c = last.c, r = last.r + 1 } )~=-1)
local leftRestricted = (wallLeft or spLeft)
local rightRestricted = (wallRight or spRight)
local upRestricted = (wallUp or spUp)
local downRestricted = (wallDown or spDown)
if ( leftRestricted and rightRestricted and upRestricted and downRestricted ) then
-- dead end
print('d/e')
return nil
else
-- go somewhere possible
local possibleDirections = {}
if (not leftRestricted) then possibleDirections[#possibleDirections+1] = 1 end
if (not rightRestricted) then possibleDirections[#possibleDirections+1] = 2 end
if (not upRestricted) then possibleDirections[#possibleDirections+1] = 3 end
if (not downRestricted) then possibleDirections[#possibleDirections+1] = 4 end
local direction = possibleDirections[math.random( 1, #possibleDirections )]
if (direction==1) then
--next point is left
return { c = last.c - 1, r = last.r }
elseif (direction==2) then
--next point is right
return { c = last.c + 1, r = last.r }
elseif (direction==3) then
--next point is up
return { c = last.c, r = last.r - 1 }
elseif (direction==4) then
--next point is down
return { c = last.c, r = last.r + 1 }
end
end
end
--[[ subfunctions end ]]
-- choose random entry point
local entry = { c = math.random( 1, config.tableSize.c ),
r = math.random( 1, config.tableSize.r ) }
-- start points sequence
local pointSequence = { [1] = entry }
-- building the pattern
local succeed = false
while (not succeed) do
for i = 2, self.patternLength do
local nextPoint = move( pointSequence )
if (nextPoint~=nil) then
pointSequence[i] = nextPoint
if (i==self.patternLength) then succeed = true end
else
pointSequence = { [1] = entry }
break
end
end
end
return pointSequence
end
Any ideas or approaches on how this could be realized would be highly appreciated. Maybe some recursive backtracker or a pathfinding or a random-walk algorithms?
The snake-style growing is not enough for good performance.
The main idea is to randomly modify the path being generated by adding small detours like the following:
- - 6 - - - - 8 - -
- - 5 - - - 6 7 - -
- - 4 1 - ===> - 5 4 1 -
- - 3 2 - - - 3 2 -
- - - - - - - - - -
(note the additional two cells added to the left of 4-5 segment)
Such implementation works very fast for area filling < 95%
local function generate_path(W, H, L)
-- W = field width (number of columns) -- c = 1..W
-- H = field height (number of rows) -- r = 1..H
-- L = path length, must be within range 1..W*H
assert(L >= 1 and L <= W * H, "Path length is greater than field area")
local function get_idx(x, y)
return x >= 1 and x <= W and y >= 1 and y <= H and (y - 1) * W + x
end
local function get_x_y(idx)
local x = (idx - 1) % W + 1
local y = (idx - x) / W + 1
return x, y
end
local function random_sort(array)
for last = #array, 2, -1 do
local pos = math.random(last)
array[pos], array[last] = array[last], array[pos]
end
end
local path_sum_x = 0
local path_sum_y = 0
local path_ctr = 0
local is_unused = {} -- [idx] = true/nil (or idx recently swapped with)
local function mark_as_unused(idx, value)
local x, y = get_x_y(idx)
path_sum_x = path_sum_x - x
path_sum_y = path_sum_y - y
path_ctr = path_ctr - 1
is_unused[idx] = value or true
end
local function mark_as_path(idx)
local x, y = get_x_y(idx)
path_sum_x = path_sum_x + x
path_sum_y = path_sum_y + y
path_ctr = path_ctr + 1
is_unused[idx] = nil
end
for x = 1, W do
for y = 1, H do
is_unused[get_idx(x, y)] = true
end
end
-- create path of length 1 by selecting random cell
local idx = get_idx(math.random(W), math.random(H))
mark_as_path(idx)
local path = {first = idx, last = idx, [idx] = {}}
-- path[idx] == {next=next_idx/nil, prev=prev_idx/nil}
local function grow()
local variants = {
{dx=-1, dy=0, origin="last"}, {dx=1, dy=0, origin="last"},
{dx=0, dy=-1, origin="last"}, {dx=0, dy=1, origin="last"},
{dx=-1, dy=0, origin="first"}, {dx=1, dy=0, origin="first"},
{dx=0, dy=-1, origin="first"}, {dx=0, dy=1, origin="first"}
}
random_sort(variants)
for _, vector in ipairs(variants) do
local x, y = get_x_y(path[vector.origin])
local idx = get_idx(vector.dx + x, vector.dy + y)
if is_unused[idx] then
if vector.origin == 'first' then
-- add new first cell of the path
local old_first = path.first
path[old_first].prev = idx
path[idx] = {next = old_first}
path.first = idx
else
-- add new last cell of the path
local old_last = path.last
path[old_last].next = idx
path[idx] = {prev = old_last}
path.last = idx
end
mark_as_path(idx)
return true
end
end
end
local function shrink()
if math.random(2) == 2 then
-- remove first cell of the path
local old_first = path.first
local new_first = assert(path[old_first].next)
path[old_first] = nil
path.first = new_first
path[new_first].prev = nil
mark_as_unused(old_first)
else
-- remove last cell of the path
local old_last = path.last
local new_last = assert(path[old_last].prev)
path[old_last] = nil
path.last = new_last
path[new_last].next = nil
mark_as_unused(old_last)
end
end
local function inflate()
local variants = {}
local idx1 = path.first
repeat
local idx4 = path[idx1].next
if idx4 then
local x1, y1 = get_x_y(idx1)
local x4, y4 = get_x_y(idx4)
local dx14, dy14 = x4 - x1, y4 - y1
local dx, dy = dy14, dx14
for side = 1, 2 do
dx, dy = -dx, -dy
local x2, y2 = x1 + dx, y1 + dy
local idx2 = get_idx(x2, y2)
local idx3 = get_idx(x2 + dx14, y2 + dy14)
if is_unused[idx2] and is_unused[idx3] then
table.insert(variants, {idx1, idx2, idx3, idx4})
end
end
end
idx1 = idx4
until not idx4
if #variants > 0 then
local idx1, idx2, idx3, idx4 =
(table.unpack or unpack)(variants[math.random(#variants)])
-- insert idx2 and idx3 between idx1 and idx4
path[idx1].next = idx2
path[idx2] = {prev = idx1, next = idx3}
path[idx3] = {prev = idx2, next = idx4}
path[idx4].prev = idx3
mark_as_path(idx2)
mark_as_path(idx3)
return true
end
end
local function euclid(dx, dy)
return dx*dx + dy*dy
end
local function swap()
local variants = {}
local path_center_x = path_sum_x / path_ctr
local path_center_y = path_sum_y / path_ctr
local idx1 = path.first
repeat
local idx2 = path[idx1].next
local idx3 = idx2 and path[idx2].next
if idx3 then
local x1, y1 = get_x_y(idx1)
local x2, y2 = get_x_y(idx2)
local x3, y3 = get_x_y(idx3)
local dx12, dy12 = x2 - x1, y2 - y1
local dx23, dy23 = x3 - x2, y3 - y2
if dx12 * dx23 + dy12 * dy23 == 0 then
local x, y = x1 + dx23, y1 + dy23
local idx = get_idx(x, y)
local dist2 = euclid(x2 - path_center_x, y2 - path_center_y)
local dist = euclid(x - path_center_x, y - path_center_y)
if is_unused[idx] and dist2<dist and is_unused[idx]~=idx2 then
table.insert(variants, {idx1, idx2, idx3, idx})
end
end
end
idx1 = idx2
until not idx3
if #variants > 0 then
local idx1, idx2, idx3, idx =
(table.unpack or unpack)(variants[math.random(#variants)])
-- swap idx2 and idx
path[idx1].next = idx
path[idx] = path[idx2]
path[idx3].prev = idx
path[idx2] = nil
mark_as_unused(idx2, idx)
mark_as_path(idx)
return true
end
end
local actions = {grow, inflate, swap}
repeat
random_sort(actions)
local success
for _, action in ipairs(actions) do
success = action()
if success then
break
end
end
if not success and path_ctr < L then
-- erase and rewind
while path_ctr > 1 do
shrink()
end
end
until path_ctr >= L
while path_ctr > L do
shrink()
end
local pointSequence = {}
local idx = path.first
local step = 0
repeat
step = step + 1
path[idx].step = step
local x, y = get_x_y(idx)
pointSequence[step] = {c = x, r = y}
idx = path[idx].next
until not idx
local field = 'W = '..W..', H = '..H..', L = '..L..'\n'
for y = 1, H do
for x = 1, W do
local c = path[get_idx(x, y)]
field = field..(' '..(c and c.step or '-')):sub(-4)
end
field = field..'\n'
end
print(field)
return pointSequence
end
Usage example:
math.randomseed(os.time())
local pointSequence = generate_path(6, 7, 10)
-- pointSequence = {[1]={r=r1,c=c1}, [2]={r=r2,c=c2},...,[10]={r=r10,c=c10}}
Result examples:
W = 5, H = 5, L = 10
- - - 9 10
- 6 7 8 -
- 5 4 1 -
- - 3 2 -
- - - - -
W = 5, H = 5, L = 19
15 16 17 18 19
14 1 2 3 4
13 12 11 6 5
- - 10 7 -
- - 9 8 -
W = 6, H = 7, L = 35
- 35 34 25 24 23
- - 33 26 21 22
- 31 32 27 20 19
- 30 29 28 - 18
- 1 10 11 12 17
3 2 9 8 13 16
4 5 6 7 14 15
W = 19, H = 21, L = 394
77 78 79 84 85 118 119 120 121 122 123 124 125 126 127 128 129 254 255
76 75 80 83 86 117 116 115 114 141 140 139 138 135 134 131 130 253 256
73 74 81 82 87 88 89 112 113 142 145 146 137 136 133 132 - 252 257
72 69 68 67 92 91 90 111 - 143 144 147 148 149 150 151 152 251 258
71 70 65 66 93 108 109 110 163 162 161 160 159 158 157 156 153 250 259
58 59 64 63 94 107 166 165 164 191 192 193 196 197 - 155 154 249 260
57 60 61 62 95 106 167 168 189 190 - 194 195 198 241 242 243 248 261
56 55 54 53 96 105 170 169 188 203 202 201 200 199 240 239 244 247 262
47 48 51 52 97 104 171 172 187 204 205 206 231 232 237 238 245 246 263
46 49 50 99 98 103 174 173 186 209 208 207 230 233 236 267 266 265 264
45 42 41 100 101 102 175 184 185 210 211 228 229 234 235 268 269 270 271
44 43 40 39 38 177 176 183 214 213 212 227 226 225 276 275 274 273 272
33 34 35 36 37 178 179 182 215 216 217 218 223 224 277 278 279 280 281
32 29 28 23 22 - 180 181 12 11 10 219 222 287 286 285 284 283 282
31 30 27 24 21 18 17 14 13 8 9 220 221 288 289 290 291 292 293
380 381 26 25 20 19 16 15 394 7 4 3 304 303 300 299 296 295 294
379 382 383 384 387 388 391 392 393 6 5 2 305 302 301 298 297 312 313
378 371 370 385 386 389 390 347 346 343 342 1 306 307 308 309 310 311 314
377 372 369 364 363 350 349 348 345 344 341 340 333 332 319 318 317 316 315
376 373 368 365 362 351 352 353 354 355 338 339 334 331 320 321 322 323 324
375 374 367 366 361 360 359 358 357 356 337 336 335 330 329 328 327 326 325
I am attempting to reclassify continuous data to categorical data using Matlab. The following script takes a 4-band (Red, Green, Blue, nIR) aerial image and calculates the normalized difference vegetation index (i.e. a vegetation index showing healthy green vegetation). The script then rescales the values from (-1 to 1) to (0 - 255). This is the matrix I am trying to reclassify in the third section of the script %% Reclassify Imag1 matrix. I am attempting to use conditional statements to perform the reclassification, although this may be the wrong approach. The reclassification step in the script does not have any apparent effect.
How can I reclassify continuous values (0 - 255) to categorical values (1, 2, 3, 4) on a cell by cell basis?
file = 'F:\path\to\naip\image\4112107_ne.tif';
[Z R] = geotiffread(file);
outputdir = 'F:\temp\';
%% Make NDVI calculations
NIR = im2single(Z(:,:,4));
red = im2single(Z(:,:,3));
ndvi = (NIR - red) ./ (NIR + red);
ndvi = double(ndvi);
%% Stretch NDVI to 0-255 and convert to 8-bit unsigned integer
ndvi = floor((ndvi + 1) * 128); % [-1 1] -> [0 256]
ndvi(ndvi < 0) = 0; % not really necessary, just in case & for symmetry
ndvi(ndvi > 255) = 255; % in case the original value was exactly 1
Imag1 = uint8(ndvi);
%% Reclassify Imag1 matrix
if (150 <= Imag1)
Imag1 = 1;
elseif (150 > Imag1) & (140 < Imag1)
Imag1 = 2;
elseif (140 > Imag1) & (130 < Imag1)
Imag1 = 3;
elseif (130 >= Imag1)
Imag1 = 4;
end
%% Write the results to disk
tiffdata = geotiffinfo(file);
outfilename = [outputdir 'reclass_ndvi' '.tif'];
geotiffwrite(outfilename, Imag1, R, 'GeoKeyDirectoryTag', tiffdata.GeoTIFFTags.GeoKeyDirectoryTag)
disp('Processing complete')
Try this:
Imag1 = [ 62 41 169 118 210;
133 158 96 149 110;
211 200 84 194 29;
209 16 15 146 28;
95 144 13 249 170];
Imag1(find(Imag1 <= 130)) = 4;
Imag1(find(Imag1 >= 150)) = 1;
Imag1(find(Imag1 > 140)) = 2;
Imag1(find(Imag1 > 130)) = 3;
Result:
Imag1 =
62 41 169 118 210
133 158 96 149 110
211 200 84 194 29
209 16 15 146 28
95 144 13 249 170
Imag1 =
4 4 1 4 1
3 1 4 2 4
1 1 4 1 4
1 4 4 2 4
4 2 4 1 1
I can go into the logic in detail if you like, but I wanted to confirm that this gives your expected results first.
Some updates based on comments on the follow-up question to eliminate the unnecessary find and make the code more robust and independent of execution order.
Imag2 = zeros(size(Imag1));
Imag2(Imag1 >= 150) = 1;
Imag2((Imag1 > 140) & (Imag1 < 150)) = 2;
Imag2((Imag1 > 130) & (Imag1 < 141)) = 3;
Imag2(Imag1 <= 130) = 4;
Note that the results are now in Imag2 instead of overwriting Imag1.
I am using a Linux platform (3.12.13 & 2.6.35.3),& imx5x series processor.
In my program I am using the two serial port for read write operation /dev/ttymxc2 & /dev/ttymxc1 .After some duration the /dev/tty open system call executes which is not a part of my program & the error comes open("/dev/tty", ...) writev(7, [{"* glibc detected * ", 23}.
Please suggest some solution ,the port which i am not using in my code still system call executed to open /dev/tty/ .
These are some strace log .
open("/dev/ttymxc2", O_RDWR|O_NOCTTY|O_NONBLOCK) = 4
nanosleep({0, 200000000}, NULL) = 0
ioctl(4, TCFLSH, 0x2) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B9600 opost -isig -icanon -echo ...}) = 0
ioctl(4, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B9600 opost -isig -icanon -echo ...}) = 0
open("/dev/ttymxc0", O_RDWR|O_NONBLOCK) = 5
ioctl(5, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B115200 opost -isig -icanon -echo ...}) = 0
ioctl(5, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B115200 opost -isig -icanon -echo ...}) = 0
open("/dev/ttymxc1", O_RDWR|O_NOCTTY|O_NONBLOCK) = 6
nanosleep({0, 200000000}, NULL) = 0
ioctl(6, TCFLSH, 0x2) = 0
ioctl(6, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B9600 opost -isig -icanon -echo ...}) = 0
ioctl(6, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B9600 opost -isig -icanon -echo ...}) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f2d000
write(1, "in main \n", 9) = 9
write(1, " Leaving process fun \n", 22) = 22
sigreturn() (mask []) = 71
write(1, "bab0 bab0\n", 11) = 11
open("/dev/tty", O_RDWR|O_NOCTTY|O_NONBLOCK) = 7
writev(7, [{"*** glibc detected *** ", 23}, {"./test11_2", 10}, {": ", 2}, {"double free or corruption (!prev"..., 33}, {": 0x", 4}, {"00bfa0c0", 8}, {" ***\n", 5}], 7) = 85
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x76d2d000
munmap(0x76d2d000, 864256) = 0
munmap(0x76f00000, 184320) = 0
mprotect(0x76e00000, 135168, PROT_READ|PROT_WRITE) = 0
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
write(1, "final out", 9) = 9
gettid() = 8796
tgkill(8796, 8796, SIGABRT) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=8796, si_uid=0} ---
+++ killed by SIGABRT +++
Please suggest some solution
You need to fix the heap corruption bug that glibc discovered for you.
One way to do that is to run your program under Valgrind, but I don't believe it's available for imx5x.
Another way is to run the program with export MALLOC_CHECK_=2. See documentation.
Yet another way is to use AddressSanitizer (if your toolchain supports it).
In my code I am using an external C library and the library calls madvise with MADV_SEQUENTIAL option which takes too long to finish. In my opinion only calling madvise with MADV_SEQUENTIAL is enough for our job. My first question is, why multiple madvise system calls are made, is there a logic in calling madvise with different options sequentially? My second question is, do you have any idea why madvise with MADV_SEQUENTIAL takes too long, sometimes about 1-2 minutes?
[root#mymachine ~]# strace -ttT my_compiled_code
...
13:11:35.358982 open("/some/big/file", O_RDONLY) = 8 <0.000010>
13:11:35.359060 fstat64(8, {st_mode=S_IFREG|0644, st_size=953360384, ...}) = 0 <0.000006>
13:11:35.359155 mmap2(NULL, 1073741824, PROT_READ, MAP_SHARED, 8, 0) = 0x7755e000 <0.000007>
13:11:35.359223 madvise(0x7755e000, 1073741824, MADV_NORMAL) = 0 <0.000006>
13:11:35.359266 madvise(0x7755e000, 1073741824, MADV_RANDOM) = 0 <0.000006>
13:11:35.359886 madvise(0x7755e000, 1073741824, MADV_SEQUENTIAL) = 0 <0.000006>
13:11:53.730549 madvise(0x7755e000, 1073741824, MADV_RANDOM) = 0 <0.000013>
...
I am using 32-bit linux kernel: 3.4.52-9
[root#mymachine ~]# free -lk
total used free shared buffers cached
Mem: 4034412 3419344 615068 0 55712 767824
Low: 853572 495436 358136
High: 3180840 2923908 256932
-/+ buffers/cache: 2595808 1438604
Swap: 4192960 218624 3974336
[root#mymachine ~]# cat /proc/buddyinfo
Node 0, zone DMA 89 23 9 4 5 4 4 1 0 2 0
Node 0, zone Normal 9615 7099 3997 1723 931 397 78 0 0 1 1
Node 0, zone HighMem 7313 8089 2187 420 206 92 41 15 8 3 6
I have a code like this...
Dim sFileText As String
Dim Files As String
Dim iFileNo As Integer
Dim aray1() As String
Dim aray2() As String
Grid(1).Rows = 1
iFileNo = FreeFile
Files = Text1.Text
Open Files For Input As #iFileNo
Do While Not EOF(iFileNo)
Input #iFileNo, sFileText
aray1 = Split(sFileText, Chr(9))
For i = 0 To UBound(aray1) - 1
' MsgBox aray1(i)
Grid(1).Rows = Grid(1).Rows + 1
Grid(1).TextMatrix(Grid(1).Rows - 1, 0) = aray1(0)
Grid(1).TextMatrix(Grid(1).Rows - 1, 1) = aray1(1)
Grid(1).TextMatrix(Grid(1).Rows - 1, 2) = aray1(2)
Grid(1).TextMatrix(Grid(1).Rows - 1, 3) = aray1(3)
Grid(1).TextMatrix(Grid(1).Rows - 1, 4) = aray1(4)
Grid(1).TextMatrix(Grid(1).Rows - 1, 5) = aray1(5)
Next i
Loop
The Result is Like this (sorry I can't display images) :
36 2012-10-20 08:59:34 1 255 1 0
36 2012-10-20 08:59:34 1 255 1 0
36 2012-10-20 08:59:34 1 255 1 0
36 2012-10-20 08:59:34 1 255 1 0
36 2012-10-20 08:59:34 1 255 1 0
110 2012-10-20 09:45:00 1 255 1 0
110 2012-10-20 09:45:00 1 255 1 0
110 2012-10-20 09:45:00 1 255 1 0
110 2012-10-20 09:45:00 1 255 1 0
110 2012-10-20 09:45:00 1 255 1 0
Is everyone know the code to display only once for each record in the MSFlexGrid ?
It shows 5 times in each records..
P.S : Sorry for Bad English :)
Get rid of the line that starts the FOR loop, and the line that ends it (the NEXT statement)
You are looping, and there is no need.
Basically, with the FOR NEXT Loop you are adding a new row in the grid, for every element (Column) in the array (aray1) NOT every row.
Delete those two lines and you should be fine.