2012年3月22日 星期四

some string related tips

0. replace strings for all files in a folder
find ./ | xargs grep -l "$STRING_TO_BE_REPLACED" | xargs sed -i -e "s/$STRING_TO_BE_REPLACED/$STRING_TO_REPLACE/g"

0. find files and then grep som key word
find ./ -iname '$FILE_NAMES*' | xargs grep $SEARCH_KEY_WORDS

0. find files and then remove
find ./ -iname '$FILE_NAMES*' | xargs rm -rf

0. find and push multiple files from adb
find ./ -iname *.ko  | xargs -t -i adb push {} /system/lib/modules/

0. Search multiple words in VIM
/\(kernel\|panic\);  you will search both kernel and panic at the same time

0. Copy and rename multiple filse
for i in `find ./ -iname "*file_name*"`; do cp $i `echo $i | sed "s/$STRING_TO_BE_REPLACED/$STRING_TO_REPLACE/g"`; done

2011年12月26日 星期一

Note about kobjects, ksets, and ktypes.

kobject, quoted form kernek documentation: (example in samples/kobject/kobject-example.c)
1. A kobject must be initialized. for example
void kobject_init(struct kobject *kobj, struct kobj_type *ktype);
The ktype is required for a kobject to be created properly, as every kobject
must have an associated kobj_type.

2. After calling kobject_init(), to regsiter the kobject with sysfs, kobject_add() must be called
int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...);
This setup the parrent of the kobject and the name for the kobject properly. If the kobject is to be associated with a specific kset, kobj->kset must be assigned before calling kobject_add(). If a kset is associated with a kobject, then the parent for the kobject can be set to NULL in the call to kobject_add() andthen the kobject's parent will be the kset itself.
or call int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
struct kobject *parent, const char *fmt, ...); to init and add kobject to the kernel at the same time.

3. To inform userspace that a kobj has been created, call
int kobject_uevent(struct kobject *kobj, enum kobject_action action);

4. To create a simple directory in the sysfs hierarchy and not to mess with the whole complication of ksets, show and store functions, call
struct kobject *kobject_create_and_add(char *name, struct kobject *parent);
It creates a kobject and place it in sysfs in the location underneath the specified parent kobject.

5. To release a kobject, don't do kfree() but kobject_put(). A good practice is to use kobject_put() as an error check after kobject_init() to avoid errors creeping in.

6. Every kobject must have a release() method and the release() method is not stored in the kobject itself but associated with the ktype. for example:
struct kobj_type {
void (*release)(struct kobject *);
const struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
This structure must be referenced when you call kobject_init() or kobject_init_and_add()..

2011年11月23日 星期三

git remote; github

Commands help you manage remotes:

add:
git remote add project git://github.com/user/project.git
This will create "project" pointing to git://githun.com/user/project.git

rename:
git remote rename project test
This renames "project" to "test" in a remote and it's remote-tracking branches

rm:
git remote rm project
This deletes "project" remote and any remote-tracking branches we've fetched.

change url:
git remote set-url example git://github.com/user/test.git
This sets the URL of the remote named "example" to git://github.com/user/test.git


git shortcut

git diff --staged; git diff --cached
0. To diff HEAD and added but not committed files

git format-patch -1 SHA1
0. To patch only this commit

git --abbrev-commit --pretty=oneline
0. To shorten SHA1 number and show only one line of commit logs

2010年6月1日 星期二

VIM 修改 ^M 換行的指令

在windows版本的gvim/vim底下
:% s/\r//g

在linux based的vim底下
:% s/^M//g

其中^M 的输入用 Ctrl+v, Ctrl+m。

會有這樣的不同是因為Ctrl+v在windows是貼上@@

2010年4月14日 星期三

cross compile ssh daemon(dropbear) for arm

1. Get zlib(included by dropbear)
#wget http://www.zlib.net/zlib-1.2.3.tar.gz
#tar zxvf zlib-1.2.3.tar.gz
#mkdir zlib
#cd zlib-1.2.3/
#CC=arm-none-linux-gnueabi-gcc ./configure --prefix=/zlib
#make
#make install

2. Get dropbear source
#wget http://matt.ucc.asn.au/dropbear/releases/dropbear-0.51.tar.gz
#tar zxvf dropbear-0.51.tar.gz
#mkdir dropbear-build
#cd dropbear-build/
#mkdir build
#../dropbear-0.51/configure --prefix=/build/ \
--with-zlib=/zlib/ CC=arm-none-linux-gnueabi-gcc --host=arm-none-linux-gnueabi LDFLAGS=-static
#make
#sudo make install

3. Copy dbclient, dropbearconvert, dropbearkey, and dropbear binarys to your file system and generate the cpio.gz file(Under build/bin and build/sbin, if you are not using a emulator, do not generate cpio.gz file :))

