nullfxp 新分支

2008年03月05日 Wednesday

最近的libssh2协议库开发进度缓慢,还有另一些据点,如只实现了ssh2协议部分等。

我准备新建立一个使用 putty的分支,试试效果怎么样。

svn 源码版本控制使用体会

2007年11月28日 Wednesday

我的nullfxp项目使用的svn有三个多月了,越来越感觉这东西的重要性了,甚至有点离不了。

现在使用了svn中的许多功能了,像tags,开支开发,版本回溯,异地维护代码的一致性等。我现在无论在哪都可以通过这个svn维护项目了,测试svn中项目的最新版本,查看以前某一版本的特性,修改提交bug。

由于现在项目只我一人在维护,现在还没有碰到过像版本冲突的及处理的问题,多分支开发与合并的问题,还有我现在还不知道的一些高级功能,多人协作功能,这些才是svn的核心用途,以后有机会再回来讨论。

linux 下 iconv 函数的使用

2007年10月30日 Tuesday

  #include <iconv.h>

size_t iconv(iconv_t cd,  char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);

iconv -l 命令列出支持的转换码表。

注意的问题:

iconv的man有点问题。iconv返回的实际上不是成功的数目。0只是说明成功。

iconv返回0就说明字符序列全部已经转换成功,pin和pout指针都会变化的。

信号与槽进阶

2007年10月15日 Monday

信号与槽进阶

信号与槽的机制是 Qt 编程的基础。它使得应用程序程序员将对象与对象无隔阂的绑定在一起。我们已经将一些信号和槽连接在一起,声明了自己的信号和槽并实现了我们自己的槽,发出了自己信号。让我们花一些时间来仔细研究一下这一机制。

槽和普通的 C++ 成员函数几乎完全相同。它们可以使虚函数;可以被重载;可以是公开、保护或私有的,它们可以象其它 C++ 成员函数一样被直接调用;并且参数可以是任何数据类型。不同的是一个槽可以被连接到一个信号,在这种情况下当信号发出时它可以被自动调用。

connect() 语句看起来是这样的:

connect(sender, SIGNAL(signal), receiver, SLOT(slot));

 

sender receiver 是指向 QObjects 的指针,signal slot 是不带参数名的函数签名。SIGNAL() SLOT() 宏本质上将它们的参数转化成字符串。

在我们已经看到的例子中,我们总是连接不同的信号和不同的槽,其实,还有其它可能的选择。

  • 一个信号可以被连接到多个槽上:

connect(slider, SIGNAL(valueChanged(int)),

spinBox, SLOT(setValue(int)));

connect(slider, SIGNAL(valueChanged(int)),

this, SLOT(updateStatusBarIndicator(int)));

 

当信号发出时,槽会按一个非特定的顺序被轮流调用。

  • 多个信号可以被连接到同一个槽上:

connect(lcd, SIGNAL(overflow()),

this, SLOT(handleMathError()));

connect(calculator, SIGNAL(divisionByZero()),

this, SLOT(handleMathError()));

当任何一个信号发出时,槽都会被调用。

  • 一个信号可以被连接到另一个信号上:

connect(lineEdit, SIGNAL(textChanged(const QString &)),

this, SIGNAL(updateRecord(const QString &)));

当地一个信号被发出时,第二个信号也会发出。除此之外,信号与信号的连接和信号与槽的连接没有任何不同。

  • 连接可以被取消:

disconnect(lcd, SIGNAL(overflow()),

this, SLOT(handleMathError()));

这不是必需的,因为当对象被删除后 Qt 会自动取消与对象相关的连接。

要成功连接一个信号到一个槽 (或到另一个信号)上,你必需拥相同的参数类型和顺序:

connect(ftp, SIGNAL(rawCommandReply(int, const QString &)),

this, SLOT(processReply(int, const QString &)));

 

另外,如果一个信号比要连接槽拥有更多的参数,多余的参数会被简单的忽略掉:

connect(ftp, SIGNAL(rawCommandReply(int, const QString &)),

this, SLOT(checkErrorCode(int)));

 

