首先让我们踏着欢快的脚步去Github创建一个新库,这里取名 composer-car,又欢快的将它克隆到本地:

git clone https://github.com/GeHou/composer-car.git

cd composer-car

这个composer-car文件夹就是你的包的root目录了,你只需要记住composer.json在包的哪个目录下面,一般那就是包的root目录了。什么?做包子的工作台?这么理解呢也是可以的,不过同学能先收收你的口水么。

现在我们还没有composer.json文件,你可以根据composer文档生成并编辑它,当然composer贴心的为我们准备了命令行,look:

-> composer init

Welcome to the Composer config generator

This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [hou/composer-car]: 这里填写<包提供者>/<包名>的信息
Description []: 包的描述
Author [GeHou <***@gmail.com>]: 作者信息
Minimum Stability []: 最低稳定版本
License []: 授权协议

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? no
Would you like to define your dev dependencies (require-dev) interactively [yes]? no

{
    "name": "hou/composer-car",
    "description": "In order to study composer",
    "license": "MIT",
    "authors": [
        {
            "name": "GeHou",
            "email": "***@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {

    }
}

Do you confirm generation [yes]? yes
Would you like the vendor directory added to your .gitignore [yes]? yes

虽然经过以上的一番挣扎生成了composer.json文件,不过我们还得往里面加点东西。使用你熟悉的编辑器打开composer.json文件修改至如下:

{
    "name": "hou/composer-car",
    "description": "In order to study composer",
    "license": "MIT",
    "authors": [
        {
            "name": "GeHou",
            "email": "***@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {
        "php": ">=5.3.0"
    },
    "autoload": {
        "psr-4": {
            "Ford\\Escape\\": "src/Ford/Escape",
            "Ford\\Fusion\\": "src/Ford/Fusion",
            "Ford\\Focus\\": "src/Ford/Focus",
            "Ford\\Fiesta\\": "src/Ford/Fiesta"
        }
    }   
}

细心的小伙伴可能已经认出了福特的商标(Ford),这说明我们都是同道中人,你一定也很喜欢汽车,对吧对吧? 🙂

我们登陆一下福特的网站看看都有哪些热销车型,嗯嗯分别有ESCAPE、FUSION、FOCUS、FIESTA,中文名称分别是翼虎、蒙迪欧、福克斯、嘉年华,嘉年华ST我的梦想啊~~~ 好了好了,那位看官放下你手里的板砖,我承认一说到汽车就会滔滔不绝,下面我们把水分挤出去继续讲解。

根据上面的命名空间和目录的映射关系,包的结构现在应该是下面这个样子:

composer-car
- src
- - Ford
- - - Escape
- - - - Escape2013.php
- - - Fiesta
- - - - Fiesta2013.php
- - - Focus
- - - - Focus2013.php
- - - Fusion
- - - - Fusion2013.php
- .gitignore
- composer.json
- README.md

Escape2013.php:

<?php

namespace Ford\Escape;

class Escape2013
{
    public static function info()
    {
        echo "This is Ford Escape2013!<br />";
    }
}

Fiesta2013.php:

<?php

namespace Ford\Fiesta;

class Fiesta2013
{
    public static function info()
    {
        echo "This is Ford Fiesta2013!<br />";
    }
}

Focus2013.php:

<?php

namespace Ford\Focus;

class Focus2013
{
    public static function info()
    {
        echo "This is Ford Focus2013!<br />";
    }
}

Fusion2013.php:

<?php

namespace Ford\Fusion;

class Fusion2013
{
    public static function info()
    {
        echo "This is Ford Fusion2013!<br />";
    }
}

以上都梳理完毕后,需要安装composer来测试我们的包是否可以正常工作,安装它很简单在包的root目录下install即可:

composer install

闪过几行神秘的提示之后即安装完毕,此时会在vendor/composer/autoload_psr4.php中生成命名空间和目录的映射关系,被包在一个数组中:

<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Ford\\Fusion\\' => array($baseDir . '/src/Ford/Fusion'),
    'Ford\\Focus\\' => array($baseDir . '/src/Ford/Focus'),
    'Ford\\Fiesta\\' => array($baseDir . '/src/Ford/Fiesta'),
    'Ford\\Escape\\' => array($baseDir . '/src/Ford/Escape'),
);

如果发布成packagist包然后进行安装的话,到时候这里就不是$baseDir了而是$vendorDir。

然后我们新建一个测试文件show.php,用以下内容填充它:

<?php

require 'vendor/autoload.php';

use Ford\Escape as Escape;
use Ford\Fiesta as Fiesta;
use Ford\Focus as Focus;
use Ford\Fusion as Fusion;

echo Escape\Escape2013::info();
echo Fiesta\Fiesta2013::info();
echo Focus\Focus2013::info();
echo Fusion\Fusion2013::info();

打开浏览器敲入 http://foo.com/composer-car/show.php (foo.com是我的本地测试域名,请替换成小伙伴自己的)。

浏览器上依次输出了:

This is Ford Escape2013!
This is Ford Fiesta2013!
This is Ford Focus2013!
This is Ford Fusion2013!

是不是有点小激动呢?别急,别一副作鸟兽散的样子,还有发布的流程呢?不过你要是真的急着wc或者觉得教程too simple,侯哥是不会让你捡肥皂的。

首先作为调试代码的部分我们是不需要push到github上的,所以将show.php打入冷宫,编辑.gitignore文件,在末尾加入show.php。这个时候有些小伙伴可能会疑惑了,为什么上面还有个/vendor/,记得我们init包的时候回答过一个问题么?

Would you like the vendor directory added to your .gitignore [yes]? yes

嗯嗯,你懂了吧?

废话少说,经过职业玩家的一番噼里啪啦的敲击之后,代码被push到github上了,噼里啪啦的内容如下:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore
#   composer.json
#   src/
nothing added to commit but untracked files present (use "git add" to track)

$ git add .
$ git commit -m "gogogo"
$ git push

接下来需要将github上的代码同步到https://packagist.org/上,去[Packagist的网站](https://packagist.org/](https://packagist.org/)注册一个账号(Login with github是个不错的选择)。登录,然后点击的大大的绿色背景按钮 Submit a Package,在 Repository URL (Git/Svn/Hg) 处输入包在github上的地址,这里就是:

https://github.com/GeHou/composer-car 

now,点击 Check,如果一切顺利,会返回项目的名称,确认后点击 Submit 完成抓取操作。

默认情况下Packagist是不会自动更新你在github上commit的代码的,在刚才导入的项目页面中点击 Force Update,Packagist会抓取github上对应库的内容进行更新,但这还不是自动化的,幸运的是我们可以在Github库的设置中进行配置来消除手动更新的麻烦。

进入Github库的 Settings 页面,找到 Webhooks & Services 选项,点击 Configure services 按钮,在出现的列表中找到 Packagist,猛击它!这里需要填写一些信息,在Packagist网站的profile页面可以找到它们:

  • User : Packagist上的用户名
  • Token : Packagist的授权令牌
  • Domain : http://packagist.org

补全后点击 Update settings,如果列表中显示绿剪头就表示OK了。

真的OK了吗?还是有点担心?大不了我们再测试下嘛!

先跳出root目录,在测试环境下新建一个文件夹:

mkdir test-auto-update
cd test-auto-update
vim composer.json

这次我们不使用init命令,只往composer.json里填充一些简单内容:

{
    "require": {
        "php": ">=5.3.0",
        "hou/composer-car": "dev-master"
    },
    "minimum-stability": "dev"
}

然后:

composer install

安装完后扫一眼test-auto-update/src/Ford/Fiesta目录看下是否只有2013款的Fiesta,然后暂时就不需要理会此目录下的内容了,让我们回到composer-car目录。

注:这时test-auto-update/vendor下面的hou/composer-car对应建立项目时的( / ) [hou/composer-car]。

听说2014款的嘉年华出了,赶紧追加新的车款吧:

composer-car/src/Ford/Fiesta 目录下新建文件Fiesta2014.php,填充它:

<?php

namespace Ford\Fiesta;

class Fiesta2014
{
    public static function info()
    {
        echo "This is Ford Fiesta2014!<br />";
    }
}

修改show.php,在最后追加:

echo Fiesta\Fiesta2014::info();

访问测试页,看看是否出现了:

This is Ford Fiesta2014!

ok,再次提交代码:

git add .
git commit -m "test auto update"
git push

接着回到 test-auto-update 目录,这次要换一个命令耍耍,因为install命令之后root目录下会生成一个composer.lock文件,已经安装过的依赖是不能通过install命令进行更新的,所以这次需要使用composer update命令,试试这个命令,看看会发生什么:

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
       - Updating hou/composer-car dev-master (91bceb0 => 01550b4)
    Checking out 01550b4eeaa85513573ce7406ca7d46ee30c6978

Writing lock file
Generating autoload files

类似这样的神秘信息又在屏幕上一闪而过,实际上因为网络的缘故,有时候得闪好久~

不管怎么闪,更新成功后你就应该在 test-auto-update/vendor/hou/composer-car/src/Ford/Fiesta/ 文件夹下中找到新的 Fiesta2014.php 文件了。不过这里需要注意一点,有时候Packagist与Github之间的同步可能会出现延迟,这时不妨喝杯咖啡、找妹子聊会、扣扣鼻孔之类的噼里啪啦一会再回来试试更新操作。

好吧我们在 test-auto-update 根目录下新建一个 index.php 文件看看是否能跑起来,文件内容其实跟前面的show.php差不了多少:

<?php

require 'vendor/autoload.php';

use Ford\Fiesta as Fiesta;

echo Fiesta\Fiesta2014::info();

不错的话,运行index.php文件后浏览器会输出:

This is Ford Fiesta2014!

至此更新操作也被证实是OK了,同志赶紧自己动手试试吧。

参考资料

中文文档 http://composer.golaravel.com/

PSR-4规范 https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md

本文示例

https://github.com/GeHou/composer-car

https://packagist.org/packages/hou/composer-car

link: http://my.oschina.net/houlive/blog/206832

使用aapt    //aapt是sdk自带的一个工具,在sdk\builds-tools\目录下

1.以微信为例,命令行中切换到aapt.exe目录执行:aapt dump badging E:\android\weixin531android460.apk
2.运行后的结果如下(仅截取部分):
package: name=’com.tencent.mm’ versionCode=’542′ versionName=’6.1.0.105_r1085424′
uses-permission:’com.tencent.mm.plugin.permission.READ’
uses-permission:’com.tencent.mm.plugin.permission.WRITE’
uses-permission:’com.tencent.mm.plugin.permission.SEND’
uses-permission:’com.tencent.mm.permission.MM_MESSAGE’
sdkVersion:’10’
targetSdkVersion:’16’

我们可以看到关于微信的很多信息,其中就包括包名,微信的包名为:com.tencent.mm

然后启动代码:

  1. try {
  2.     PackageManager packageManager = getPackageManager();
  3.     Intent intent=new Intent();
  4.     intent = packageManager.getLaunchIntentForPackage(“com.tencent.mm”);
  5.     startActivity(intent);
  6. catch (Exception e) {
  7.     e.printStackTrace();
  8.     Intent viewIntent = new
  9.     Intent(“android.intent.action.VIEW”,Uri.parse(“http://weixin.qq.com/”));
  10.     startActivity(viewIntent);
  11. }

如果手机上安装了微信,就打开微信的主界面,如果没有安装就打开一个浏览器去下载!!!

link: http://blog.csdn.net/lovexieyuan520/article/details/44301753

 

最近因为需要用到Android的自动化测试,于是找到了uiautomator和espresso这两个框架(这里以uiautomator为例).由于在Android Studio(以下简称AS)中使用uiautomator这方面的资料很少,国内这方面的博客基本没有,国外的资料也都很少.可能是因为比较新的原因吧.虽然Android官网有教程,但最终还是折腾了好久才解决.写这篇博客一方面希望大家能够少走一些弯路,另一方面也算是我自己的学习笔记吧.

说明:我的AS版本是1.2.1.1

关于什么是uiautomator和espresso,这里就不做介绍了.

使用之前首先得保证你的Android Support Repository已经成功安装

安装成功后,根据Android官网给出的教程,首先第一步是在build.gradle中添加依赖:

dependencies {
        androidTestCompile 'com.android.support.test:runner:0.2'
        androidTestCompile 'com.android.support.test:rules:0.2'
        androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.0'
}

然后添加

defaultConfig {
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

添加完依赖后Sync Project with Gradle Files,但是同步后我发现上面相关的库文件并没有被添加进来.对比很多资料后,我很确信不是我在写法的问题.就是这个问题折腾了我好几天的!

最后的解决办法是先把androidTestCompile换成compile,同步一下,此时会发现库文件已经被添加进来了.

最后再将compile换回androidTestCompile,解决~

突然就觉得自己被坑了,也不知道这算不算是AS的一个BUG…

如果同步之后发现诸如此类的错误:

 Warning:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (22.1.1) and test app (22.0.0) differ.

先在项目的根目录用./gradlew -q app:dependencies查看项目依赖关系(Windows用户请使用gradlew.bat -q app:dependencies), 然后修改build.gradle,否则在后面运行测试时可能会报依赖关系的错误.
可能需要为gradlew加上可执行权限.

说明:我这里会报这个警告是因为新建项目的时候AS帮我自动添加了compile 'com.android.support:appcompat-v7:22.1.1'依赖,将22.1.1改为22.0.0即可.

然后还要在build.gradle中添加:

packagingOptions {
    exclude 'LICENSE.txt'
}

不添加的话运行时候还是会报错的.

最后,确保此时有android设备在运行(虚拟器或手机都可以,要求是系统版本要18或18以上),然后在项目的根目录下输入命令:

./gradlew cC

如无意外的话,应该可以看到BUILD SUCCESS了!

如果不想用命令行的话,也可以Edit Configurations,然后点击+ –> Android Test,然后选择对应的Module,然后在下面的Specific Instrumentation Runner选择

android.support.test.runner.AndroidJUnitRunner

选择OK,然后点击启动按钮.如无意外的话,应该可以看到一条绿色的进度条了!

关于另外一个自动化测试框架Espresso,导入方法和uiautomator一样,不同的只是依赖而已.

dependencies {
    androidTestCompile 'com.android.support.test:runner:0.2'
    androidTestCompile 'com.android.support.test:rules:0.2'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
}

关于测试框架的导入就先说这么多了,有关这些框架的使用网上的资料应该也是比较多的了,只不过有一些API已经被弃用了.等我熟悉了这两大框架的使用再来写相关的博客吧.

 

link: http://blog.csdn.net/u011504118/article/details/46318693

文章目录

Git Protocol

A guide for programming within version control.

Maintain a Repo

  • Avoid including files in source control that are specific to your development machine or process.
  • Delete local and remote feature branches after merging.
  • Perform work in a feature branch.
  • Rebase frequently to incorporate upstream changes.
  • Use a pull request for code reviews.

Write a Feature

Create a local feature branch based off master.

git checkout master
git pull
git checkout -b <branch-name>

Rebase frequently to incorporate upstream changes.

git fetch origin
git rebase origin/master

Resolve conflicts. When feature is complete and tests pass, stage the changes.

git add --all

When you’ve staged the changes, commit them.

git status
git commit --verbose

Write a good commit message. Example format:

Present-tense summary under 50 characters

* More information about commit (under 72 characters).
* More information about commit (under 72 characters).

http://project.management-system.com/ticket/123

If you’ve created more than one commit, use a rebase to squash them into cohesive commits with good messages:

git rebase -i origin/master

Share your branch.

git push origin <branch-name>

Submit a GitHub pull request.

Ask for a code review in the project’s chat room.

Review Code

A team member other than the author reviews the pull request. They follow Code Review guidelines to avoid miscommunication.

They make comments and ask questions directly on lines of code in the GitHub web interface or in the project’s chat room.

For changes which they can make themselves, they check out the branch.

git checkout <branch-name>
./bin/setup
git diff staging/master..HEAD

They make small changes right in the branch, test the feature on their machine, run tests, commit, and push.

When satisfied, they comment on the pull request Ready to merge.

Merge

Rebase interactively. Squash commits like “Fix whitespace” into one or a small number of valuable commit(s). Edit commit messages to reveal intent. Run tests.

git fetch origin
git rebase -i origin/master

Force push your branch. This allows GitHub to automatically close your pull request and mark it as merged when your commit(s) are pushed to master. It also makes it possible to find the pull request that brought in your changes.

git push --force origin <branch-name>

View a list of new commits. View changed files. Merge branch into master.

git log origin/master..<branch-name>
git diff --stat origin/master
git checkout master
git merge <branch-name> --ff-only
git push

Delete your remote feature branch.

git push origin --delete <branch-name>

Delete your local feature branch.

git branch --delete <branch-name>

link: https://github.com/thoughtbot/guides/tree/master/protocol/git

对于nginx来说,如果打开了gzip,会对关闭掉etag。

在我们的应用中etag是后端返回的,关闭了就影响到了逻辑。

修改:

在srv/http/modules/ngx_http_gzip_filter_module.c

ngx_http_gzip_header_filter函数中屏蔽//ngx_http_clear_etag(r);

然后重编

 

转自: http://blog.csdn.net/anghlq/article/details/40042057

文章目录

其实制作 OS X Yosemite 正式版 USB 启动盘的方法有很多,譬如使用命令行的,也有使用第三方工具的。这个教程主要介绍前者,因为这是目前我了解到的最稳妥、简单,而且没有兼容性问题的方法了。

01

不过大家可别被「命令行」三个字吓到,其实你只需按步骤来,复制粘贴命令即可快速完成,事实上是很简单的。

一、准备工作:

  1. 准备一个 8GB 或以上容量的 U 盘,确保里面的数据已经妥善备份好(该过程会抹掉 U 盘全部数据)
  2. 从这里下载苹果官方 OS X Yosemite 正式版的安装程序 (可选 AppSotre 或网盘下载)
  3. 如果你是从 Mac AppStore 下载的,下载完成后安装程序可能自动开始,这时先退出安装
  4. 如从网盘下载的,请将解压后获得的 “Install OS X Yosemite.app” (显示为 “安装 OS X Yosemite.app”) 移动到「应用程序」文件夹里面

二、格式化 U 盘:

插入你的 U 盘,然后在「应用程序」->「实用工具」里面找到并打开「磁盘工具」,或者直接用 Spotlight 搜索“磁盘工具” 打开,如下图。

02

  • 1 – 在左方列表中找到 U 盘的名称并点击
  • 右边顶部选择 2 -「分区」,然后在 3 -「分区布局」选择「1个分区」
  • 在分区信息中的 4 -「名称」输入「iPlaySoft」 (由于后面的命令中会用到此名称,如果你要修改成其他(英文),请务必对应修改后面的命令)
  • 在「格式」中选择 5 -「Mac OS 扩展 (日志式)」
  • 这时,先别急着点“应用”,还要先在 6 -「选项」里面,如下图

03

  • 选择「GUID 分区表」,然后点击「好」
  • 最后再点「应用」开始对 U 盘进行格式化。

三、输入终端命令开始制作启动盘:

  • 请再次确保名为 “安装 OS X Yosemite” 的文件是保存在「应用程序」的目录中
  • 在「应用程序」->「实用工具」里面找到「终端」并打开。也可以直接通过 Spotlight 搜索「终端」打开
  • 复制下面的命令,并粘贴到「终端」里,按回车运行:

sudo /Applications/Install\ OS\ X\ Yosemite.app/Contents/Resources/createinstallmedia –volume /Volumes/iPlaySoft –applicationpath /Applications/Install\ OS\ X\ Yosemite.app –nointeraction

回车后,系统会提示你输入管理员密码,接下来就是等待系统开始制作启动盘了。这时,命令执行中你会陆续看到类似以下的信息:

Erasing Disk: 0%… 10%… 20%… 30%…100%…
Copying installer files to disk…
Copy complete.
Making disk bootable…
Copying boot files…
Copy complete.
Done.

当你看到最后有 「Copy complete」和「Done」 字样出现就是表示启动盘已经制作完成了!

四、U 盘启动安装 OS X Yosemite 的方法:

当你插入制作完成的 OS X Yosemite U盘启动盘之后,桌面出现「Install OS X Yosemite」的盘符那么就表示启动盘是正常的了。那么怎样通过 USB 启动进行全新的系统安装呢?

其实很简单,先在目标电脑上插上 U 盘,然后重启你的 Mac,然后一直按住「option」(alt) 按键不放,直到屏幕显示多出一个 USB 启动盘的选项,如下图。

04

这时选择 U 盘的图标回车,即可通过 U 盘来安装 Yosemite 了!这时,你可以直接覆盖安装系统(升级),也可以在磁盘工具里面格式化抹掉整个硬盘,或者重新分区等实现全新的干净的安装。

 

link: http://www.iplaysoft.com/osx-yosemite-usb-install-drive.html

Linux默认情况下使用UTC格式作为标准时间格式,如果在Linux下运行程序,且在程 序中指定了与系统不一样的时区的时候,可能会造成时间错误。如果是Ubuntu的桌面版,则可以直接在图形模式下修改时区信息,但如果是在Server版 呢,则需要通过tzconfig来修改时区信息了。使用方式(如将时区设置成Asia/Chongqing):

 

sudo tzconfig,如果命令不存在请使用 dpkg-reconfigure tzdata

然后按照提示选择 Asia对应的序号,选完后会显示一堆新的提示—输入城市名,如Shanghai或Chongqing,最后再用 sudo date -s “” 来修改本地时间。

按照提示进行选择时区,然后:

sudo cp /usr/share/zoneinfo/Asia/ShangHai /etc/localtime

上面的命令是防止系统重启后时区改变。

 

网上同步时间

1.  安装ntpdate工具

# sudo apt-get install ntpdate

2.  设置系统时间与网络时间同步

# ntpdate cn.pool.ntp.org

3.  将系统时间写入硬件时间

# hwclock –systohc

cn.pool.ntp.org是位于中国的公共NTP服务器,用来同步你的时间(如果你的时间与服务器的时间截不同的话,可能无法同步时间哟,甚至连sudo reboot这样的指令也无法执行)。

 

link: http://www.cnblogs.com/php5/archive/2011/02/15/1955432.html

Valgrind简介:

Valgrind是动态分析工具的框架。有很多Valgrind工具可以自动的检测许多内存管理和多进程/线程的bugs,在细节上剖析你的程序。你也可以利用Valgrind框架来实现自己的工具。

Valgrind通常包括6个工具:一个内存错误侦测工具,两个线程错误侦测工具,cache和分支预测的分析工具,堆的分析工具。

Valgrind的使用与CPU OS以及编译器和C库都有关系。目前支持下面的平台:

– x86/Linux

– AMD64/Linux

– PPC32/Linux

– PPC64/Linux

– ARM/Linux

– x86/MacOSX

– AMD64/MacOSX

 

Valgrind是GNU v2下的开源软件,你可以从http://valgrind.org下载最新的源代码。

 

Valgrind的安装:

1.从http://valgrind.org下载最新的valgrind-3.7.0.tar.bz2d,用tar -xfvalgrind-3.7.0.tar.bz2解压安装包。

2.执行./configure,检查安装要求的配置。

3.执行make。

4.执行make install,最好是用root权限。

5.试着valgrind ls -l来检测是否正常工作。

 

 

Valgrind的概述:

Valgrind时建立动态分析工具的框架。它有一系列用于调试分析的工具。Valgrind的架构是组件化的,所以可以方便的添加新的工具而不影响当前的结构。

 

下面的工具是安装时的标准配置:

Memcheck:用于检测内存错误。它帮助c和c++的程序更正确。

Cachegrind:用于分析cache和分支预测。它帮助程序执行得更快。

Callgrind:用于函数调用的分析。

Helgrind:用于分析多线程。

DRD:也用于分析多线程。与Helgrind类似,但是用不同的分析技术,所以可以检测不同的问题。

Massif:用于分析堆。它帮助程序精简内存的使用。

SGcheck:检测栈和全局数组溢出的实验性工具,它和Memcheck互补使用。

 

 

Valgrind的使用:

1.准备好程序:

编译程序时用-g,这样编译后的文件包含调试信息,那Memcheck的分析信息中就包含正确的行号。最好使用-O0的优化等级,使用-O2及以上的优化等级使用时可能会有问题。

2.在Memcheck下运行程序:

如果你的程序执行如下:

myprog arg1 arg2

那么使用如下:

valgrind –leak-check=yes myprog arg1 arg2

Memcheck是默认的工具。–leak-check打开内存泄漏检测的细节。

在上面的命令中运行程序会使得程序运行很慢,而且占用大量的内存。Memcheck会显示内存错误和检测到的内存泄漏。

3.如何查看Memcheck的输出:

这里有一个实例c代码(a.c),有一个内存错误和一个内存泄漏。

#include <stdlib.h>

void f(void)

{

int*x = (int *)malloc(10 * sizeof(int));

x[10]= 0;

//problem 1: heap block overrun

}        //problem 2: memory leak — x not freed

 

int main(void)

{

f();

return0;

}

 

运行如下:

huerjia@huerjia:~/NFS/valg/test$ valgrind–leak-check=yes ./a

==24780== Memcheck, a memory error detector

==24780== Copyright (C) 2002-2011, and GNUGPL’d, by Julian Seward et al.

==24780== Using Valgrind-3.7.0 and LibVEX;rerun with -h for copyright info

==24780== Command: ./a

==24780==

==24780== Invalid write of size 4

==24780==   at 0x80484DF: f() (a.c:5)

==24780==   by 0x80484F1: main (a.c:11)

==24780== Address 0x42d3050 is 0 bytes after a block of size 40 alloc’d

==24780==   at 0x4026444: malloc (vg_replace_malloc.c:263)

==24780==   by 0x80484D5: f() (a.c:4)

==24780==   by 0x80484F1: main (a.c:11)

==24780==

==24780==

==24780== HEAP SUMMARY:

==24780==     in use at exit: 40 bytes in 1 blocks

==24780==  total heap usage: 1 allocs, 0 frees, 40 bytes allocated

==24780==

==24780== 40 bytes in 1 blocks aredefinitely lost in loss record 1 of 1

==24780==   at 0x4026444: malloc (vg_replace_malloc.c:263)

==24780==   by 0x80484D5: f() (a.c:4)

==24780==   by 0x80484F1: main (a.c:11)

==24780==

==24780== LEAK SUMMARY:

==24780==   definitely lost: 40 bytes in 1 blocks

==24780==   indirectly lost: 0 bytes in 0 blocks

==24780==      possibly lost: 0 bytes in 0 blocks

==24780==   still reachable: 0 bytes in 0 blocks

==24780==         suppressed: 0 bytes in 0 blocks

==24780==

==24780== For counts of detected andsuppressed errors, rerun with: -v

==24780== ERROR SUMMARY: 2 errors from 2contexts (suppressed: 17 from 6)

 

如何来阅读这个输出结果:

==24780== Memcheck, a memory error detector

==24780== Copyright (C) 2002-2011, and GNUGPL’d, by Julian Seward et al.

==24780== Using Valgrind-3.7.0 and LibVEX;rerun with -h for copyright info

==24780== Command: ./a

这一部分是显示使用的工具以及版本信息。其中24780是Process ID。

 

==24780== Invalid write of size 4

==24780==   at 0x80484DF: f() (a.c:5)

==24780==   by 0x80484F1: main (a.c:11)

==24780== Address 0x42d3050 is 0 bytes after a block of size 40 alloc’d

==24780==   at 0x4026444: malloc (vg_replace_malloc.c:263)

==24780==   by 0x80484D5: f() (a.c:4)

==24780==   by 0x80484F1: main (a.c:11)

这部分指出了错误:Invalid write。后面的几行显示了函数堆栈。

 

==24780== HEAP SUMMARY:

==24780==     in use at exit: 40 bytes in 1 blocks

==24780==  total heap usage: 1 allocs, 0 frees, 40 bytes allocated

==24780==

==24780== 40 bytes in 1 blocks aredefinitely lost in loss record 1 of 1

==24780==   at 0x4026444: malloc (vg_replace_malloc.c:263)

==24780==   by 0x80484D5: f() (a.c:4)

==24780==   by 0x80484F1: main (a.c:11)

==24780==

==24780== LEAK SUMMARY:

==24780==   definitely lost: 40 bytes in 1 blocks

==24780==   indirectly lost: 0 bytes in 0 blocks

==24780==      possibly lost: 0 bytes in 0 blocks

==24780==   still reachable: 0 bytes in 0 blocks

==24780==         suppressed: 0 bytes in 0 blocks

这部分是对堆和泄漏的总结,可以看出内存泄漏的错误。

 

==24780== For counts of detected andsuppressed errors, rerun with: -v

==24780== ERROR SUMMARY: 2 errors from 2contexts (suppressed: 17 from 6)

这部分是堆所有检测到的错误的总结。代码中的两个错误都检测到了。

 

 

 

Helgrind:线程错误检测工具

若使用这个工具,在Valgrind的命令中添加–tool=helgrind。

Helgrind用于c,c++下使用POSIXpthreads的程序的线程同步错误。

Helgrind可以检测下面三类错误:

1.POSIX pthreads API的错误使用

2.由加锁和解锁顺序引起的潜在的死锁

3.数据竞态–在没有锁或者同步机制下访问内存

 

以数据竞态为例来说明Helgrind的用法:

在不使用合适的锁或者其他同步机制来保证单线程访问时,两个或者多个线程访问同一块内存就可能引发数据竞态。

一个简单的数据竞态的例子:

#include <pthread.h>

 

int var = 0;

 

void* child_fn ( void* arg ) {

var++;/* Unprotected relative to parent */ /* this is line 6 */

returnNULL;

}

 

int main ( void ) {

pthread_tchild;

pthread_create(&child,NULL, child_fn, NULL);

var++;/* Unprotected relative to child */ /* this is line 13 */

pthread_join(child,NULL);

return0;

}

 

运行如下:

huerjia@huerjia:~/NFS/valg/test$ valgrind–tool=helgrind ./b

==25449== Helgrind, a thread error detector

==25449== Copyright (C) 2007-2011, and GNUGPL’d, by OpenWorks LLP et al.

==25449== Using Valgrind-3.7.0 and LibVEX;rerun with -h for copyright info

==25449== Command: ./b

==25449==

==25449==—Thread-Announcement——————————————

==25449==

==25449== Thread #1 is the program’s rootthread

==25449==

==25449== —Thread-Announcement——————————————

==25449==

==25449== Thread #2 was created

==25449==   at 0x4123A38: clone (in /lib/tls/i686/cmov/libc-2.11.1.so)

==25449==   by 0x40430EA: pthread_create@@GLIBC_2.1 (in /lib/tls/i686/cmov/libpthread-2.11.1.so)

==25449==   by 0x402A9AD: pthread_create_WRK (hg_intercepts.c:255)

==25449==   by 0x402AA85: pthread_create@* (hg_intercepts.c:286)

==25449==   by 0x80484E1: main (b.c:11)

==25449==

==25449==—————————————————————-

==25449==

==25449== Possible data race during read ofsize 4 at 0x804A020 by thread #1

==25449== Locks held: none

==25449==   at 0x80484E2: main (b.c:12)

==25449==

==25449== This conflicts with a previouswrite of size 4 by thread #2

==25449== Locks held: none

==25449==   at 0x80484A7: child_fn (b.c:6)

==25449==   by 0x402AB04: mythread_wrapper (hg_intercepts.c:219)

==25449==   by 0x404296D: start_thread (in /lib/tls/i686/cmov/libpthread-2.11.1.so)

==25449==   by 0x4123A4D: clone (in /lib/tls/i686/cmov/libc-2.11.1.so)

==25449==

==25449==—————————————————————-

==25449==

==25449== Possible data race during writeof size 4 at 0x804A020 by thread #1

==25449== Locks held: none

==25449==   at 0x80484E2: main (b.c:12)

==25449==

==25449== This conflicts with a previouswrite of size 4 by thread #2

==25449== Locks held: none

==25449==   at 0x80484A7: child_fn (b.c:6)

==25449==   by 0x402AB04: mythread_wrapper (hg_intercepts.c:219)

==25449==   by 0x404296D: start_thread (in /lib/tls/i686/cmov/libpthread-2.11.1.so)

==25449==   by 0x4123A4D: clone (in /lib/tls/i686/cmov/libc-2.11.1.so)

==25449==

==25449==

==25449== For counts of detected andsuppressed errors, rerun with: -v

==25449== Use –history-level=approx or=none to gain increased speed, at

==25449== the cost of reduced accuracy ofconflicting-access information

==25449== ERROR SUMMARY: 2 errors from 2contexts (suppressed: 0 from 0)

 

错误信息从“Possible data race during write of size 4 at 0x804A020 by thread #1

”开始,这条信息你可以看到竞态访问的地址和大小,还有调用的堆栈信息。

第二条调用堆栈从“This conflicts with a previous write of size 4 by thread #2

”开始,这表明这里与第一个调用堆栈有竞态。

 

一旦你找到两个调用堆栈,如何找到竞态的根源:

首先通过每个调用堆栈检查代码,它们都会显示对同一个位置或者变量的访问。

现在考虑如何改正来使得多线程访问安全:

1.使用锁或者其他的同步机制,保证同一时间只有独立的访问。

2.使用条件变量等方法,确定多次访问的次序。

 

 

本文介绍了valgrind的体系结构,并重点介绍了其应用最广泛的工具:memcheck和helgrind。阐述了memcheck和helgrind的基本使用方法。在项目中尽早的发现内存问题和多进程同步问题,能够极大地提高开发效率,valgrind就是能够帮助你实现这一目标的出色工具。

 

link: http://blog.csdn.net/dndxhej/article/details/7855520

We introduced Stage3D last year and the momentum behind has never stopped growing but there is one area we did not give all the details. The ATF file format, it is mentioned here and there, so what’s up with this? Some of you may have seen it in the documentation for Stage3D referred as the compressed texture file format, but we never shared any tools to create those famous ATF textures.

Before we package the ATF tools with the AIR SDK, I am happy to share here in advance the ATF tools so that you guys can start leveraging the ATF format now!

So what is it?

First, let’s start by talking about what compressed textures are.

When doing GPU programming with any technology, you have two options for how you handle your textures. You can go compressed or uncompressed, very simple. So, what is the difference?

  1. When using uncompressed textures, a good old uncompressed file format like PNG is used and uploaded to the GPU.
  2. Because GPUs don’t support such a file format natively, your texture is actually stored in CPU memory, when it could actually be stored on the GPU memory!
  3. Same thing applies for JPEG images, make no mistake, graphics chipsets don’t know anything about JPEG which would also be decoded on CPU memory.
  4. Of course, each platform has different support for compressed textures depending on the hardware chipset being used.
Now get ready for the fun! Here is below a little table to illustrate it:
Platform Format
ImgTech (iOS) PVRTC
Qualcom (Android) ETC1
Mali (Android) ETC1
NVidia (Android) ETC1/DXT1/DXT5
Android (PowerVR) PVRTC/ETC1
Windows DXT1/DXT5
MacOS DXT1/DXT5

 

Why ATF?

As you can imagine, if you would develop a game targeting iOS, Android and desktop, you would need to supply your textures compressed to each format for each platform. Which would look like this:

  1. leaf.png encoded to DXT for Windows and MacOS
  2. leaf.png encoded to ETC1 or DXT for Android (Nvidia)
  3. leaf.png encoded to PVRTC for iOS (ImgTech)

Of course it is a pain to provide all the different versions of the textures, detect at runtime which platform you are running on and upload the corresponding texture. Wouldn’t it be cool if you could just rely on one single container, that would wrap all the textures for each platform and Flash Player or AIR would extract automatically the texture required depending on the platform? So here comes ATF.

The ATF internals

Really, think about the ATF format as a container for lossy images. Here is below a little figure showing very sinply the structure of a default compressed ATF file:

01

By default, all textures format (PVRTC (4bpp), ETC1, and DXT1/5) are embedded in the ATF file so that for each platform, AIR or Flash Player automatically extracts the appropriate texture. But in some cases, you may want to target mobile only and why should you embed desktop related textures or Android if you are targeting iOS only? To cover this, you can also embed the PVRTC textures only inside the ATF file, making your assets smaller.

The figure below illustrate the idea:

02

As you can imagine, the same applies to ETC1 if you are targeting Android:

03

If you know about ETC1, you may wonder how we handle transparency then? We use a dual ETC1 approach with two textures, one for the alpha channel and one for the colors.

And finally on desktop only, where only the DXT texture can be provided:

04

The difference between DXT1 and DXT5 resides in alpha support. DXT1 does not support transparency, DXT5 does. Automatically the ATF tools will detect if your images have transparency and select the proper DXT version for you. Also note that ATF is not alpha pre-multiplied.

Now, if you want to store uncompressed textures inside an ATF file, you can also do that:

05

Why would you do that you may ask? Well, you may want to use uncompressed textures but still want to leverage cubemap, automatic mipmap support or even texture streaming.

Ok, now apart from the fact that hardware requires those textures to be compressed, what is the value for your content?

Yes, what does it bring you?

  • Faster rendering
  • Lower texture memory requirements (extremely important on devices like the iPad1 where memory is very limited)
  • Faster texture uploads into texture memory
  • Automatic generation of all required mip-maps (note that you can disable this if needed).
  • Additionally, the use of compress textures allows the application to utilize higher resolution textures with the same memory footprint.
Now the question is, how do you create such ATF files? It is very easy, we provide a few command line tools for that. Let’s have a look at how it works.

How to use the tools

The main tool you need to know about is png2atf , which as you can guess, takes a png and gives you an ATF file:

//package leaf.png with all 3 formats (DXT5, PVRTC and ETC1x2)
C:\png2atf.exe  -c  -i  leaf.png  -o  leaf.atf
[In 213KB][Out 213KB][Ratio 99.9703%][LZMA:0KB JPEG-XR:213KB]

//package specific range of mipmaps
C:\png2atf.exe  -c  -n  0,5  -i  leaf.png  -o  leaf0,5.atf
[In 213KB][Out 213KB][Ratio 99.8825%][LZMA:0KB JPEG-XR:213KB]

//package only DXT format
C:\png2atf.exe  -c d  -i  leaf.png  -o  leaf_dxt5.atf
[In 85KB][Out 85KB][Ratio 100.045%][LZMA:0KB JPEG-XR:85KB]

//package only ETC1 format
C:\png2atf.exe  -c e  -i  leaf.png  -o  leaf_etc1.atf
[In 85KB][Out 85KB][Ratio 100.045%][LZMA:0KB JPEG-XR:85KB]

//package only PVRTC format
C:\png2atf.exe  -c p  -i  leaf.png  -o  leaf_pvrtc.atf
[In 42KB][Out 42KB][Ratio 100.089%][LZMA:0KB JPEG-XR:42KB]

As mentioned earlier, what if you wanted to store uncompressed a uncompressed texture inside your ATF? For this, just don’t use the -c argument:

//package as uncompressed (RGBA) format
C:\png2atf.exe  -i  leaf.png  -o  leaf_rgba.atf
[In 341KB][Out 43KB][Ratio 12.8596%][LZMA:0KB JPEG-XR:43KB]

Another cool feature is that ATF can also be used with streaming, to generate 3 sub-files you can do this:

png2atf -m -n 0,0 -c -i cubecat0.png -o cubecat_c_high.atf
png2atf -m -n 1,2 -c -i cubecat0.png -o cubecat_c_med.atf
png2atf -m -n 3,20 -c -i cubecat0.png -o cubecat_c_low.atf

For info, texture support streaming shipped in Flash Player 11.3/AIR 3.3. Make sure to create the texture with streaming on, by using the streamingLevel arguments of the Texture.createTexture() API.

If you have used the texturetool from Apple to generate your PVR textures, this is the same approach. Another tool called pvr2atf , which is a command line utility converts PVR texture files to ATF files. The tool works similarly to png2atf except that you have to provide input files in the PVR texture format.

To convert a PVR file to an RGB or RGBA ATF file run the command as such:

C:\> pvr2atf -i test.pvr -o test.atf
[In 4096KB][Out 410KB][Ratio 10.0241%][LZMA:0KB JPEG-XR:410KB]

Also, you can use ATF for a cubemap texture:

//to create a ATF for cubemap texture,
//prepare png file for each side of the cube as:
// -X: cube0.png
//+X: cube1.png
// -Y: cube2.png
//+Y: cube3.png
// -Z: cube4.png
//+Z: cube5.png
C:\png2atf.exe  -c   -m  -i  cube0.png  -o  cube.atf

ATFViewer is a GUI tool which previews and inspects ATF files. The primary purpose is to audit DXT1, ETC1 and PVRTC compression artifacts. You can open and view ATF files by either using the ‘Open…’ menu item or by dragging a file from Explorer into the window. The Snippet preview area shows you an example of how to load a particular ATF file in raw ActionScript 3 Stage3D code.

Below is an example of a test file from Starling, you can preview the texture for each format and also have a little code snippet at the bottom which tells you how to use it in ActionScript 3 with Stage3D:

06

Note that when opening an ATF texture containing only specific compression, the ATFViewer will show this, below we opened an ATF file containing only the DXT textures, you can see that ETC1 and PVRTC in the texture types list are greyed out:

07

Let’s have a look now at how we can use compressed textures with the Stage3D APIs.

Using compressed textures with Stage3D

To use compressed textures with Stage3D, you need to use theTexture.uploadCompressedTextureFromByteArray API with one of the two relatedContext3DTextureFormat constants (Context3DTextureFormat.COMPRESSED_ALPHA andContext3DTextureFormat.COMPRESSED ):

class Example {
[Embed( source = "mytexture.atf", mimeType="application/octet-stream")]
public static const TextureAsset:Class;
public var context3D:Context3D;

public function init():void{
var texture:Texture = context3D.createTexture(256, 256, Context3DTextureFormat.COMPRESSED_ALPHA, false);
var textureAsset:ByteArray = new TextureAsset() as ByteArray;
texture.uploadCompressedTextureFromByteArray(textureAsset, 0);
}
};

In the context of a cubemap texture, you would write:

var texCubemap:CubeTexture = context3D.createCubeTexture(256, Context3DTextureFormat.COMPRESSED_ALPHA, false);
var textureAsset:ByteArray = new TextureAsset() as ByteArray;
texCubemap.uploadCompressedTextureFromByteArray(textureAsset, 0);

Also, depending on the format of the texture, “dxt1” or “dxt5” is needed in the texture sampler of your fragment shader:

  • Nothing needed for Context3DTextureFormat.BGRA , same as before
  • “dxt1” for Context3DTextureFormat.COMPRESSED (whatever the texture format used, DXT, PVRTC, or ETC1)
  • “dxt5” for Context3DTextureFormat.COMPRESSED_ALPHA  (whatever the texture format used, DXT, PVRTC, or ETC1)
You can also check the specific  Starling commit for ATF support  to see how it got integrated.

Integration with Starling

Great news, Starling already supports ATF textures through theTexture.uploadAtfData API. Find here all the details about ATF and Starling, but it is as simple as this:

[Embed(source="starling.atf", mimeType="application/octet-stream")]
public static const CompressedData:Class;

var data:ByteArray = new CompressedData();
var texture:Texture = Texture.fromAtfData(data);

var image:Image = new Image(texture);
addChild(image);

Yes, as simple as this .

Limitations

I want to highlight that even if ATF will be very useful for 2D content (like with Starling), ATF has been mainly designed for 3D textures purposes. So what does it mean?
The compression applied to the textures is lossy and may impact too much the quality of your assets. Things like RGBA8888 and RGBA4444 for PVR are not supported and could be an issue.
But we need your feedback and testing to see how we can improve ATF and add support for more compression types. So let us know!

Requirements

One thing to keep in mind is that to cover the entire set of capabilities for ATF textures, you need:

  • If you are using Starling, you need at least Starling 1.2. Just pull the latest version from Github .
  • If you are using Stage3D directly, you need to use the latestAGALMiniAssembler
  • You need at least the AIR SDK 3.4. Download Flash Builder 4.7 which comes out of the box with the AIR 3.4 SDK.
  • You need to target at least Flash Player 11.4/AIR 3.4
  • You need to add the following compiler argument: ”-swf-version=17”

Download

Download the ATF tools here . Which contains:

  • The ATF tools binaries (Linux, Mac, Windows).
  • ATF specification
  • ATF User Guide with some more details.

Enjoy!

 

link: http://www.tuicool.com/articles/Q3Ajay