4. In target,
#cd /etc
#mkdir dropbear
#cd dropbear
#dropbearkey -t rsa -f dropbear_rsa_host_key

if indicate "Exited: couldn't open random device", do the following
#mknod -m=666 /dev/random c 1 8
#mknod -m=666 /dev/urandom c 1 9

#dropbear(assume the binary is under /sbin)

5. Done, you should be able to run ssh client to access this machine.
(May add password if it's originally none, otherwise ssh will complain permission denied)

PS. If you encountered the following error when ssh to the target.
"PTY allocation request failed on channel 0"
"shell request failed on channel 0"
do the following:

# mkdir /dev/pts
# mknod /dev/ptmx c 5 2
# mount -t devpts devpts /dev/pts

2010年4月9日 星期五

Cross Compile gdb for x86 and gdbserver for ARM

1. Download GDB source code
2. Download toolchain. ex, you can download the toolchain binary from codesourcery.
3. you will have GDB for x86 host machine after the following:
#./configure --target=arm-none-linux-gnueabi LDFLAGS=-static --with-build-libsubdir=/usr/local/arm-2008q3/arm-none-linux-gnueabi/libc/usr/lib --disable-werror
#make
4. enter gdb/gdbserver, you will have gdbserver for ARM after the following:
#./configure --host=arm-none-linux-gnueabi --target=arm-none-linux-gnueabi LDFLAGS=-static --with-build-libsubdir=/usr/local/arm-2008q3/arm-none-linux-gnueabi/libc/usr/lib --disable-werror
#make

ps.
If make complains about no termcap library, do the following
1. Download ncurses (search the web)
2. Do the following
#./configure --host=arm-none-linux-gnueabi --target=arm-none-linux-gnueabi --prefix="$HOME/install"
#make && make install
#sudo cp ~/install/lib/libncurses.a /usr/local/arm-2008q3/arm-none-linux-gnueabi/libc/usr/lib
#sudo cp ~/install/include/ncurses/ /usr/local/arm-2008q3/arm-none-linux-gnueabi/libc/usr/include -rf

Beaware that this is because that the toolchain is not aware of the libncurses.a library though you've probably install it in the regular path. We need it for the toolchain and which is for ARM machine.
You can do
#file libncurses.a
to check if it's for your machine or for the target. The format should match to cease the complaining.

2009年10月21日 星期三

幾個好用的線上訂房網站

expedia-->全美最大。
priceline-->有個好玩的功能是可以自己去競標旅館。
hotwire-->用匿名的方式去預約旅館,一直到最後一刻才會知道你住的是哪一間,不過如果熟門熟路的已經知道那附近有哪些旅館的話,幾乎可以百發百中。

每一個網站的價格可能稍有不同,多多比較囉。

至於租車的話可以從這裡
http://www.4travelcoupons.com/car-rentals.html
裡面有各大租車公司的coupon

2009年10月6日 星期二

ARM BL instruction

syntax:
   bl function_A;
簡單說就是把下一個要執行的位置(i.e. the return address),
存到LR(r13)之後,
把function_A的位置,
存到PC中。
這樣就會跳到callee function
然後把return address存給caller function。

2009年10月3日 星期六

Businuss trip in San Diego

莫名的就來到了聖地牙哥,
大概是上禮拜三吧,

"你有美簽嗎?"
"有阿" 我說
"那麻煩你下禮拜一去一趟QualComm"
"....."

總之禮拜一的晚上我就到了QualComm在聖地牙哥的總部了。

這次是我第一次來美國出差有租車的經驗
之前都是做人家便車的,

公司規定只能租economic和compact兩種車型,
雖然說我也搞不太清楚有什麼差異
特別跟櫃台強調了要一台日本車
結果他給了我一台 Nissan Versa

我只能說車子還滿可愛的
感覺也還滿好開的
只是不太穩

感忙著去租車是因為周末有一個同事要來
所以要去接機
這個我必須要抱怨一下
為什麼不一起來就好了呢??

為了他我還特地繞了一下機場
看要怎嚜過去
探路ㄟ
又不是大學參加社團@@

下午想去逛個mall的
只是好累我就睡著了@@
不過可能也還好
因為發現要去的那個交流道車好多
大家都忙裡偷閒去買東西就對了

明天再看看吧

2009年9月29日 星期二

防止資料被初始化 in ARM environment

有的時候,資料並不想被初始化,這時候我們需要特別的指定section。在code裡面我們可以用
#pragma arm section zidata = "non_init"
int i, j;    //uninit (in non_init section)
#pragma arm section zidata   //back to default (.bss section)
int k=0, l=0;  //zero-init (in .bss section)
這樣我們就會有一個自己的section名子叫做non_init。之後在execution region中我們可以把它指定成UNINIT,好比說

LOAD_1 0x0{

EXEC_1 +0


{



* (+RO)


* (+RW)


* (+ZI) ;ZI data will be initialized to zero



}



EXEC_2 +0 UNINIT


{



* (non_init) ;ZI data will not be initialized to zero



}



}

這樣我們的i和j就不會就算不給值也不會被初始成0了。

ARM assembly 範例 and 解說

   AREA ARMex, CODE, READONLY ;Name this block of code ARMex
   ENTRY ;Mark first instruction to execute
start
   MOV r0, #10 ; Set up parameters
   MOV r1, #3
   ADD r0, r0, r1 ; r0 = r0 + r1
stop
   MOV r0, #0x18 ; angel_SWIreason_ReportException
   LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit
   SVC #0x123456 ; ARM semihosting (formerly SWI)
END ; Mark end of file

我們可以發現第一行就指定了這個section的名子,叫做ARMex。第一個AREA的意思是表示一個section
的開始,除了明子以外,還會設定這個section的屬性。名子基本上可以隨便取,可是如果不是英文字母開頭的話,就要用兩個bar把它包起來,好比說|1_DataArea|。不然的話會有AREA name missing的錯誤。


ENTRY跟AREA一樣,都是directive,顧名思義是說明一個section的開始,後面的END相對應的就是說明一個section的結束。

start和stop都是function的label。

如果是在C code裡面的話
就是 #pragma arm section [code、rwdata、rodata、zidata] = "label"

ARM assembler online reference

you can find a quick reference online through the following link

http://www.keil.com/support/man/docs/armasm/

2009年8月31日 星期一

有人離職了

一位同事離職了,其實嚴格說來是我的長官。跟他平常並沒有機會交談,一直到很後來才偶然的有機會跟他聊天。 其實,他還滿有想法的,平常也有閱讀的習慣。

這真的很難得,在上班之後還能在閒暇之虞讀點閒書。因為我認識的大部分的上班族回家之後都是發呆或躺平的。

其實想說明的是,有跟他討論到一些他正在閱讀的書,以後有時間也要去買來看。1. 雪球 2. 一個投機者的告白 3. 黑天鵝效應 4. 投資金律

2009年8月5日 星期三

Android radio interface layer

    其實Android很奇怪,明明是linux系統,ap卻偏偏要跑java。也因此,硬要多一層java與底層api間的橋樑,作為轉化劑,其中的目的就是透過android制定好的api去執行不同解決方案的modem。也因此多了很多麻煩。當然也是有他的好處,就是既然介面都訂好了,剩下的就是去配合不同的方案而產生不同的程式碼。

    底下是一張google自己的投影片,搜尋anatomy-google-io就找的到了。

    可以看到jave跟底層的溝通是透過socket和中間一個叫做rild的daemon program,這個daemon到也沒做什麼事情,只是init自己的event thread,這裡的event就是指每個socket listen到的結果,就是用select()去聽socket,有結果就做對應的事情。說穿了也就是收jave來的request和要送給java的request result。然後呢,他會去load oem的radio library並且做library的init,除了初始library的狀態之外,還會得到一組library必須提供的call back function的address然後利用這組call back functino跟library溝通。定義了五支call back。ex: onRequest(); onRequestComplete()之類的。

    如果是我,在這樣的情形之下,我會怎麼設計我的radio library呢?首先一定是來兩個queue,伴隨著相對應的兩支worker thread,一個處理daemon送來的request,然後往下送,另一個則相反,處理底層來的事件然後回送給daemon。這樣雖然複雜,但是萬無一失,屬於標準設計,library自我隔離於外界,專心於處理本份之上。

    所以每個onRequest()都會把資料put到library中處理request的queue然後給library的thread去按照順序楚哩。因為有了queue所以每個request會是mutual exclusive,因為我們可以等該request處理完畢之後,才去處理下一個。這樣也模擬了android原本對底層telephony的精神,也就是at command,而at command是mutual exclusive的。
    否則的話,如果有某個request的執行必須依賴之前的request的執行的結果的話,會有可能的錯誤發生,好比說在end call之後來一個switch call,那這個switch的request要不要被執行呢??
    而這,就會是推託爭執與各說各話的起點了。
    讓我想到夫妻與男女朋友的相處之道。

2008年11月30日 星期日

install iPhone opensource toolchain in Windows cygwin

先準備下面的東西:
1. firmware檔, 我用1.1.4的,這個是要抓iphone的filesystem要用。抓下來會是ipsw檔, 把檔名改成.rar 然後抓裡面的022-3894-4.dmg下來。
這是加密過的檔案,要先解密才行
解密的工具
解密的指令
vfdecrypt -i 022-3894-4.dmg -o dec-1.1.4.dmg -k \ d0a0c0977bd4b6350b256d6650ec9eca419b6f961f593e74b7e5b93e010b698ca6cca1fe 然後再用transmac mount上去。
2. odcctool 的patch
3. 用transmac抓下來的檔案不會preserve sybolic link, 要自己改回來。不過已經有好心人幫我們弄好一包了,在這,解壓縮密碼是 aksblog.co.nr。
4. Mac OS X 10.4 Universal SDK,解壓縮密碼是 aksblog.co.nr。

步驟
基本上按照http://code.google.com/p/iphone-dev/wiki/Building上面的步驟做。

除了以下要注意
1. 在build odcctool的時候,先執行patch
patch -p0 <odcctools_cygwin.patch
mv include/foreign/machine \include/foreign/_machinethen
到然後config, make, make install

2. 在裝header的時候,SDK用 gunzip -c MacOSX10.4u.sdk.pax.gz cpio -i 解壓縮,要先把RAR解開成pax.gz檔,你當前的目錄就是解開的SDK的目錄所在,再打指令的時候要注意。

3. 在make llvm-gcc的時候,把剛剛的lib取代iphone file system裡面的usr/lib。

差不多就是這樣,找個helloworld來試看看吧。

2008年11月28日 星期五

compile QT 4.4.3 using visual studio express

1. download VS 2008 express from MS website
2. download QT opensource edition
3. VS 安裝目錄下的VC資料夾, 執行vcvarsall.bat(或是程式集裡面的command prompt)
4. 在console下切換到QT目錄(就是解壓縮的那個目錄)
5. configure -platform win32-msvc2008 (其實可以直接config就好)
6. nmake (這個會很久)

that's it!!

2008年2月14日 星期四

Synchronization mechanisms

As we know, to run threads, we need to schedule them. In order to run them effectively, they need to be synchronized. Suppose one thread creates a brush and then creates several threads that share the brush and draw with it. The first thread must not destroy the brush until the other threads finish drawing. This requires a means of coordinating the sequence of actions in several threads. One way is to create a global Boolean variable that one thread uses to signal another. The writing thread will set this parameter to TRUE and the reading thread might loop until it sees the flag change. This will definitely work, but the looping thread wastes a lot of processor time. Instead, Win32 supports a set of synchronization objects such as mutexes, semaphores, events and critical sections. These are the system objects created by the object manager. All of them will work in a similar way. A thread that wants to perform some coordinated action waits for a response from one of these objects and proceeds only after receiving it. The scheduler removes the waiting objects from the dispatch queue so that they will not consume processor time It is important to keep in mind that:
• A mutex object works like a narrow gate for one thread to pass at a time.
• A semaphore object work like a multi-lane gate that a limited number of threads can pass through together.
• An event object broadcasts a public signal for any listening thread to hear.
• A critical section object works like a mutex but only within a single process. Mutexes, semaphores and events can coordinate threads in different processes, but critical sections are only visible to threads in a single process.
Mutexex: These are very much like critical sections except that they can be used to synchronize data across multiple processes. To do this, a thread in each process must have its own process-relative handle to a single mutex object. Semaphores: These objects are used for resource counting. They offer a thread the ability to query the number of resources available; if one or more resources are available, the count of available resources is decremented. Thus semaphores perform the test and set operations automatically, that is, when you request a resource from a semaphore, the operating system checks whether the resource is available and decrements the count of the available resources without letting another thread interfere. Only after the resource count has been decremented does the system allow another thread to request a resource. For example, let us say that a computer has three serial ports. No more than three threads can use the serial ports at any given time; each port can be assigned to one thread. This situation provides a perfect opportunity to use a semaphore. To monitor serial port usage, you can create a semaphore with a count of three - one for each port. A semaphore is signaled when its resource count is greater than zero and is non-signaled when the count is zero. Because several threads can affect a semaphore's resource count, a semaphore, unlike a critical section or mutex, is not considered to be owned by a thread. This means that it is possible to have one thread wait for the semaphore object and another thread release the object. Events: Even objects are the most primitive form of synchronization objects and they are quite different from mutexes and semaphores. Mutexes and semaphores are usually used to control access to data, but events are used to signal that some operation has been completed. There are two different types of event objects - manual reset events and auto reset events. A manual reset event is used to signal several threads simultaneously to say that an operation has finished, and an auto reset event is used to signal a single thread to say that an operation has been completed. Events are most commonly used when one thread performs initialization work and, when it finishes, signals another thread to perform the remaining work. The initialization thread sets the event to the non-signaled state and begins to perform the initialization. Then, after the initialization has been completed, the thread sets the event to the signaled state. Waiting for the event, the worker thread wakes up and performs the rest of the work. For example, a process might be running two threads. The first thread reads data from a file into a memory buffer. After the data has been read, the first thread signals the second thread that it can process the data. When the second thread finishes processing the data, it might need to signal the first thread again, so that the first thread can read the next block of data from the file. Critical sections: A critical section is a small section of the code that required exclusive access to some shared data before the code can execute. Of all synchronization objects, critical sections are the simplest to use, but they can be used to synchronize threads only within a single process. Critical sections allow only one thread at a time to gain access to a region of data.

原出處
http://chinese-school.netfirms.com/forums/synchronizing-threads-in-windows-vt127.html

2008年1月31日 星期四

Windows CE Virtual Memory Layout for Debugging

quote from http://blogs.msdn.com/sloh/archive/2005/02/25/380475.aspx

I want to blog about how to resolve symbols manually, and realized I would have to assume that the reader would understand the CE VM layout. So I figure I’d better explain that first. You don’t need to know everything about the VM layout in order to work with Windows CE, but it can be handy at times to at least understand the basics. You need to understand some of it in order to be effective at debugging.
There are a few spots in this discussion that I could go into more “whys” but I avoided them because the answers aren’t necessary in order to debug. We can discuss them separately if they bug you.
Anybody who has worked with CE for very long knows that there are a maximum of 32 processes, and each process gets a maximum of 32MB of virtual address space to work inside. Part of the reason for that is because Windows CE keeps all processes’ address spaces available at all times, even when those processes are not running. What it means is that the lower part of the address space is split into 32MB “slots.” The important details to internalize are:
32MB in hex is 0x02000000
Slot 0 is 0x00000000 through 0x01FFFFFF
Slot 1 is 0x02000000 through 0x03FFFFFF
The last process ends at 0x41FFFFFF
Memory from 0x42000000 to 0x7FFFFFFF is mostly the “shared area” used for VirtualAllocs and memory-mapped files. In other words there will never be any symbols there.
Memory above 0x80000000 is “kernel stuff” – the kernel does run there, as well as DLLs that load into the kernel, like installable interrupt service routine (ISR) DLLs.
If you do the math, that adds up to 33 slots. Slots 0 & 1 are special slots that aren’t used by processes, and I’ll explain that in a bit. That leaves 31 slots for process to run inside – and the 32nd process is the kernel, which lives elsewhere in RAM somewhere above the 0x80000000 mark. [OK detail hounds, in CE 3.0 and earlier, the kernel ran in slot 1 instead of in the upper 2GB.]
Slot 0 is a special slot whose contents change depending on what process is running. The current process is always mapped into slot 0 in addition to having its own unique slot. Most of the addresses a processes is given to work with, are in slot 0. Get the address of a variable or function from an EXE in the debugger, and you’ll see something like 0x00012345. But if that variable is from a process that’s running in the slot from 0x12000000 to 0x13FFFFFF, that same variable will be present at address 0x12012345.
Try it out. Break into the debugger while your EXE is running. Use the Modules & Symbols Window to figure out what slot your process is in, then change a slot 0 address into one from the process slot and see if you get the same data.
Understanding slot 0 is actually very important for debugging. If you hit the “break” button at a random time, your process might not be running at that time. If you use the Watch Window to try to look at a global variable inside your process – the debugger might know what address the variable is at, without knowing the value of the variable. For example, John Eldridge already blogged a bit about how to use the Watch Window to look at a variable inside a specific module. Suppose you did this:
Watch Window {,,helloworld.exe} &MyGlobalVar 0x00012345 {,,helloworld.exe} MyGlobalVar ??? If helloworld.exe isn’t the process that’s running at the moment you break into the debugger, the debugger knows what the address of the global variable is, but not the value. But you can manually map the slot 0 address to the right slot, if you know what slot the process is running in. If helloworld.exe is running in the slot starting at 0x12000000, then you can add the slot start address to the slot 0 address, like this:
Watch Window {,,helloworld.exe} &MyGlobalVar 0x00012345 {,,helloworld.exe} MyGlobalVar ??? *((DWORD*)0x12012345) 72
(yes, that’s not a DWORD-aligned address, please close your eyes if it bugs you)
Also, if you switch the debugger to helloworld.exe, it can figure things out. I usually use the Callstack Window and select a thread from helloworld.exe to switch to. Then the contents of the Watch Window might change.
Watch Window {,,helloworld.exe} &MyGlobalVar 0x00012345 {,,helloworld.exe} MyGlobalVar 72 The difference is that now the slot 0 address refers to the same slot the debugger is currently pointed at.
Slot 1 is also a special slot. All DLLs that are stored in the “MODULES” section of ROM load in slot 1. The code – not the data – for as many DLLs as possible loads in slot 1. Only ROM DLLs load in slot 1. If you drop a new copy of a DLL onto a device, to replace a DLL that was in ROM, that new DLL will not load in slot 1.
Check it out. Open the Modules & Symbols Window and view the addresses that various DLLs are loaded at. Some will be in slot 0, some will be in slot 1. A few will be in the kernel range.
So now look back at the addresses John Eldridge posted on his blog entry, and you can see that the DLL addresses he posted were all from slot 1.
Slot 1 stays the same no matter what the current process is. That’s why only code can load there; if two processes load the same slot 1 DLL, they will share the same code, but the two instances of the DLL will have different globals. The globals are stored in the process slot – so they will most often be referenced in slot 0 just like everything else the process owns.
The main point to all of this description of slot 0 & 1 is that you need to understand when the memory you need to look at is process-specific, and how to view process-specific memory. If a DLL loads into multiple processes, and you want to look at a global variable inside the DLL, the value could be different in different processes. You need to know which process you’re looking at, and how to change it if necessary.
One other detail that’s handy to know, is that EXE code loads at the very bottom of the slot (closest to 0x00000000), while DLL code & data load from the top of the slot down (closest to 0x1FFFFFFF). In between are heap allocations, thread stacks, small VirtualAllocs, and other “goodies” that don’t have symbols.
With practice you will develop one of the ninja debugging skillz: recognizing the location of an address just by looking at it. Here’s some practice:
0x00012345 is probably code or global variables from an EXE. 0x0056789A is probably not. Why? Too big, that’s a gigantic EXE. It’s more likely to be stack or heap, some other dynamically allocated memory, not EXE or DLL contents. It’s easy to ballpark if you can look at the actual size of the EXE.
0x03123456 is a slot 1 DLL. So is 0x02123456.
Address 0x3456789A is inside the process that’s running in the slot that starts at 0x34000000; you can use the Modules and Symbols window to figure out which process that is. But it’s most likely not code or global variables – for the exact same reason as 0x0056789A in my first bullet. This is just a “slot-mapped” version of the same address.
Address 0x019ABCDE is probably from a DLL. It's near the top of the slot so it's more likely to be a DLL than heap or stack. The same with 0x3519ABCDE. Get used to noticing whether the 2nd nibble of the address is odd or even.
Address 0x6789ABCD is not from a module. Maybe something from VirtualAlloc or a memory-mapped file, but you’ll never find a symbol that matches that address.
While we’re at it, okay, I am using bad sample addresses. 0x00012345 is not DWORD-aligned. Things are much more likely to be aligned on a 4-byte boundary: ending in 0, 4, 8 or C. Using consecutive numbers just seems more “friendly” to me, so I’m sorry if that bugs you. If you noticed, then you already have some ninja debugging skillz. It’s a good thing to be attuned to, since non-x86 processors can’t cope with accessing 4-byte values that are not 4-byte aligned.
Doug Boling, one of our MVPs, has written a paper that explains the virtual address space, and its implications, in much more detail. You should review that if you have more questions. I was just trying to cover the aspects that are important for debugging.
Next I’ll write about how to resolve symbols for addresses (how to go from address --> symbol), and after that I’ll write about the other direction, how to figure out an address for a particular function or variable (symbol --> address).