如果参数类型不兼容,又或者信号或槽不存在,如果应用程序在调试模式下编译Qt 会发出一个运行时警告。同样的,如果参数名被包含进信号或者槽的签名,Qt 会给出一个警告。

到目前为止,我们只用到了物件的信号与槽。但是信号与槽的机制本身是在 QObject 中实现的并且不仅仅用在 GUI 编程上。这个机制可以被 QObject 任何子类使用。:

class Employee : public QObject

{

Q_OBJECT

public:

Employee() { mySalary = 0; }

int salary() const { return mySalary; }

public slots:

void setSalary(int newSalary);

signals:

void salaryChanged(int newSalary);

private:

int mySalary;

};

void Employee::setSalary(int newSalary)

{

if (newSalary != mySalary) {

mySalary = newSalary;

emit salaryChanged(mySalary);

}

}

 

注意 setSalary () 是如何实现的。我们只发出 salary-Changed() 信号 if newSalary != mySalary。这确保循环连接不会进入死循环。

Qt 的元对象系统

One of Qt’s major achievements has been the extension of C++ with a mechanism for creating independent software components that can be bound together without any component knowing anything about the other components it is connected to.

The mechanism is called the meta-object system, and it provides two key services: signalsslots and introspection. The introspection functionality is necessary for implementing signals and slots, and allows application programmers to obtain “meta-information” about QObject subclasses at run-time, including the list of signals and slots supported by the object and its class name. The mechanism also supports properties (for Qt Designer) and text translation (for internationalization), and it lays the foundation for Qt Script for Applications (QSA).

Standard C++ doesn’t provide support for the dynamic meta-information needed by Qt’s meta-object system. Qt solves this problem by providing a separate tool, moc, that parses Q_OBJECT class definitions and makes the information available through C++ functions. Since moc implements all its functionality using pure C++, Qt’s meta-object system works with any C++ compiler.

这个机制象下面这样工作:

  • The Q_OBJECT macro declares some introspection functions that must be implemented in every QObject subclass: metaObject(), TR(), qt_metacall(), and a few more.

  • Qt’s moc tool generates implementations for the functions declared by Q_OBJECT and for all the signals.

  • QObject member functions such as connect() and disconnect() use the introspection functions to do their work.

All of this is handled automatically by qmake, moc, and QObject, so you rarely need to think about it. But if you are curious, you can check out the QMetaObject class documentation and have a look at the C++ source files generated by moc to see how the implementation works.

 

创建 QDialog 的子类

2007年10月10日 Wednesday

这一章将教你如何利用 Qt 创建对话框。对话框向用户提供选项(options)和选择(choices),允许用户设置他们喜欢的选项值并做出他们的选择。它们之所以被称为对话框或者简单的称为对话,是因为它们提供了一种用户和应用程序用来相互对话的方式。大多数 GUI 应用程序是由一个主窗口、一个菜单栏、若干工具栏和一些作为主窗口补充的对话框构成。单独创建通过适当的行为直接响应用户的选择的对话框程序也是可能的(比如,一个计算器程序)。首先,我们将通过手写代码创建一个仅有对话框的应用程序向你展示它是怎样被完成的。然后我们将看看如何用 Qt Designer —— Qt 的可视化设计工具创建对话框。用 Qt Designer 要比手写代码快很多,并且使得以后测试不同的设计和更改设计更加容易。

创建 QDialog 的子类

我们的第一个例子是一个完全用 C++ 写的搜索对话框。我们将用一个单独的类来实现这个对话框。这样做,可以使这个对话框成为一个独立的、自包含的组件,有它自己的信号与槽。

2.1. The Find dialog

源代码被分别放在两个文件:finddialog.h finddialog.cpp。我们先从 finddialog.h 开始。

1 #ifndef FINDDIALOG_H
2 #define FINDDIALOG_H
3 #include <QDialog>
4 class QCheckBox;
5 class QLabel;
6 class QLineEdit;
7 class QPushButton;

1 2 (和行27)防止这个头文件被多次包含。

3 包含了 QDialog 的定义, Qt 的对话框基类。 QDialog 继承自 Qwidget 类。

