GDB vs. LLDB

The LLDB Debugger

执行命令(EXECUTION COMMANDS)

  • 执行程序(无参数)

    1
    2
    3
    (gdb) run                          | (lldb) process launch
    (gdb) r | (lldb) run
    | (lldb) r
  • 带参数执行程序

    1
    2
    3
    4
    5
    6
    $ gdb --args a.out 1 2 3           | $ lldb -- a.out 1 2 3
    (gdb) run <args> | (lldb) process launch -- <args>
    (gdb) r <args> | (lldb) r <args>
    #
    (gdb) set args 1 2 3 | (lldb) settings set target.run-args 1 2 3
    (gdb) run | (lldb) run

Read More

awk 101

变量 意义 默认值
ARGC 命令行参数的个数 -
ARGV 命令行参数数组 -
FILENAME 当前输入文件名 -
FNR 当前输入文件的记录个数 -
FS 控制着输入行的字段分割符 “ “
NF 当前记录的字段个数 -
NR 到目前为止读的记录数量 -
OFMT 数值的输出格式 “%.6g”
OFS 输出字段分割符 “ “
ORS 输出的记录的分割符 “\n”
RLENGTH 被函数 match 匹配的字符串的长度 -
RS 控制着输入行的记录分割符 “\n”
RSTART 被函数 match 匹配的字符串的开始
SUBSEP 下标分割符 “\034”
$0 当前行
$1 .. $n 列号
  • awk在读取输入之前先执行BEGIN关联的语句,反之处理完所有输入的记录之后执行END关联的语句。

  • 可以使用八进制替代单引号或双引号。

  • 在awk运行规则中,patternaction可以省略其一,但不能同时省略。如果pattern省略则在输入的每一行上执行action;如果action省略则默认的action是打印行。多个rule可以使用;隔开。

  • @load关键字可以用于加载awk外部扩展(系统库文件),这样就可以链接已编译的代码,或者执行awk不支持的功能。

  • 记录分割符用于将多个记录分开,默认的记录分隔符是换行符。若要指定新的记录分隔符可以给内建变量
    RS赋值,或通过参数-F指定。

1
2
3
4
5
6
7
awk 'length($0) > 80' data # 打印长度大于80的行
awk '{ if (length($0) > max) max = length($0) } END { print max }' data # 打印最长行的长度
awk 'NR % 2 == 0' data # 打印偶数行
ls -l | awk '$6 == "Nov" { sum += $5 } END { print sum }'
awk '$1 ~ /J/' inventory-shipped # 正则匹配
awk '$1 !~ /J/' inventory-shipped # 正则不匹配
awk ’/li/ { print $0 }’ mail-list # 打印包含li的行,/*/ 中间部分为正则表达式,$0 代表行

解压安装PostgreSQL

最近工作需要用到GPDB,考虑到GPDB是基于PostgreSQL开发且协议也和后者完全兼容,所以先在Windows上搭建一个简单的环境学习下PostgreSQL。

  • 下载PostgreSQL
  • 解压到指定目录,如:D:\Tools\pgsql
  • 指定数据库文件目录,增加环境变量 PGDATA=D:\Tools\pgsql\data,后面的相关操作就无需显示指定数据文件目录
  • 初始化数据库目录:initdb.exe -E UTF8 –locale C
  • 将PostgreSQL注册Windows服务:pg_ctl.exe register
  • 启动服务

GNU ps

GNU版命令选项

常用选项 说明
-A 显示所以进程
-N 显示与指定进程不符的所有进程
-a 显示除控制进程(session leader)和无终端进程外的所有进程
-d 显示除控制进程外的所有进程
-e 显示所有进程
-C cmdlist 显示包含在cmdlist中的进程
-G grplist 显示组ID在grplist中的进程
-U userlist 显示属主的用户ID在userlist列表中的进程
-g grplist 显示会话或组ID在grplist列表中的进程
-p pidlist 显示PID在pidlist列表中的进程
-s sesslist 显示会话ID在sesslist列表中的进程
-t ttylist 显示终端ID在ttylist列表中的进程
-u userlist 显示有效用户ID在userlist列表中的进程
-F 显示更多额外输出(相对-f参数而言)
-O format 显示默认的输出列以及format列表指定的列
-M 显示进程的安全信息
-c 显示进程的额外调度信息
-f 显示完整格式的输出
-j 显示任务信息
-l 显示长列表
-o format 仅显示由format指定的列
-y 不要显示进程标记(process flag,表明进程状态的标记)
-Z 显示安全标签信息
-H 用层级格式来显示进程(树状,用来显示父进程)
-n namelist 定义WCHAN列显示的值
-w 采用宽输出模式,不限宽度显示
-L 显示进程中的线程
-V 显示PS命令的版本号

输出说明

