I am new to Rust and I try to figure out where things are allocated.
I use Rust 1.64.0 on Ubuntu 22.04.0 (jammy):
$ rustc --version
rustc 1.64.0 (a55dd71d5 2022-09-19)
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
Codename: jammy
I try to explore the executable produce by compiling this very basic Rust program:
fn tester() {
let borrowed_string: &str = "world";
println!("{}", borrowed_string);
}
fn main() { tester(); }
Compilation (OK, this is overkill... but I want to be sure that I have all I need for using GDB):
$ cargo build --config "profile.dev.debug=true" --config "profile.dev.opt-level=0" --profile=dev
Compiling variables v0.1.0 (/home/denis/Documents/github/rust-playground/variables)
Finished dev [unoptimized + debuginfo] target(s) in 0.71s
Run rust-gdb, set the brakpoint and run the program:
$ rust-gdb target/debug/variables
GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90
...
Reading symbols from target/debug/variables...
(gdb) b 3
Breakpoint 1 at 0x7959: file src/main.rs, line 3.
(gdb) r
Starting program: /home/denis/Documents/github/rust-playground/variables/target/debug/variables
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, variables::tester () at src/main.rs:3
3 println!("{}", borrowed_string);
(gdb)
s
Print the memory mapping;
(gdb) info proc map
process 6985
Mapped address spaces:
Start Addr End Addr Size Offset Perms objfile
0x555555554000 0x55555555a000 0x6000 0x0 r--p /home/denis/Documents/github/rust-playground/variables/target/debug/variables
0x55555555a000 0x555555591000 0x37000 0x6000 r-xp /home/denis/Documents/github/rust-playground/variables/target/debug/variables
0x555555591000 0x55555559f000 0xe000 0x3d000 r--p /home/denis/Documents/github/rust-playground/variables/target/debug/variables
0x5555555a0000 0x5555555a3000 0x3000 0x4b000 r--p /home/denis/Documents/github/rust-playground/variables/target/debug/variables
0x5555555a3000 0x5555555a4000 0x1000 0x4e000 rw-p /home/denis/Documents/github/rust-playground/variables/target/debug/variables
0x5555555a4000 0x5555555c5000 0x21000 0x0 rw-p [heap]
0x7ffff7d5c000 0x7ffff7d5f000 0x3000 0x0 rw-p
0x7ffff7d5f000 0x7ffff7d87000 0x28000 0x0 r--p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7d87000 0x7ffff7f1c000 0x195000 0x28000 r-xp /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f1c000 0x7ffff7f74000 0x58000 0x1bd000 r--p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f74000 0x7ffff7f78000 0x4000 0x214000 r--p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f78000 0x7ffff7f7a000 0x2000 0x218000 rw-p /usr/lib/x86_64-linux-gnu/libc.so.6
0x7ffff7f7a000 0x7ffff7f87000 0xd000 0x0 rw-p
0x7ffff7f87000 0x7ffff7f8a000 0x3000 0x0 r--p /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff7f8a000 0x7ffff7fa1000 0x17000 0x3000 r-xp /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff7fa1000 0x7ffff7fa5000 0x4000 0x1a000 r--p /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff7fa5000 0x7ffff7fa6000 0x1000 0x1d000 r--p /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff7fa6000 0x7ffff7fa7000 0x1000 0x1e000 rw-p /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff7fb8000 0x7ffff7fb9000 0x1000 0x0 ---p
0x7ffff7fb9000 0x7ffff7fbd000 0x4000 0x0 rw-p
0x7ffff7fbd000 0x7ffff7fc1000 0x4000 0x0 r--p [vvar]
0x7ffff7fc1000 0x7ffff7fc3000 0x2000 0x0 r-xp [vdso]
0x7ffff7fc3000 0x7ffff7fc5000 0x2000 0x0 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7fc5000 0x7ffff7fef000 0x2a000 0x2000 r-xp /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7fef000 0x7ffff7ffa000 0xb000 0x2c000 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7ffb000 0x7ffff7ffd000 0x2000 0x37000 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7ffd000 0x7ffff7fff000 0x2000 0x39000 rw-p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 --xp [vsyscall]
(gdb)
We have:
HEAP: [0x5555555A4000, 0x5555555C4FFF]
STACK: [0x7FFFFFFDE000, 0x7FFFFFFFEFFF]
I assume that the data "world" is allocated in the heap. Thus, let's find out... but look at what I obtain!!!
(gdb) find 0x5555555A4000, 0x5555555C4FFF, "world"
0x5555555a4ba0
1 pattern found.
(gdb) find 0x5555555A4000, 0x5555555C4FFF, "world"
0x5555555a4be0
1 pattern found.
(gdb) find 0x5555555A4000, 0x5555555C4FFF, "world"
0x5555555a4c20
1 pattern found.
(gdb) find 0x5555555A4000, 0x5555555C4FFF, "world"
0x5555555a4c60
1 pattern found.
(gdb) find 0x5555555A4000, 0x5555555C4FFF, "world"
0x5555555a4ca0
1 pattern found.
(gdb)
Please note that:
0x5555555A4BA0 -> 0x5555555A4BE0 => 64
0x5555555A4BE0 -> 0x5555555A4C20 => 64
0x5555555A4C20 -> 0x5555555A4C60 => 64
Question: why does the position of the data change from one scan to the next?
(This question may not be related specifically to Rust.)
(gdb) p borrowed_string
$1 = "world"
(gdb) ptype borrowed_string
type = struct &str {
data_ptr: *mut u8,
length: usize,
}
(gdb) p borrowed_string.data_ptr
$2 = (*mut u8) 0x555555591000
(gdb) x/5c 0x555555591000
0x555555591000: 119 'w' 111 'o' 114 'r' 108 'l' 100 'd'
We have:
0x5555555A4000: start of the heap (included)
0x5555555C5000: end of the heap (excluded), and start of the "uncharted" memory territory
0x555555591000: address of the data "world"
0x7FFFF7D5F000: end of the "uncharted" memory territory
Question: what is this "uncharted" memory territory between 0x5555555C5000 (included) and 0x7FFFF7D5F000 (excluded)?
EDIT:
As mentioned in the comments below, I made a mistake. The data "world" is "before" the heap... The comments make sense. Thank you.
Question: what is this "uncharted" memory territory between 0x5555555C5000 (included) and 0x7FFFF7D5F000 (excluded)?
It's nothing. It's memory which is not mapped.
Where are "str" values allocated? Is it in the heap?
Your memory map answers the question:
0x555555591000 0x55555559f000 0xe000 0x3d000 r--p /home/denis/Documents/github/rust-playground/variables/target/debug/variables
This is one of the areas where the binary itself is mapped. Most likely the "rodata" segment of the executable. String literals are generally "allocated" in the binary itself, then a static reference is loaded.
More generally str values are not allocated, they're a reference to data living somewhere else which could be on the heap (if the reference was obtained from a String or Box<str> or some pointers), in the binary (literals, static includes), or even on the stack (e.g. you can create an array on the stack then pass it through std::str::from_utf8 and get an &str out of it)
We have: HEAP: [0x5555555A4000, 0x5555555C4FFF]
That's... not really helpful or useful or true, frankly: modern systems have largely moved away from linear heaps and to memory map heaps. While Linux software still makes some limited use of (s)brk, BSDs qualify them as "historical curiosities". If you assume the heap is contained within these bounds you're going to face lots of surprises.
Question: why does the position of the data change from one scan to the next?
Because the debugger is allocating stuff in context of the program, I assume? So you might be finding the data gdb itself is storing.
Related
I have a pintool that has calls to PIN_Backtrace(). It seems that libunwind does not support some registers in x86_64 and this leads to the following error message and an abnormal exit:
libunwind: uint64_t libunwind::Registers_x86_64::getRegister(int) const Source/bionic/libunwind/src/Registers.hpp:342 - unsupported x86_64 register
Aborted
I want the program to continue even with these errors. What is the most efficient way to handle this situation?
I debugged my pintool using gdb. Here is the backtrace when abort() is received by the debugger:
(gdb) bt
#0 0x00007ffff726c22b in ?? ()
#1 0x00007fffeca88730 in ?? ()
#2 0x00007ffff726c363 in ?? ()
#3 0x0000000000005386 in ?? ()
#4 0x0000000000000001 in ?? ()
#5 0x0000000000000000 in ?? ()
info proc mapping shows the address ranges as follows:
...
0x7fffeea3a000 0x7ffff71fb000 0x87c1000 0x0
0x7ffff71fb000 0x7ffff7283000 0x88000 0x0 /home/ahmad/Programs/pin-3.7-97619-g0d0c92f4f-gcc-linux/intel64/runtime/pincrt/libc-dynamic.so
0x7ffff7283000 0x7ffff7284000 0x1000 0x0
0x7ffff7284000 0x7ffff7286000 0x2000 0x88000 /home/ahmad/Programs/pin-3.7-97619-g0d0c92f4f-gcc-linux/intel64/runtime/pincrt/libc-dynamic.so
...
and
...
0x7fffe1687000 0x7fffec287000 0xac00000 0x0
0x7fffec287000 0x7fffed28e000 0x1007000 0x0
0x7fffed28e000 0x7fffedb6a000 0x8dc000 0x0
...
It seems that the libunwind library used by Pin is a special one exlusive to PinCRT. This can be seen in the info /proc/<PID>/maps output for the pintool:
...
7ffff7e33000-7ffff7e45000 r-xp 00000000 08:13 466277 /home/ahmad/Programs/pin-3.7-97619-g0d0c92f4f-gcc-linux/intel64/runtime/pincrt/libunwind-dynamic.so
7ffff7e45000-7ffff7e46000 r--p 00011000 08:13 466277 /home/ahmad/Programs/pin-3.7-97619-g0d0c92f4f-gcc-linux/intel64/runtime/pincrt/libunwind-dynamic.so
7ffff7e46000-7ffff7e47000 rw-p 00012000 08:13 466277 /home/ahmad/Programs/pin-3.7-97619-g0d0c92f4f-gcc-linux/intel64/runtime/pincrt/libunwind-dynamic.so
...
I was running Gapcloser (a tool released from Soapdenovo), and it kept comes up a message and failed in the middle of the process:
*** Error in `GapCloser': free(): invalid pointer: 0x0000000001eb4a80 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f7658b0a7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f7658b1337a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f7658b1753c]
GapCloser[0x405d41]
GapCloser[0x40983b]
GapCloser[0x405ad3]
GapCloser[0x403982]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f7658ab3830]
GapCloser[0x402b59]
======= Memory map: ========
00400000-0042a000 r-xp 00000000 fc:02 93192245 /opt/GapCloser-v1.12-r6/Debug/GapCloser
00629000-0062a000 r--p 00029000 fc:02 93192245 /opt/GapCloser-v1.12-r6/Debug/GapCloser
0062a000-0062b000 rw-p 0002a000 fc:02 93192245 /opt/GapCloser-v1.12-r6/Debug/GapCloser
01e9b000-01ed7000 rw-p 00000000 00:00 0 [heap]
7f6689a9b000-7f6aeab13000 rw-p 00000000 00:00 0
7f6f2ac77000-7f6f3c4b9000 rw-p 00000000 00:00 0
7f6f44000000-7f6f44021000 rw-p 00000000 00:00 0
7f6f44021000-7f6f48000000 ---p 00000000 00:00 0
7f6f4b9f4000-7f7658a93000 rw-p 00000000 00:00 0
7f7658a93000-7f7658c53000 r-xp 00000000 fc:00 66322933 /lib/x86_64-linux-gnu/libc-2.23.so
7f7658c53000-7f7658e53000 ---p 001c0000 fc:00 66322933 /lib/x86_64-linux-gnu/libc-2.23.so
7f7658e53000-7f7658e57000 r--p 001c0000 fc:00 66322933 /lib/x86_64-linux-gnu/libc-2.23.so
7f7658e57000-7f7658e59000 rw-p 001c4000 fc:00 66322933 /lib/x86_64-linux-gnu/libc-2.23.so
7f7658e59000-7f7658e5d000 rw-p 00000000 00:00 0
7f7658e5d000-7f7658e74000 r-xp 00000000 fc:00 66326925 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f7658e74000-7f7659073000 ---p 00017000 fc:00 66326925 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f7659073000-7f7659074000 r--p 00016000 fc:00 66326925 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f7659074000-7f7659075000 rw-p 00017000 fc:00 66326925 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f7659075000-7f765917d000 r-xp 00000000 fc:00 66322974 /lib/x86_64-linux-gnu/libm-2.23.so
7f765917d000-7f765937c000 ---p 00108000 fc:00 66322974 /lib/x86_64-linux-gnu/libm-2.23.so
7f765937c000-7f765937d000 r--p 00107000 fc:00 66322974 /lib/x86_64-linux-gnu/libm-2.23.so
7f765937d000-7f765937e000 rw-p 00108000 fc:00 66322974 /lib/x86_64-linux-gnu/libm-2.23.so
7f765937e000-7f76594fa000 r-xp 00000000 fc:00 51382039 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
7f76594fa000-7f76596fa000 ---p 0017c000 fc:00 51382039 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
7f76596fa000-7f7659704000 r--p 0017c000 fc:00 51382039 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
7f7659704000-7f7659706000 rw-p 00186000 fc:00 51382039 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
7f7659706000-7f765970a000 rw-p 00000000 00:00 0
7f765970a000-7f7659722000 r-xp 00000000 fc:00 66323020 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f7659722000-7f7659921000 ---p 00018000 fc:00 66323020 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f7659921000-7f7659922000 r--p 00017000 fc:00 66323020 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f7659922000-7f7659923000 rw-p 00018000 fc:00 66323020 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f7659923000-7f7659927000 rw-p 00000000 00:00 0
7f7659927000-7f765994d000 r-xp 00000000 fc:00 66322909 /lib/x86_64-linux-gnu/ld-2.23.so
7f7659afc000-7f7659b3a000 rw-p 00000000 00:00 0
7f7659b4b000-7f7659b4c000 rw-p 00000000 00:00 0
7f7659b4c000-7f7659b4d000 r--p 00025000 fc:00 66322909 /lib/x86_64-linux-gnu/ld-2.23.so
7f7659b4d000-7f7659b4e000 rw-p 00026000 fc:00 66322909 /lib/x86_64-linux-gnu/ld-2.23.so
7f7659b4e000-7f7659b4f000 rw-p 00000000 00:00 0
7ffc5a9e7000-7ffc5aa08000 rw-p 00000000 00:00 0 [stack]
7ffc5abaa000-7ffc5abad000 r--p 00000000 00:00 0 [vvar]
7ffc5abad000-7ffc5abaf000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
And this is my log file:
cat gapcloser.log
[WARNING] Maximum supported read length is 155 bp! Program will use 155 instead of 251.
Program: GapCloser
Version: 1.12
Parameters:
-a (scaffold file): sunbird_platanus_raw_kraken_scaff_scaffold.fa
-b (config file): sunbird_raw.config
-o (output file): sunbird_platanus_raw_kraken_scaff_gapclosed
-l (max read len): 155
-p (overlap para): 25
-t (thread num): 40
>>>>>>>>>>hash initializing<<<<<<<<<<
counting reads
in lib:
total reads sum: 289413008
Paired-end reads sum: 289413008
in lib:
total reads sum: 21371568
Paired-end reads sum: 21371568
in lib:
total reads sum: 21944342
Paired-end reads sum: 21944342
in lib:
total reads sum: 20671814
Paired-end reads sum: 20671814
in lib:
total reads sum: 20949232
Paired-end reads sum: 20949232
in lib:
total reads sum: 22977390
Paired-end reads sum: 22977390
in lib:
total reads sum: 19285920
Paired-end reads sum: 19285920
in lib:
total reads sum: 23065494
Paired-end reads sum: 23065494
in lib:
total reads sum: 21131136
Paired-end reads sum: 21131136
in lib:
total reads sum: 20350118
Paired-end reads sum: 20350118
in lib:
total reads sum: 20579926
Paired-end reads sum: 20579926
in lib:
total reads sum: 18998014
Paired-end reads sum: 18998014
in lib:
total reads sum: 20039196
Paired-end reads sum: 20039196
reads sum: 540777158
spent time: 1658s
reads counted
allocating memorys
spent time: 19s
memorys allocated
initializing reads
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
in lib:
spent time: 1984s
reads initialized
sorting reads in reversed direction
spent time: 1357s
reads sorted
initializing hash on reversed reads
kmers sum: 413463339
spent time: 951s
hash initialized
reversing reads
spent time: 633s
reads reversed
sorting reads in forward direction
spent time: 1363s
reads sorted
initializing hash on forward reads
kmers sum: 783012674
spent time: 994s
hash initialized
marking unique reads
spent time: 41s
unique reads marked
sorting reads by serial number
spent time: 1011s
reads sorted
spent total time: 10011s
>>>>>>>>>>hash initialization finished<<<<<<<<<<
In fact, I have run this programme successfully with the same set of data before, however our server has been re-installed therefore Gapcloser was re-installed again, but running the same data no longer works due to this issue...
I thought it was memory's problem so I cleaned the memory page cache by this command, but it did not help at all, this is my current memory, which should definitely be enough for Gapcloser.
free -h
total used free shared buff/cache available
Mem: 755G 2.7G 539G 14M 214G 751G
Swap: 810G 106M 810G
By the way I am using Gapcloser source code version, and my ubuntu is 16.04 version.
This is my Soapdenovo/Gapcloser Config file which I think it's not a problem because it seems to have read all the libraries successfully?
#FOR MATEPAIR LIBRARIES
#maximal read length
max_rd_len=251
#average insert size for 1kb
[LIB]
#average insert size for gel free
avg_ins=1805
#reverse-forward, generated from circularizing libraries with typical insert size greater than 2Kb
reverse_seq=1
#In which parts the reads are used. 2 - only scaffold assembly
asm_flags=4
#assembler will cut the reads from the current library to this length
rd_len_cutof=150
#In which order the reads are used while scaffolding,1-170/200/250bp,2-350/500bp,3-800bp,4-2KB,5-5Kb,6-10Kb,7-20Kb
rank=4
#fastq files for 1kb1
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads1K1_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads1K1_R2.fastq
[LIB]
#average insert size for 3kb1
avg_ins=3918
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=5
#fastq files for 3kb
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads3K1_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads3K1_R2.fastq
[LIB]
#average insert size for 5kb1
avg_ins=6243
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=5
#fastq files for 5kb
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads5K1_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads5K1_R2.fastq
[LIB]
#average insert size for 8kb1
avg_ins=8930
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=6
#fastq files for 8kb
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads8K1_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads8K1_R2.fastq
[LIB]
#average insert size for 12kb1
avg_ins=12507
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=6
#fastq files for 12kb
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads12K1_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads12K1_R2.fastq
[LIB]
#average insert size for 20kb1
avg_ins=17407
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=7
#fastq files for 20kb
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads20K1_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads20K1_R2.fastq
[LIB]
#average insert size for 1kb2
avg_ins=9793
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=4
#fastq files for 1kb2
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads1K2_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads1K2_R2.fastq
[LIB]
#average insert size for 3kb2
avg_ins=3944
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=5
#fastq files for 3kb2
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads3K2_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads3K2_R2.fastq
[LIB]
#average insert size for 5kb2
avg_ins=6225
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=5
#fastq files for 5kb2
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads5K2_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads5K2_R2.fastq
[LIB]
#average insert size for 8kb2
avg_ins=8913
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=6
#fastq files for 8kb2
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads8K2_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads8K2_R2.fastq
[LIB]
#average insert size for 12kb2
avg_ins=12491
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=6
#fastq files for 12kb2
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads12K2_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads12K2_R2.fastq
[LIB]
#average insert size for 20kb2
avg_ins=17370
reverse_seq=1
asm_flags=4
rd_len_cutoff=150
rank=7
#fastq files for 20kb2
q1=/home/cch/sunbird/sunbird_kraken/Pure_MPreads20K2_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_MPreads20K2_R2.fastq
### 2x250 run data
[LIB]
avg_ins=434
reverse_seq=0
#only contigs assembly
asm_flags=4
rank=2
#fastq files from LGC16_JM06_591bp
q1=/home/cch/sunbird/sunbird_kraken/Pure_LGC16_JM09_594bp_CTTGTA_L002_R1.fastq
q2=/home/cch/sunbird/sunbird_kraken/Pure_LGC16_JM09_594bp_CTTGTA_L002_R2.fastq
I have run the Gapcloser through Valgrind and got 2 errors, but I do not know how to fix it, does anyone have any ideas?
valgrind --leak-check=yes GapCloser
==77240== Memcheck, a memory error detector
==77240== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==77240== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==77240== Command: GapCloser
==77240==
==77240== Syscall param open(filename) points to unaddressable byte(s)
==77240== at 0x59FB040: __open_nocancel (syscall-template.S:84)
==77240== by 0x597DACD: _IO_file_open (fileops.c:221)
==77240== by 0x597DD34: _IO_file_fopen##GLIBC_2.2.5 (fileops.c:328)
==77240== by 0x5971D33: __fopen_internal (iofopen.c:86)
==77240== by 0x510AD2F: std::__basic_file<char>::open(char const*, std::_Ios_Openmode, int) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==77240== by 0x514B259: std::basic_filebuf<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==77240== by 0x514B42F: std::basic_ifstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==77240== by 0x403450: main (Main.cpp:121)
==77240== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==77240==
[Error] Can not open input file.
Version:
1.12
Contact:
soap#genomics.org.cn
Usage:
GapCloser [options]
-a <string> input scaffold file name, required.
-b <string> input library info file name, required.
-o <string> output file name, required.
-l <int> maximum read length (<=155), default=100.
-p <int> overlap param(<=31), default=25.
-t <int> thread number, default=1.
-h -? output help information.
==77240==
==77240== Process terminating with default action of signal 27 (SIGPROF)
==77240== at 0x5A0CE0F: write_gmon (gmon.c:354)
==77240== by 0x5A0D589: _mcleanup (gmon.c:422)
==77240== by 0x593DFF7: __run_exit_handlers (exit.c:82)
==77240== by 0x593E044: exit (exit.c:104)
==77240== by 0x40315F: usage() (Main.cpp:60)
==77240== by 0x403497: main (Main.cpp:124)
==77240==
==77240== HEAP SUMMARY:
==77240== in use at exit: 299,124 bytes in 2 blocks
==77240== total heap usage: 4 allocs, 2 frees, 300,700 bytes allocated
==77240==
==77240== LEAK SUMMARY:
==77240== definitely lost: 0 bytes in 0 blocks
==77240== indirectly lost: 0 bytes in 0 blocks
==77240== possibly lost: 0 bytes in 0 blocks
==77240== still reachable: 299,124 bytes in 2 blocks
==77240== suppressed: 0 bytes in 0 blocks
==77240== Reachable blocks (those to which a pointer was found) are not shown.
==77240== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==77240==
==77240== For counts of detected and suppressed errors, rerun with: -v
==77240== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)
Profiling timer expired
I am learning about the Linux user space memory layout on x86_64 systems and wanted to print some addresses from some of the sections. I used this Rust code:
fn main() {
let x = 3; // should be stored on stack
let s = "hello"; // should be in the .data section
println!("stack ≈ {:p}", &x);
println!(".text ≈ {:p}", main as *const ());
println!(".data ≈ {:p}", s);
use std::io;
let mut f = std::fs::File::open("/proc/self/maps").unwrap();
let out = io::stdout();
io::copy(&mut f, &mut out.lock()).unwrap();
}
This code also prints the file /proc/self/maps to stdout. I compiled this file mem.rs simply with rustc mem.rs. It printed:
stack ≈ 0x7ffffbf82f2c
.text ≈ 0x7f45b7c0a2b0
.data ≈ 0x7f45b7c4d35b
7f45b6800000-7f45b6c00000 rw-- 00000000 00:00 0
7f45b6de0000-7f45b6f9a000 r-x- 00000000 00:00 664435 /lib/x86_64-linux-gnu/libc-2.19.so
7f45b6f9a000-7f45b6fa2000 ---- 001ba000 00:00 664435 /lib/x86_64-linux-gnu/libc-2.19.so
[ ... more .so files]
7f45b7a22000-7f45b7a23000 r--- 00022000 00:00 663920 /lib/x86_64-linux-gnu/ld-2.19.so
7f45b7a23000-7f45b7a24000 rw-- 00023000 00:00 663920 /lib/x86_64-linux-gnu/ld-2.19.so
7f45b7a24000-7f45b7a25000 rw-- 00000000 00:00 0
7f45b7aa0000-7f45b7aa2000 rw-- 00000000 00:00 0
7f45b7ab0000-7f45b7ab2000 rw-- 00000000 00:00 0
7f45b7ac0000-7f45b7ac1000 rw-- 00000000 00:00 0
7f45b7ad0000-7f45b7ad1000 rw-- 00000000 00:00 0
7f45b7ae0000-7f45b7ae2000 rw-- 00000000 00:00 0
7f45b7c00000-7f45b7c5f000 r-x- 00000000 00:00 1134580 /home/lukas/tmp/mem
7f45b7e5e000-7f45b7e62000 r--- 0005e000 00:00 1134580 /home/lukas/tmp/mem
7f45b7e62000-7f45b7e63000 rw-- 00062000 00:00 1134580 /home/lukas/tmp/mem
7f45b7e63000-7f45b7e64000 rw-- 00000000 00:00 0
7ffffb784000-7ffffb785000 ---- 00000000 00:00 0 [stack]
7ffffb785000-7ffffbf84000 rw-- 00000000 00:00 0
7ffffc263000-7ffffc264000 r-x- 00000000 00:00 0 [vdso]
At least the addresses I printed on my own seem to match what maps says. But when I execute cat /proc/self/maps in the terminal, I get this output:
00400000-0040b000 r-x- 00000000 00:00 107117 /bin/cat
0060a000-0060b000 r--- 0000a000 00:00 107117 /bin/cat
0060b000-0060c000 rw-- 0000b000 00:00 107117 /bin/cat
0071c000-0073d000 rw-- 00000000 00:00 0 [heap]
7f7deb933000-7f7debc30000 r--- 00000000 00:00 758714 /usr/lib/locale/locale-archive
7f7debc30000-7f7debdea000 r-x- 00000000 00:00 664435 /lib/x86_64-linux-gnu/libc-2.19.so
7f7debdea000-7f7debdf2000 ---- 001ba000 00:00 664435 /lib/x86_64-linux-gnu/libc-2.19.so
[ ... more .so files ...]
7f7dec222000-7f7dec223000 r--- 00022000 00:00 663920 /lib/x86_64-linux-gnu/ld-2.19.so
7f7dec223000-7f7dec224000 rw-- 00023000 00:00 663920 /lib/x86_64-linux-gnu/ld-2.19.so
7f7dec224000-7f7dec225000 rw-- 00000000 00:00 0
7f7dec250000-7f7dec252000 rw-- 00000000 00:00 0
7f7dec260000-7f7dec261000 rw-- 00000000 00:00 0
7f7dec270000-7f7dec272000 rw-- 00000000 00:00 0
7ffff09e8000-7ffff11e8000 rw-- 00000000 00:00 0 [stack]
7ffff1689000-7ffff168a000 r-x- 00000000 00:00 0 [vdso]
The latter result matches everything I read about this topic: the sections from the executable are mapped in the lower end of the virtual address space (beginning around 0x400000).
I executed and compiled everything in the Linux Subsystem for Windows (Ubuntu 14.04 basically). I know, it's new and stuff, but I'm fairly sure this is not an issue with the subsystem (please tell me if it is, though!). Rust 1.14 is that matters (I doubt it),
I also tried the same with a C program (excuse my probably bad C):
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv) {
FILE *test_file;
char buf[4096];
if ((test_file = fopen ("/proc/self/maps", "r")) != NULL) {
while (!feof (test_file)) {
fgets (buf, sizeof (buf), test_file);
puts (buf);
}
}
return 0;
}
It outputs something similar to cat:
00400000-00401000 r-x- 00000000 00:00 1325490 /home/lukas/tmp/a.out
00600000-00601000 r--- 00000000 00:00 1325490 /home/lukas/tmp/a.out
00601000-00602000 rw-- 00001000 00:00 1325490 /home/lukas/tmp/a.out
Why is the Rust executable mapped to large addresses near the stack?
Using rustc -Z print-link-args addr.rs, you can see what linker invocation the Rust compiler will use. Since the current linker happens to be cc, we can directly reuse these options for the C program. Ignoring unimportant arguments and removing others one-by-one, I was left with this compiler invocation:
gcc -fPIC -pie addr.c -o addr-c
Compiling the C code like this produces similar addresses as the Rust-compiled executable, indicating that one or both of those options is a likely culprit. This changes the question to "why does -fPIC and/or -pie map to such high addresses?"
I found another question and answer that seems to shed light on that:
The PIE binary is linked just as a shared library, and so its default load address (the .p_vaddr of the first LOAD segment) is zero. The expectation is that something will relocate this binary away from zero page, and load it at some random address.
Using readelf -e on the Rust executable, we can see that the first LOAD segment does have a virtual address of zero:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x000000000005e6b4 0x000000000005e6b4 R E 200000
LOAD 0x000000000005ead0 0x000000000025ead0 0x000000000025ead0
0x00000000000039d1 0x00000000000049e8 RW 200000
I guess that this then changes the question to "why are these random addresses chosen", but I'm not sure of that answer. ^_^ A hunch tells me that ASLR comes into play. This other answer seems to bear that out:
PIE is to support ASLR in executable files.
ASLR is a security technique to help harden programs against certain types of attacks, so it makes sense that Rust, with its safety-minded approach, would attempt to enable something like this by default. Indeed, the addresses change a small bit each invocation:
root#97bcff9a925c:/# ./addr | grep 'r-xp' | grep 'addr'
5587cea9d000-5587ceafc000 r-xp 00000000 00:21 206 /addr
561d8aae2000-561d8ab41000 r-xp 00000000 00:21 206 /addr
555c30ffd000-555c3105c000 r-xp 00000000 00:21 206 /addr
55db249d5000-55db24a34000 r-xp 00000000 00:21 206 /addr
55e988572000-55e9885d1000 r-xp 00000000 00:21 206 /addr
560400e1b000-560400e7a000 r-xp 00000000 00:21 206 /addr
Test is on the 32 bit Linux
The code is as below:
int foo(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int e = 0;
int d = foo(1, 2);
printf("%d\n", d);
scanf("%d", &e);
return 0;
}
and when I use cat /proc/pid/maps to see the memory layout, it seems that I can see three
text segment for my code and the library.
ubuntu% cat /proc/2191/maps
08048000-08049000 r-xp 00000000 08:01 1467306 /home/shuai/work/asm/test1
08049000-0804a000 r--p 00000000 08:01 1467306 /home/shuai/work/asm/test1
0804a000-0804b000 rw-p 00001000 08:01 1467306 /home/shuai/work/asm/test1
09137000-09158000 rw-p 00000000 00:00 0 [heap]
b75c6000-b75c7000 rw-p 00000000 00:00 0
b75c7000-b776b000 r-xp 00000000 08:01 3149924 /lib/i386-linux-gnu/libc-2.15.so
b776b000-b776d000 r--p 001a4000 08:01 3149924 /lib/i386-linux-gnu/libc-2.15.so
b776d000-b776e000 rw-p 001a6000 08:01 3149924 /lib/i386-linux-gnu/libc-2.15.so
b776e000-b7771000 rw-p 00000000 00:00 0
b7780000-b7784000 rw-p 00000000 00:00 0
b7784000-b7785000 r-xp 00000000 00:00 0 [vdso]
b7785000-b77a5000 r-xp 00000000 08:01 3149914 /lib/i386-linux-gnu/ld-2.15.so
b77a5000-b77a6000 r--p 0001f000 08:01 3149914 /lib/i386-linux-gnu/ld-2.15.so
b77a6000-b77a7000 rw-p 00020000 08:01 3149914 /lib/i386-linux-gnu/ld-2.15.so
bfd47000-bfd68000 rw-p 00000000 00:00 0 [stack]
Could any one give me some guide about this issue? Thank you a lot!
Please mind the values in columns 3 (starting offset) and 2 (permissions). Really you have the same part mapped twice, in lines 1 and 2 for your binary file, but, in line 3, it's different. It's permitted to map the same file separately multiple times; different systems could skip merging this into one VM map entry, so it could reflect mapping history but not the current state jist.
If you see at library mappings you could easily find the law that any library is mapped separately:
With permission to read and execute: the main code which shouldn't be changed.
With permission to read: constant data area without code allowed.
With permission to read and write: it combines non-constant data area and relocation tables of shared objects.
Having the same starting 4K binary file area mapped twice could be explained with RTLD logic which differs from an arbitrary library logic due to bootstrapping needs. I don't treat it so important, more so it could easily differ on platform specifics.
Note that the three sections for each file have different permissions: read-only, read-write, and read-execute. This is for security: the code section (read-execute) can't be written to through exploits, and the segment that can be written can't be executed.
I am learning socket programming under Linux,so I make a sample program to list all the network interface,here is the code
/* print the name of interface */
#include <sys/socket.h>
#include <net/if.h>
#include <stdio.h>
int
main(void)
{
struct if_nameindex *pif;
pif = if_nameindex();
while (pif->if_index) {
printf("name: %s \t index: %d\n", pif->if_name, pif->if_index);
pif++;
}
if_freenameindex(pif);
printf("after the first if_freenameindex call\n");
return 0;
}
run it and it returns
name: lo index: 1
name: eth0 index: 2
name: eth1 index: 3
name: eth2 index: 4
*** glibc detected *** ./if: double free or corruption (out): 0x0983b420 ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6[0xb7edb624]
/lib/i686/cmov/libc.so.6(cfree+0x96)[0xb7edd826]
/lib/i686/cmov/libc.so.6(if_freenameindex+0x40)[0xb7f6f9e0]
./if[0x80484b6]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7e83455]
./if[0x80483d1]
======= Memory map: ========
08048000-08049000 r-xp 00000000 03:01 51169 /home/jcyang/src/net/gnu/if
08049000-0804a000 rw-p 00000000 03:01 51169 /home/jcyang/src/net/gnu/if
0983b000-0985c000 rw-p 0983b000 00:00 0 [heap]
b7d00000-b7d21000 rw-p b7d00000 00:00 0
b7d21000-b7e00000 ---p b7d21000 00:00 0
b7e54000-b7e60000 r-xp 00000000 03:01 73587 /lib/libgcc_s.so.1
b7e60000-b7e61000 rw-p 0000b000 03:01 73587 /lib/libgcc_s.so.1
b7e6c000-b7e6d000 rw-p b7e6c000 00:00 0
b7e6d000-b7fc2000 r-xp 00000000 03:01 82774 /lib/i686/cmov/libc-2.7.so
b7fc2000-b7fc3000 r--p 00155000 03:01 82774 /lib/i686/cmov/libc-2.7.so
b7fc3000-b7fc5000 rw-p 00156000 03:01 82774 /lib/i686/cmov/libc-2.7.so
b7fc5000-b7fc9000 rw-p b7fc5000 00:00 0
b7fd3000-b7fd5000 rw-p b7fd3000 00:00 0
b7fd5000-b7fd6000 r-xp b7fd5000 00:00 0 [vdso]
b7fd6000-b7ff0000 r-xp 00000000 03:01 73586 /lib/ld-2.7.so
b7ff0000-b7ff2000 rw-p 0001a000 03:01 73586 /lib/ld-2.7.so
bffdc000-bfff1000 rw-p bffeb000 00:00 0 [stack]
Aborted
Acoording to the GNU C Library Reference Manaul,we should use if_freenameindex to free the earily returned if_nameindex.So whats wrong?
thanks.
You should call if_freenameindex() on first pif, not the final one. for example:
struct if_nameindex *pif;
struct if_nameindex *head;
head = pif = if_nameindex();
while (pif->if_index) {
printf("name: %s \t index: %d\n", pif->if_name, pif->if_index);
pif++;
}
if_freenameindex(head);
....