4 7 前置声明了我们将用来实现对话框的类。前置声明告诉 C++ 编译器一个类的存在,不需要给出类定义的所有细节(通常可以从头文件和文件本身找到)。很快我们将对此做进一步介绍。

接下来,我们定义一个 QDialog 的子类 FindDialog

8 class FindDialog : public QDialog
9 {
10     Q_OBJECT
11 public:
12     FindDialog(QWidget *parent = 0);

类定义开头的Q_OBJECT 宏是所有定义信号或槽的类所必需的。

构造函数 FindDialog 显示了 FindDialog 是一个典型的 Qt 物件类。parent 参数指向其父物件。默认是一个空指针,说明这个对话框没有父物件。

13 signals:
14     void findNext(const QString &str, Qt::CaseSensitivity cs);
15     void findPrevious(const QString &str, Qt::CaseSensitivity cs);

信号(signals)部分声明了当用户点击 Find 按钮后对话框将发出的两个信号。如果向上选择选项被打开,对话框发出 findPrevious() 信号;否则,它发出 findNext()信号。关键字 signals 实际上是一个宏。C++ 预处理器在它被送到编译器之前将把它转化成标准 C++Qt::CaseSensitivity 是一个取值为 Qt::CaseSensitive 和Qt::CaseInsensitive的枚举类型数据。

16 private slots:
17     void findClicked();
18     void enableFindButton(const QString &text);
19 private:
20     QLabel *label;
21     QLineEdit *lineEdit;
22     QCheckBox *caseCheckBox;
23     QCheckBox *backwardCheckBox;
24     QPushButton *findButton;
25     QPushButton *closeButton;
26 };
27 #endif

在类的私有定义(private)部分,我们定义了两个槽。要实现这两个槽,我们需要访问对话框的大部分子物件,所以我们也保存了指向他们的指针。关键词 slots,就像 signals,也是一个可以转化为一个 C++ 编译器能够识别的结构体

对于私有变量,我们前置声明了他们的类指针。这是可能的,因为他们都是指针并且我们不在头文件中存取它们,所以编译器不需要类的完整定义。当然,我们本应该包含相关的头文件(<QCheckBox>,<QLabel>,),但是利用前置声明如果可能的话可以使编译的速度稍微加快。

我们现在看看包含了 FindDialog 类实现的 finddialog.cpp 的内容

1  #include <QtGui>
2  #include “finddialog.h”

首先,我们包含了 <QtGui>,一个包含 Qt GUI 类定义的头文件。Qt由几个模块组成,每个模块都是自成一体独立的库最重要的几个模块是:QtCore, QtGui, QtNetwork, QtOpenGL, QtSql, QtSvg QtXml<QtGui> 头文件包含了作为 QtCore QtGui 模块的一部分的所有类的定义。包含这个头文件可以免去我们一个一个包含每个单独的类的麻烦。 filedialog.h 中,我们可以简单地用包含 <QtGui> 来代替 <QDialog> 的包含和QCheckBox, Qlabel, QlineEdit, QPushButton的前置声明。但是,在一个头文件中包含另一个大的头文件通常是一个不好的风格,尤其是在大型应用程序的开发中。