说明
F 内核分给进程的系统标记
S 进程的状态(0代表正在运行;S代表休眠;R代表可运行,正等待运行;Z代表僵化,进程已结束但父进程不存在;T代表停止
UID 启动这些进程的用户
PID 进程的进程号
PPID 父进程的进程号
C 进程生命周期中的CPU利用率
PRI 进程的优先级(越大的数字代表越低的优先级)
NI 进程的谦让度
ADDR 进程的内存地址
SZ 假如进程被换出,所需交换空间的大致大小
WCHAN 进程休眠的内核函数地址
TTY 进程启动时的终端设备
STIME 进程启动时的系统时间
TIME 运行进程需要的累计CPU时间
CMD 启动的程序名称

ASP.NET Boilerplate v0.2.0.0 分析

AbpWebApplication派生HttpApplication,成为应用入口。该类包含唯一属性:

1
2
3
4
/// <summary>
/// Gets a reference to the <see cref="AbpBootstrapper"/> instance.
/// </summary>
private AbpBootstrapper AbpBootstrapper { get; set; }

启动

AbpWebApplication中重载Application_Start函数:

1
2
3
4
5
6
7
8
/// <summary>
/// This method is called by ASP.NET system on web application's startup.
/// </summary>
protected virtual void Application_Start(object sender, EventArgs e)
{
AbpBootstrapper = new AbpBootstrapper();
AbpBootstrapper.Initialize();
}

Read More

C#字符串Split方法分析

参考了C#源代码中String.Split的实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
using System;
using System.Diagnostics.Contracts;
using System.Linq;

namespace MySplit
{
class Program
{
static void Main(string[] args)
{
string[] result = split("we are families.",
new char[] { 'e', 'a', 'e' },
2,
StringSplitOptions.RemoveEmptyEntries);

result.ToList().ForEach(s => Console.Write("[{0}] ", s));
}

static string[] split(
string str,
char[] separator,
int? count = Int32.MaxValue,
StringSplitOptions options = StringSplitOptions.None)
{
return splitInternal(str, separator, count.Value, options);
}

static string[] splitInternal(
string str,
char[] separator,
int count,
StringSplitOptions options)
{
if (count < 0)
throw new ArgumentOutOfRangeException("count");

bool omitEmptyEntries = (options == StringSplitOptions.RemoveEmptyEntries);

if (count == 0 || str.Length == 0)
{
return new string[0];
}

int[] sepList = new int[str.Length];
int numReplaces = makeSeparatorList(str, separator, ref sepList);

if (0 == numReplaces || count == 1)
{
return new string[] { str };
}

if (omitEmptyEntries)
{
return internalSplitOmitEmptyEntries(str, sepList, null, numReplaces, count);
}
else
{
return internalSplitKeepEmptyEntries(str, sepList, null, numReplaces, count);
}
}

static int makeSeparatorList(string str, char[] separator, ref int[] sepList)
{
int foundCount = 0;

if (separator == null || separator.Length == 0)
{
for (int i = 0; i < str.Length && foundCount < separator.Length; i++)
{
if (Char.IsWhiteSpace(str[i]))
{
sepList[foundCount++] = i;
}
}
}
else
{
int sepListCount = sepList.Length;
int sepCount = separator.Length;

for (int i = 0; i < str.Length && foundCount < sepListCount; i++)
{
for (int j = 0; j < sepCount; j++)
{
if (str[i] == separator[j])
{
sepList[foundCount++] = i;
}
}

}
}

return foundCount;
}

static string[] internalSplitOmitEmptyEntries(
string str,
int[] sepList,
int[] lengthList,
int numReplaces,
int count)
{
Contract.Requires(numReplaces >= 0);
Contract.Requires(count >= 2);
Contract.Ensures(Contract.Result<string[]>() != null);

int maxItems = (numReplaces < count) ? (numReplaces + 1) : count;
string[] splitStrings = new string[maxItems];

int currentIndex = 0;
int arrIndex = 0;

for (int i = 0; i < numReplaces && currentIndex < str.Length; i++)
{
if (sepList[i] - currentIndex > 0)
{
splitStrings[arrIndex++] =
str.Substring(currentIndex, sepList[i] - currentIndex);
}

currentIndex = sepList[i] + ((lengthList == null) ? 1 : lengthList[i]);

if (arrIndex == count - 1)
{
while (i < numReplaces - 1 && currentIndex == sepList[++i])
{
currentIndex += ((lengthList == null) ? 1 : lengthList[i]);
}
break;
}
}

Contract.Assert(arrIndex < maxItems);

if (currentIndex < str.Length)
{
splitStrings[arrIndex++] = str.Substring(currentIndex);
}

string[] stringArray = splitStrings;
if (arrIndex != maxItems)
{
stringArray = new string[arrIndex];
for (int j = 0; j < arrIndex; j++)
stringArray[j] = splitStrings[j];
}

return stringArray;
}
static string[] internalSplitKeepEmptyEntries(
string str,
int[] sepList,
int[] lengthList,
int numReplacese,
int count)
{
Contract.Requires(numReplacese >= 0);
Contract.Requires(count >= 2);
Contract.Ensures(Contract.Result<string[]>() != null);

return null;
}
}
}