3 FindDialog::FindDialog(QWidget *parent)
4     : QDialog(parent)
5 {
6     label = new QLabel(tr(”Find &what:”));
7     lineEdit = new QLineEdit;
8     label->setBuddy(lineEdit);
9     caseCheckBox = new QCheckBox(tr(”Match &case”));
10     backwardCheckBox = new QCheckBox(tr(”Search &backward”));
11     findButton = new QPushButton(tr(”&Find”));
12     findButton->setDefault(true);
13     findButton->setEnabled(false);
14     closeButton = new QPushButton(tr(”Close”));

在第 4 行,我们向基类的构造函数传递 parent 参数。然后我们创建子物件。 用字符串文本作为参数调用 tr() 函数可以标记出它们来翻译成其他语言。这个函数在 QObject 和所有包含 Q_OBJECT 宏的子类中声明。用 TR() 包围用户可视的字符串是一个好的习惯,即使你没有立即将你的应用程序翻译成其他语言的打算。翻译 Qt 应用程序将在 第十七章 做详细介绍。

在字符串文本中,我们‘&’符号指示快捷键。例如,在行 11 创建了一个 Find 按钮,用户可以在支持快捷键的系统上用快捷键 Alt+F来激活它。‘&’符号还可以用来控制焦点:在第6行,我们创建了一个带有一个快捷键(Alt+W)的标签,在第8行我们设置标签的伙伴(buddy)为行编辑器。一个伙伴(buddy)是一个在标签的快捷键被按下时接受焦点的物件。所以当用户按下 Alt+W(标签的快捷键),行编辑器(标签的伙伴)将拥有焦点。

在第12行,我们调用 setDefault(true) Find 按钮设置为对话框的默认按钮。默认按钮是当用户敲回车后将被按下的按钮。在第13行,我们禁用了 Find 按钮。当一个物件被禁用,它通常灰化显示并且不再响应用户的交互。

15     connect(lineEdit, SIGNAL(textChanged(const QString &)),
16             this, SLOT(enableFindButton(const QString &)));
17     connect(findButton, SIGNAL(clicked()),
18             this, SLOT(findClicked()));
19     connect(closeButton, SIGNAL(clicked()),
20             this, SLOT(close()));

私有槽 enableFindButton(const QString &) 将在每次行编辑器中的文本有所改变的时候被调用。私有槽 findClicked() 将在用户点击 Find 按钮时被调用。当用户点击 Close 时对话框将关闭。槽 close() 是从 Qwidget 继承而来,它的默认行为是从视图中隐藏物件(而不是删除它)。稍后,我们将看一下 enableFindButton() findClicked() 的源代码。因为 QObject FindDialog 的一个祖先类,你可以省略 connect() 调用前面的 QObject:: 前缀。

21     QHBoxLayout *topLeftLayout = new QHBoxLayout;
22     topLeftLayout->addWidget(label);
23     topLeftLayout->addWidget(lineEdit);
24     QVBoxLayout *leftLayout = new QVBoxLayout;
25     leftLayout->addLayout(topLeftLayout);
26     leftLayout->addWidget(caseCheckBox);
27     leftLayout->addWidget(backwardCheckBox);
28     QVBoxLayout *rightLayout = new QVBoxLayout;
29     rightLayout->addWidget(findButton);
30     rightLayout->addWidget(closeButton);
31     rightLayout->addStretch();
32     QHBoxLayout *mainLayout = new QHBoxLayout;
33     mainLayout->addLayout(leftLayout);
34     mainLayout->addLayout(rightLayout);
35     setLayout(mainLayout);

接下来,我们用布局管理器来布局子物件。布局可以包含物件和其他布局。通过不同的组合嵌套 QHBoxLayoutsQVBoxLayoutsQGridLayouts,你可以创建一些很专业的对话框。

对于 Find 对话框,我们用了两个 QHBoxLayouts 和两个 QVBoxLayouts,就像 2.2 展示的那样,外层布局是主要布局;它在35行被安装到 FindDialog 用来响应整个对话框的行为。其它三个布局是子布局。 2.2右下角的弹簧是一个空白项 (或称伸展”)。它用来填充 Find Close 按钮下的空白,确保这两个按钮占据他所在布局的上部。

2.2. The Find dialog’s layouts

比较微妙的一点是布局管理类不是物件,相反,它继承自 Qlayout,而 QLayout则继承了QObject。图中,物件用实线框代表而布局用虚线框代表作为两者之间的区别。布局在程序运行时是不可见的。

当子布局被加入到父布局时 ( 25, 33, 34)子布局的父布局会被自动重置(reparented)然后,当主布局被安装到对话框(行 35),它会变成对话框的子布局。2.3描述了这一父子继承关系。

2.3. The Find dialog’s parentchild relationships

36     setWindowTitle(tr(”Find”));
37     setFixedHeight(sizeHint().height());
38 }

最后,我们将为对话框设置在标题栏显示的标题并为窗口设置一个固定高度,因为对话框中没有任何一个物件可以占据额外的垂直空间。 QWidget::sizeHint() 函数返回一个物件的理想大小。

以上我们完整的定义了 FindDialog 的构造函数。既然我们用 new 创建了一个对话框物件和布局,看起来我们需要写一个析构函数对每一个我们创建的物件调用 delete 。但这并不是必需的,因为 Qt 会在父对象销毁时自动释放子对象,并且子物件和布局都是 FindDialog 的派生物

现在我们看一下对话框的槽:

39 void FindDialog::findClicked()
40 {
41     QString text = lineEdit->text();
42     Qt::CaseSensitivity cs =
43             caseCheckBox->isChecked() ? Qt::CaseSensitive
44                                       : Qt::CaseInsensitive;
45     if (backwardCheckBox->isChecked()) {
46         emit findPrevious(text, cs);
47     } else {
48         emit findNext(text, cs);
49     }
50 }
51 void FindDialog::enableFindButton(const QString &text)
52 {
53     findButton->setEnabled(!text.isEmpty());
54 }

当用户点击 Find 按钮时槽 findClicked() 会被调用,Find 按钮会发出 findPrevious() findNext() 信号,这取决于向后选择 (Search backward) 选项。关键词 emit Qt 独有的;象其它 Qt 扩展它会被 C++ 预处理器转换成标准的 C++

无论何时,在用户改变行编辑器的文本的时候,槽 enableFindButton() 会被调用,如果编辑器里有文本会使按钮可用,没有则不可用。

这两个槽完善了对话框。现在我们创建一个main.cpp 文件来测试我们的uanggeFindDialog 物件:

1 #include <QApplication>
2 #include “finddialog.h”
3 int main(int argc, char *argv[])
4 {
5     QApplication app(argc, argv);
6     FindDialog *dialog = new FindDialog;
7     dialog->show();
8     return app.exec();
9 }

要编译这个程序,运行 qmake。因为 FindDialog 类的定义包含了 Q_OBJECT 宏,由 qmake 生成的 makefile 将包含运行 moc ——Qt 的元对象编译器的特殊规则(Qt 元对象系统将在下一部分讲解)。

为了使 moc 正确工作,我们必需将类的定义放到一个头文件,从实现文件中分离出来。 moc 生成的代码包含这个头文件并且添加一些 C++ 自有的魔力(magic)

运用 Q_OBJECT 宏的类必需运行 moc。这不是问题因为 qmake 会自动向makefile 添加需要的规则。但是如果你忘记用 qmake 重新生成你的 makefile 文件,并且没有运行 moc,连接器会报告一些函数没有实现就被声明了。显示信息可能相当晦涩。GCC 产生的警告象下面这样:

     finddialog.o: In function ‘FindDialog::tr(char const*, char const*)’:
     /usr/lib/qt/src/corelib/global/qglobal.h:1430: undefined reference to
     ‘FindDialog::staticMetaObject’

Visual C++ 则会这样显示:

     finddialog.obj : error LNK2001: unresolved external symbol
     “public:~virtual int __thiscall MyClass::qt_metacall(enum QMetaObject
     ::Call,int,void * *)”

如果这在你身上发生,运行 qmake 升级你的makefile,然后重新编译应用程序。

现在运行程序。如果你的系统支持快捷键,用 Alt+WAlt+CAlt+B Alt+F验证它们是否触发正确的行为。按 Tab 键浏览所有的物件。默认的 Tab 顺序是物件被创建的顺序。可以用 QWidget::setTabOrder() 改变默认顺序。.

提供一个明智的 Tab 顺序和键盘快捷键确保不喜欢(或者不能)用鼠标的用户能够充分利用这个应用程序。完全的键盘控制也被快速的打字员所欣赏。

第三章,我们将把 Find 对话框运用到真实的应用程序,并且连接 findPrevious() findNext() 信号到某些槽。

mingw qt 4.3.2 开发环境的搭建

2007年10月01日 Monday

1. 安装mingw/msys基本环境
这个环境包含了unix环境开发中用到编译器和基本构建工具,如automake,autoconf等。请注意我们在这一节中下载的所有包指的都是二进制的包。

mingw
下载 mingw-5.1.3.exe
选择E:\cross\mingw作为安装目录。选择”candidate”包并选中g++。

下载 msys-1.0.exe
选择 E:\cross\msys作为安装目录,其他选项默认即可。

MSYS Developer Toolkit
下载 MSYS-DTK 并把它也安装到 E:\cross\msys目录下。

Autotools
下载 Libtool  Autoconf Automake  的最新版本,使用解压软件解压到 E:\cross\msys目录下。

2. 准备启动 msys 系统
使用任何文本编译器编译 E:\cross\msys\etc\fstab 文件,加入下面一行:
e:/cross/mingw /mingw
这样我们安装的msys系统就可以使用  安装在 E:\cross\mingw目录下的命令,工具,和库了。

2. 几个基本库安装 , libiconv , gettext , libgpg-error,libgcrypt

现在在桌面上应该有一个MSYS的快捷方式,启动MSYS.

下载 libiconv-1.11.tar.gz 到 E:\cross\msys\home目录
cd /home
tar zxvf libiconv-1.11.tar.gz && cd libiconv-1.11
./configure –prefix=/mingw –disable-shared –enable-static
make && make install

下载 gettext-0.16.1.tar.gz 以及补丁文件 http://cvs.savannah.gnu.org/viewvc/gettext/gettext-runtime/intl/localename.c?root=gettext&r1=1.15&r2=1.16&view=patch 到 e:/corss/msys/home 目录下
cd /home
tar zxvf gettext-0.16.1.tar.gz
cd gettext-0.16.1/gettext-runtime/intl
patch -i /c/dev/download/localename.c.patch
cd ../..
./configure –prefix=/mingw –disable-shared –enable-static
make && make install

下载 libgpg-error-1.5.tar.bz2 和 补丁 http://filezilla-project.org/codesquid/w32-gettext.c.patch 到 e:/cross/home 目录下

cd libgpg-error-1.5
patch -i ../w32-gettext.c.patch -p0
./configure –prefix=/mingw –disable-shared –enable-static
make && make install

下载 ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.2.4.tar.gzhttp://filezilla-project.org/codesquid/libgcrypt.patch 到e:/cross/home 目录

解压libgcrypt-1.2.4.tar.gz

cd libgcrypt-1.2.4

patch -p0 -i ../libgcrypt.patch

echo “int main() { return 0; }” > tests/random.c

./configure --disable-shared --enable-static --disable-nls --disable-asm
make && make install
3 qt 4.3.2 编译安装
下载 ftp://ftp.trolltech.com/qt/source/qt-win-opensource-src-4.3.2.zip
将这个包解压到 e:qt
启动一个cmd窗口,确定 e:crossmingw在PATH中。
cd e:qtqt-win-opensource-src-4.3.2
configure -release -fast -qt-gif -qt-style-windowsxp -no-qt3support -platform win32-g++ -make mingw32-make
这一步配置Qt 编译相关选项,并生成qmake.exe 工具。
接下来执行:
make
ls -l bin/
将看到编码好的DLL库文件,开发库 .a 文件在 lib/ 目录下面。

				

C语言解释器,用C语言脚本程序

2007年09月30日 Sunday

站点:http://www.softintegration.com/

能用在哪些地方呢?

无意中发现一个和我们的nullfxp , webfxp类似的产品了

2007年09月30日 Sunday

http://www.radinks.com/sftp/   A feature rich graphical Secure FTP client

他这也是有一个桌面版本和web版本,不过它的web版本是用java applet 实现的。桌面版本也是java 做的。

它实现的功能也就一般情况,和我们的nullfxp没什么高度。

大伙也去它网站看看,是否能得出什么市场需求的一些信息。

发布 nullfxp 1.0.0 步骤实录

2007年09月30日 Sunday

真是太麻烦了.

我先命令把代码提交到 sf svn库中

然后再把它 export 下来,打包成 nullfxp-1.0.0.tar.gz

然后,将此 包上传到 sf 的 ftp 服务器,认领到新建立的 1.0 release 目录下。

测试下载链接。添加此release note .
再解压(为了测试包是否正常),并到此解压目录中编译程序,看编译是否能通过,编译出来的程序是否正常。

修改www.qtchina.net 的下载页面链接,修改首页的公告。

将修改好的网站代码提交到svn服务器。

########################

真是麻烦啊。怎么能简单一点呢。

写出一个超强的lighttpd模块

2007年09月29日 Saturday

终于找到问题了
在我的代码里有这么一段,
char * str ; str = …………………………..;



char * k = malloc( strlen( k ) + 1 )
strcpy( k , str )

而这段代码是在一个动态链接库中的 xxx.so
这样一来,那个strcpy之后,程序的 堆 全被写乱套了,程序就会出来下面这些乱七八糟的错误了。

######################

*** glibc detected *** /serv/lighttpd1418/sbin/lighttpd: free(): invalid next size (fast): 0×080a27d8 ***
======= Backtrace: =========
/lib/libc.so.6[0xb7e72312]
/lib/libc.so.6(cfree+0×89)[0xb7e739c9]
/serv/lighttpd1418//lib/mod_stats.so(hash_walk_func+0×360)[0xb7dda210]
/serv/lighttpd1418//lib/mod_stats.so(hash_table_map+0×3d)[0xb7ddaf3d]
/serv/lighttpd1418//lib/mod_stats.so(stat_table_dump_thread+0×129)[0xb7dd9de9]
/lib/libpthread.so.0[0xb7b38e5a]
/lib/libc.so.6(clone+0×5e)[0xb7ecc91e]
======= Memory map: ========
08048000-0806d000 r-xp 00000000 08:08 163125 /serv/lighttpd1418/sbin/lighttpd
0806d000-0806e000 rw-p 00024000 08:08 163125 /serv/lighttpd1418/sbin/lighttpd
0806e000-080b0000 rw-p 0806e000 00:00 0 [heap]
b7100000-b7121000 rw-p b7100000 00:00 0
b7121000-b7200000 —p b7121000 00:00 0
b72b6000-b72b7000 —p b72b6000 00:00 0
b72b7000-b7ab6000 rw-p b72b7000 00:00 0
b7ab6000-b7ac9000 r-xp 00000000 08:08 7996 /usr/lib/libz.so.1.2.3
b7ac9000-b7aca000 rw-p 00012000 08:08 7996 /usr/lib/libz.so.1.2.3
b7aca000-b7aee000 r-xp 00000000 08:08 2241 /lib/libm-2.5.so
b7aee000-b7af0000 rw-p 00023000 08:08 2241 /lib/libm-2.5.so
b7af0000-b7b02000 r-xp 00000000 08:08 2248 /lib/libnsl-2.5.so
b7b02000-b7b04000 rw-p 00011000 08:08 2248 /lib/libnsl-2.5.so
b7b04000-b7b06000 rw-p b7b04000 00:00 0
b7b06000-b7b0b000 r-xp 00000000 08:08 2222 /lib/libcrypt-2.5.so
b7b0b000-b7b0d000 rw-p 00004000 08:08 2222 /lib/libcrypt-2.5.so
b7b0d000-b7b34000 rw-p b7b0d000 00:00 0
b7b34000-b7b47000 r-xp 00000000 08:08 2280 /lib/libpthread-2.5.so
b7b47000-b7b49000 rw-p 00012000 08:08 2280 /lib/libpthread-2.5.so
b7b49000-b7b4b000 rw-p b7b49000 00:00 0
b7b4b000-b7ce9000 r-xp 00000000 08:08 129653 /usr/lib/libmysqlclient_r.so.15.0.0
b7ce9000-b7d2d000 rw-p 0019e000 08:08 129653 /usr/lib/libmysqlclient_r.so.15.0.0
b7d2d000-b7d2e000 rw-p b7d2d000 00:00 0
b7d2e000-b7dc2000 r-xp 00000000 08:08 7538 /usr/lib/libglib-2.0.so.0.1200.11
b7dc2000-b7dc3000 rw-p 00093000 08:08 7538 /usr/lib/libglib-2.0.so.0.1200.11
b7dc3000-b7dce000 r-xp 00000000 08:08 2235 /lib/libgcc_s.so.1
b7dce000-b7dcf000 rw-p 0000a000 08:08 2235 /lib/libgcc_s.so.1
b7dcf000-b7dd1000 r-xp 00000000 08:08 163049 /serv/lighttpd1418/lib/mod_staticfile.so
b7dd1000-b7dd2000 rw-p 00002000 08:08 163049 /serv/lighttpd1418/lib/mod_staticfile.so
b7dd2000-b7dd6000 r-xp 00000000 08:08 163051 /serv/lighttpd1418/lib/mod_dirlisting.so
b7dd6000-b7dd7000 rw-p 00003000 08:08 163051 /serv/lighttpd1418/lib/mod_dirlisting.so
b7dd7000-b7e0c000 r-xp 00000000 08:08 163119 /serv/lighttpd1418/lib/mod_stats.so
b7e0c000-b7e0d000 rw-p 00034000 08:08 163119 /serv/lighttpd1418/lib/mod_stats.so
b7e0d000-b7e0e000 rw-p b7e0d000 00:00 0
b7e0e000-b7f34000 r-xp 00000000 08:08 2210 /lib/libc-2.5.so
b7f34000-b7f35000 r–p 00125000 08:08 2210 /lib/libc-2.5.so
b7f35000-b7f37000 rw-p 00126000 08:08 2210 /lib/libc-2.5.so
b7f37000-b7f3a000 rw-p b7f37000 00:00 0
b7f3a000-b7f3c000 r-xp 00000000 08:08 2229 /lib/libdl-2.5.so
b7f3c000-b7f3e000 rw-p 00001000 08:08 2229 /lib/libdl-2.5.so
b7f3f000-b7f45000 r-xp 00000000 08:08 2286 /lib/librt-2.5.so
b7f45000-b7f47000 rw-p 00006000 08:08 2286 /lib/librt-2.5.so
b7f47000-b7f4b000 r-xp 00000000 08:08 7646 /usr/lib/libgthread-2.0.so.0.1200.11
b7f4b000-b7f4c000 rw-p 00003000 08:08 7646 /usr/lib/libgthread-2.0.so.0.1200.11
b7f4c000-b7f4d000 r-xp 00000000 08:08 163098 /serv/lighttpd1418/lib/mod_rewrite.so
b7f4d000-b7f4e000 rw-p 00000000 08:08 163098 /serv/lighttpd1418/lib/mod_rewrite.so
b7f4e000-b7f4f000 r-xp 00000000 08:08 163084 /serv/lighttpd1418/lib/mod_access.so
b7f4f000-b7f50000 rw-p 00000000 08:08 163084 /serv/lighttpd1418/lib/mod_access.so
b7f50000-b7f51000 r-xp 00000000 08:08 123783 /serv/lighttpd1418/lib/mod_indexfile.so
b7f51000-b7f52000 rw-p 00001000 08:08 123783 /s忽略 (core dumped)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

*** glibc detected *** /serv/lighttpd1418/sbin/lighttpd: malloc(): memory corruption (fast): 0×080a6c58 ***

======= Backtrace: =========

/lib/libc.so.6[0xb7ed5312]

/lib/libc.so.6[0xb7ed7637]

/lib/libc.so.6(__libc_malloc+0×85)[0xb7ed8d35]

/serv/lighttpd1418//lib/mod_stats.so(counter_incr+0×99)[0xb7e3d2b9]

/serv/lighttpd1418//lib/mod_stats.so(counter_incr_matchtable+0×57)[0xb7e3d347]

/serv/lighttpd1418//lib/mod_stats.so(counter_process_browsers+0×53)[0xb7e3d3c3]

/serv/lighttpd1418//lib/mod_stats.so[0xb7e3db65]

/serv/lighttpd1418/sbin/lighttpd(plugins_call_handle_uri_clean+0×5a)[0×805fe2a]

/serv/lighttpd1418/sbin/lighttpd(http_response_prepare+0×2ff)[0×804fdaf]

/serv/lighttpd1418/sbin/lighttpd(connection_state_machine+0×2f1)[0×8052b11]

/serv/lighttpd1418/sbin/lighttpd(main+0×10a0)[0×804e760]

/lib/libc.so.6(__libc_start_main+0xdc)[0xb7e86ebc]

/serv/lighttpd1418/sbin/lighttpd[0×804d331]

在网上没找到一点关于这个问题的解释。